|
最近越來越頻繁地遇到需要配置反向代理的場景,在自己搭建博客的時候,也不可避免要用到 Nginx,所以這段時間集中學(xué)習(xí)了一下 Nginx,同時做了一些筆記,希望也可以幫助到大家~ ?? 這篇文章會在 CentOS 環(huán)境下安裝和使用 Nginx,如果對 CentOS 基本操作還不太清楚的,可以先看看 <半小時搞會 CentOS 入門必備基礎(chǔ)知識> 一文先做了解。 相信作為開發(fā)者,大家都知道 Nginx 的重要,廢話不多說,一起來學(xué)習(xí)吧。 CentOS 版本: 7.6 Nginx 版本: 1.16.1 1. Nginx 介紹傳統(tǒng)的 Web 服務(wù)器,每個客戶端連接作為一個單獨的進程或線程處理,需在切換任務(wù)時將 CPU 切換到新的任務(wù)并創(chuàng)建一個新的運行時上下文,消耗額外的內(nèi)存和 CPU 時間,當(dāng)并發(fā)請求增加時,服務(wù)器響應(yīng)變慢,從而對性能產(chǎn)生負面影響。  Nginx 是開源、高性能、高可靠的 Web 和反向代理服務(wù)器,而且支持熱部署,幾乎可以做到 7 * 24 小時不間斷運行,即使運行幾個月也不需要重新啟動,還能在不間斷服務(wù)的情況下對軟件版本進行熱更新。性能是 Nginx 最重要的考量,其占用內(nèi)存少、并發(fā)能力強、能支持高達 5w 個并發(fā)連接數(shù),最重要的是,Nginx 是免費的并可以商業(yè)化,配置使用也比較簡單。 Nginx 的最重要的幾個使用場景: 靜態(tài)資源服務(wù),通過本地文件系統(tǒng)提供服務(wù); 反向代理服務(wù),延伸出包括緩存、負載均衡等; API 服務(wù),OpenResty ;
對于前端來說 Node.js 不陌生了,Nginx 和 Node.js 的很多理念類似,HTTP 服務(wù)器、事件驅(qū)動、異步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以實現(xiàn),但 Nginx 和 Node.js 并不沖突,都有自己擅長的領(lǐng)域。Nginx 擅長于底層服務(wù)器端資源的處理(靜態(tài)資源處理轉(zhuǎn)發(fā)、反向代理,負載均衡等),Node.js 更擅長上層具體業(yè)務(wù)邏輯的處理,兩者可以完美組合,共同助力前端開發(fā)。 下面我們著重學(xué)習(xí)一下 Nginx 的使用。 2. 相關(guān)概念2.1 簡單請求和非簡單請求首先我們來了解一下簡單請求和非簡單請求,如果同時滿足下面兩個條件,就屬于簡單請求: 請求方法是 HEAD、GET、POST 三種之一; HTTP 頭信息不超過右邊著幾個字段:Accept、Accept-Language、Content-Language、Last-Event-IDContent-Type 只限于三個值 application/x-www-form-urlencoded、multipart/form-data、text/plain;
凡是不同時滿足這兩個條件的,都屬于非簡單請求。 瀏覽器處理簡單請求和非簡單請求的方式不一樣: 簡單請求 對于簡單請求,瀏覽器會在頭信息中增加 Origin 字段后直接發(fā)出,Origin 字段用來說明,本次請求來自的哪個源(協(xié)議+域名+端口)。 如果服務(wù)器發(fā)現(xiàn) Origin 指定的源不在許可范圍內(nèi),服務(wù)器會返回一個正常的 HTTP 回應(yīng),瀏覽器取到回應(yīng)之后發(fā)現(xiàn)回應(yīng)的頭信息中沒有包含 Access-Control-Allow-Origin 字段,就拋出一個錯誤給 XHR 的 error 事件; 如果服務(wù)器發(fā)現(xiàn) Origin 指定的域名在許可范圍內(nèi),服務(wù)器返回的響應(yīng)會多出幾個 Access-Control- 開頭的頭信息字段。 非簡單請求 非簡單請求是那種對服務(wù)器有特殊要求的請求,比如請求方法是 PUT 或 DELETE,或 Content-Type 值為 application/json。瀏覽器會在正式通信之前,發(fā)送一次 HTTP 預(yù)檢 OPTIONS 請求,先詢問服務(wù)器,當(dāng)前網(wǎng)頁所在的域名是否在服務(wù)器的許可名單之中,以及可以使用哪些 HTTP 請求方法和頭信息字段。只有得到肯定答復(fù),瀏覽器才會發(fā)出正式的 XHR 請求,否則報錯。 2.2 跨域在瀏覽器上當(dāng)前訪問的網(wǎng)站向另一個網(wǎng)站發(fā)送請求獲取數(shù)據(jù)的過程就是跨域請求。 跨域是瀏覽器的同源策略決定的,是一個重要的瀏覽器安全策略,用于限制一個 origin 的文檔或者它加載的腳本與另一個源的資源進行交互,它能夠幫助阻隔惡意文檔,減少可能被攻擊的媒介,可以使用 CORS 配置解除這個限制。 關(guān)于跨域網(wǎng)上已經(jīng)有很多解釋,這里就不啰嗦,也可以直接看 MDN 的 <瀏覽器的同源策略> 文檔進一步了解,這里就列舉幾個同源和不同元的例子,相信程序員都能看得懂。 # 同源的例子
http:///app1/index.html # 只是路徑不同
http:///app2/index.html
http://Example.com:80 # 只是大小寫差異
http://
# 不同源的例子
http:///app1 # 協(xié)議不同
https:///app2
http:// # host 不同
http://www.
http://myapp.
http:// # 端口不同
http://:8080
復(fù)制代碼
2.3 正向代理和反向代理反向代理(Reverse Proxy)對應(yīng)的是正向代理(Forward Proxy),他們的區(qū)別: 正向代理: 一般的訪問流程是客戶端直接向目標(biāo)服務(wù)器發(fā)送請求并獲取內(nèi)容,使用正向代理后,客戶端改為向代理服務(wù)器發(fā)送請求,并指定目標(biāo)服務(wù)器(原始服務(wù)器),然后由代理服務(wù)器和原始服務(wù)器通信,轉(zhuǎn)交請求并獲得的內(nèi)容,再返回給客戶端。正向代理隱藏了真實的客戶端,為客戶端收發(fā)請求,使真實客戶端對服務(wù)器不可見; 舉個具體的例子 ??,你的瀏覽器無法直接訪問谷哥,這時候可以通過一個代理服務(wù)器來幫助你訪問谷哥,那么這個服務(wù)器就叫正向代理。 反向代理: 與一般訪問流程相比,使用反向代理后,直接收到請求的服務(wù)器是代理服務(wù)器,然后將請求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上真正進行處理的服務(wù)器,得到的結(jié)果返回給客戶端。反向代理隱藏了真實的服務(wù)器,為服務(wù)器收發(fā)請求,使真實服務(wù)器對客戶端不可見。一般在處理跨域請求的時候比較常用。現(xiàn)在基本上所有的大型網(wǎng)站都設(shè)置了反向代理。 舉個具體的例子 ??,去飯店吃飯,可以點川菜、粵菜、江浙菜,飯店也分別有三個菜系的廚師 ?????,但是你作為顧客不用管哪個廚師給你做的菜,只用點菜即可,小二將你菜單中的菜分配給不同的廚師來具體處理,那么這個小二就是反向代理服務(wù)器。 簡單的說,一般給客戶端做代理的都是正向代理,給服務(wù)器做代理的就是反向代理。 正向代理和反向代理主要的原理區(qū)別可以參見下圖:  2.4 負載均衡一般情況下,客戶端發(fā)送多個請求到服務(wù)器,服務(wù)器處理請求,其中一部分可能要操作一些資源比如數(shù)據(jù)庫、靜態(tài)資源等,服務(wù)器處理完畢后,再將結(jié)果返回給客戶端。 這種模式對于早期的系統(tǒng)來說,功能要求不復(fù)雜,且并發(fā)請求相對較少的情況下還能勝任,成本也低。隨著信息數(shù)量不斷增長,訪問量和數(shù)據(jù)量飛速增長,以及系統(tǒng)業(yè)務(wù)復(fù)雜度持續(xù)增加,這種做法已無法滿足要求,并發(fā)量特別大時,服務(wù)器容易崩。 很明顯這是由于服務(wù)器性能的瓶頸造成的問題,除了堆機器之外,最重要的做法就是負載均衡。 請求爆發(fā)式增長的情況下,單個機器性能再強勁也無法滿足要求了,這個時候集群的概念產(chǎn)生了,單個服務(wù)器解決不了的問題,可以使用多個服務(wù)器,然后將請求分發(fā)到各個服務(wù)器上,將負載分發(fā)到不同的服務(wù)器,這就是負載均衡,核心是「分攤壓力」。Nginx 實現(xiàn)負載均衡,一般來說指的是將請求轉(zhuǎn)發(fā)給服務(wù)器集群。 舉個具體的例子 ??,晚高峰乘坐地鐵的時候,入站口經(jīng)常會有地鐵工作人員大喇叭“請走 B 口,B 口人少車空....”,這個工作人員的作用就是負載均衡。  2.5 動靜分離為了加快網(wǎng)站的解析速度,可以把動態(tài)頁面和靜態(tài)頁面由不同的服務(wù)器來解析,加快解析速度,降低原來單個服務(wù)器的壓力。  一般來說,都需要將動態(tài)資源和靜態(tài)資源分開,由于 Nginx 的高并發(fā)和靜態(tài)資源緩存等特性,經(jīng)常將靜態(tài)資源部署在 Nginx 上。如果請求的是靜態(tài)資源,直接到靜態(tài)資源目錄獲取資源,如果是動態(tài)資源的請求,則利用反向代理的原理,把請求轉(zhuǎn)發(fā)給對應(yīng)后臺應(yīng)用去處理,從而實現(xiàn)動靜分離。 使用前后端分離后,可以很大程度提升靜態(tài)資源的訪問速度,即使動態(tài)服務(wù)不可用,靜態(tài)資源的訪問也不會受到影響。 3. Nginx 快速安裝3.1 安裝我們可以先看看 yum list | grep nginx
復(fù)制代碼
來看看  然后 yum install nginx
復(fù)制代碼
來安裝 Nginx,然后我們在命令行中 nginx -v 就可以看到具體的 Nginx 版本信息,也就安裝完畢了。  3.2 相關(guān)文件夾然后我們可以使用 rpm -ql nginx 來查看 Nginx 被安裝到了什么地方,有哪些相關(guān)目錄,其中位于 /etc 目錄下的主要是配置文件,還有一些文件見下圖:  主要關(guān)注的文件夾有兩個: /etc/nginx/conf.d/ 文件夾,是我們進行子配置的配置項存放處,/etc/nginx/nginx.conf 主配置文件會默認把這個文件夾中所有子配置項都引入;
/usr/share/nginx/html/ 文件夾,通常靜態(tài)文件都放在這個文件夾,也可以根據(jù)你自己的習(xí)慣放其他地方;
3.3 跑起來康康安裝之后開啟 Nginx,如果系統(tǒng)開啟了防火墻,那么需要設(shè)置一下在防火墻中加入需要開放的端口,下面列舉幾個常用的防火墻操作(沒開啟的話不用管這個): systemctl start firewalld # 開啟防火墻
systemctl stop firewalld # 關(guān)閉防火墻
systemctl status firewalld # 查看防火墻開啟狀態(tài),顯示running則是正在運行
firewall-cmd --reload # 重啟防火墻,永久打開端口需要reload一下
# 添加開啟端口,--permanent表示永久打開,不加是臨時打開重啟之后失效
firewall-cmd --permanent --zone=public --add-port=8888/tcp
# 查看防火墻,添加的端口也可以看到
firewall-cmd --list-all
復(fù)制代碼
然后設(shè)置 Nginx 的開機啟動: systemctl enable nginx
復(fù)制代碼
啟動 Nginx (其他命令后面有詳細講解): systemctl start nginx
復(fù)制代碼
然后訪問你的 IP,這時候就可以看到 Nginx 的歡迎頁面了~ Welcome to nginx! ?? 3.4 安裝 nvm & node & git# 下載 nvm,或者看官網(wǎng)的步驟 https://github.com/nvm-sh/nvm#install--update-script
curl -o- https://raw./nvm-sh/nvm/v0.35.3/install.sh | bash
source ~/.bashrc # 安裝完畢后,更新配置文件即可使用 nvm 命令
nvm ls-remote # 查看遠程 node 版本
nvm install v12.16.3 # 選一個你要安裝的版本安裝,我這里選擇 12.16.3
nvm list # 安裝完畢查看安裝的 node 版本
node -v # 查看是否安裝好了
yum install git # git 安裝
復(fù)制代碼
4. Nginx 操作常用命令Nginx 的命令在控制臺中輸入 nginx -h 就可以看到完整的命令,這里列舉幾個常用的命令: nginx -s reload # 向主進程發(fā)送信號,重新加載配置文件,熱重啟
nginx -s reopen # 重啟 Nginx
nginx -s stop # 快速關(guān)閉
nginx -s quit # 等待工作進程處理完成后關(guān)閉
nginx -T # 查看當(dāng)前 Nginx 最終的配置
nginx -t -c <配置路徑> # 檢查配置是否有問題,如果已經(jīng)在配置目錄,則不需要-c
復(fù)制代碼
systemctl 是 Linux 系統(tǒng)應(yīng)用管理工具 systemd 的主命令,用于管理系統(tǒng),我們也可以用它來對 Nginx 進行管理,相關(guān)命令如下:
systemctl start nginx # 啟動 Nginx
systemctl stop nginx # 停止 Nginx
systemctl restart nginx # 重啟 Nginx
systemctl reload nginx # 重新加載 Nginx,用于修改配置后
systemctl enable nginx # 設(shè)置開機啟動 Nginx
systemctl disable nginx # 關(guān)閉開機啟動 Nginx
systemctl status nginx # 查看 Nginx 運行狀態(tài)
復(fù)制代碼
5. Nginx 配置語法就跟前面文件作用講解的圖所示,Nginx 的主配置文件是 /etc/nginx/nginx.conf,你可以使用 cat -n nginx.conf 來查看配置。 nginx.conf 結(jié)構(gòu)圖可以這樣概括:
main # 全局配置,對全局生效
├── events # 配置影響 Nginx 服務(wù)器或與用戶的網(wǎng)絡(luò)連接
├── http # 配置代理,緩存,日志定義等絕大多數(shù)功能和第三方模塊的配置
│ ├── upstream # 配置后端服務(wù)器具體地址,負載均衡配置不可或缺的部分
│ ├── server # 配置虛擬主機的相關(guān)參數(shù),一個 http 塊中可以有多個 server 塊
│ ├── server
│ │ ├── location # server 塊可以包含多個 location 塊,location 指令用于匹配 uri
│ │ ├── location
│ │ └── ...
│ └── ...
└── ...
復(fù)制代碼
一個 Nginx 配置文件的結(jié)構(gòu)就像 nginx.conf 顯示的那樣,配置文件的語法規(guī)則: 配置文件由指令與指令塊構(gòu)成; 每條指令以 ; 分號結(jié)尾,指令與參數(shù)間以空格符號分隔; 指令塊以 {} 大括號將多條指令組織在一起; include 語句允許組合多個配置文件以提升可維護性;
使用 # 符號添加注釋,提高可讀性; 使用 $ 符號使用變量; 部分指令的參數(shù)支持正則表達式;
5.1 典型配置Nginx 的典型配置: user nginx; # 運行用戶,默認即是nginx,可以不進行設(shè)置
worker_processes 1; # Nginx 進程數(shù),一般設(shè)置為和 CPU 核數(shù)一樣
error_log /var/log/nginx/error.log warn; # Nginx 的錯誤日志存放目錄
pid /var/run/nginx.pid; # Nginx 服務(wù)啟動時的 pid 存放位置
events {
use epoll; # 使用epoll的I/O模型(如果你不知道Nginx該使用哪種輪詢方法,會自動選擇一個最適合你操作系統(tǒng)的)
worker_connections 1024; # 每個進程允許最大并發(fā)數(shù)
}
http { # 配置使用最頻繁的部分,代理、緩存、日志定義等絕大多數(shù)功能和第三方模塊的配置都在這里設(shè)置
# 設(shè)置日志模式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # Nginx訪問日志存放位置
sendfile on; # 開啟高效傳輸模式
tcp_nopush on; # 減少網(wǎng)絡(luò)報文段的數(shù)量
tcp_nodelay on;
keepalive_timeout 65; # 保持連接的時間,也叫超時時間,單位秒
types_hash_max_size 2048;
include /etc/nginx/mime.types; # 文件擴展名與類型映射表
default_type application/octet-stream; # 默認文件類型
include /etc/nginx/conf.d/*.conf; # 加載子配置項
server {
listen 80; # 配置監(jiān)聽的端口
server_name localhost; # 配置的域名
location / {
root /usr/share/nginx/html; # 網(wǎng)站根目錄
index index.html index.htm; # 默認首頁文件
deny 172.168.22.11; # 禁止訪問的ip地址,可以為all
allow 172.168.33.44; # 允許訪問的ip地址,可以為all
}
error_page 500 502 503 504 /50x.html; # 默認50x對應(yīng)的訪問頁面
error_page 400 404 error.html; # 同上
}
}
復(fù)制代碼
server 塊可以包含多個 location 塊,location 指令用于匹配 uri,語法: location [ = | ~ | ~* | ^~] uri {
...
}
復(fù)制代碼
指令后面: = 精確匹配路徑,用于不含正則表達式的 uri 前,如果匹配成功,不再進行后續(xù)的查找;
^~ 用于不含正則表達式的 uri; 前,表示如果該符號后面的字符是最佳匹配,采用該規(guī)則,不再進行后續(xù)的查找;
~ 表示用該符號后面的正則去匹配路徑,區(qū)分大小寫;
~* 表示用該符號后面的正則去匹配路徑,不區(qū)分大小寫。跟 ~ 優(yōu)先級都比較低,如有多個location的正則能匹配的話,則使用正則表達式最長的那個;
如果 uri 包含正則表達式,則必須要有 ~ 或 ~* 標(biāo)志。 5.2 全局變量Nginx 有一些常用的全局變量,你可以在配置的任何位置使用它們,如下表: | 全局變量名 | 功能 |
|---|
$host | 請求信息中的 Host,如果請求中沒有 Host 行,則等于設(shè)置的服務(wù)器名,不包含端口 | $request_method | 客戶端請求類型,如 GET、POST | $remote_addr | 客戶端的 IP 地址 | $args | 請求中的參數(shù) | $arg_PARAMETER | GET 請求中變量名 PARAMETER 參數(shù)的值,例如:$http_user_agent(Uaer-Agent 值), $http_referer... | $content_length | 請求頭中的 Content-length 字段 | $http_user_agent | 客戶端agent信息 | $http_cookie | 客戶端cookie信息 | $remote_addr | 客戶端的IP地址 | $remote_port | 客戶端的端口 | $http_user_agent | 客戶端agent信息 | $server_protocol | 請求使用的協(xié)議,如 HTTP/1.0、HTTP/1.1 | $server_addr | 服務(wù)器地址 | $server_name | 服務(wù)器名稱 | $server_port | 服務(wù)器的端口號 | $scheme | HTTP 方法(如http,https) |
還有更多的內(nèi)置預(yù)定義變量,可以直接搜索關(guān)鍵字「nginx內(nèi)置預(yù)定義變量」可以看到一堆博客寫這個,這些變量都可以在配置文件中直接使用。 6. 設(shè)置二級域名虛擬主機在某某云 ?? 上購買了域名之后,就可以配置虛擬主機了,一般配置的路徑在 域名管理 -> 解析 -> 添加記錄 中添加二級域名,配置后某某云會把二級域名也解析到我們配置的服務(wù)器 IP 上,然后我們在 Nginx 上配置一下虛擬主機的訪問監(jiān)聽,就可以拿到從這個二級域名過來的請求了。  現(xiàn)在我自己的服務(wù)器上配置了一個 fe 的二級域名,也就是說在外網(wǎng)訪問 fe. 的時候,也可以訪問到我們的服務(wù)器了。 由于默認配置文件 /etc/nginx/nginx.conf 的 http 模塊中有一句 include /etc/nginx/conf.d/*.conf 也就是說 conf.d 文件夾下的所有 *.conf 文件都會作為子配置項被引入配置文件中。為了維護方便,我在 /etc/nginx/conf.d 文件夾中新建一個 fe..conf : # /etc/nginx/conf.d/fe..conf
server {
listen 80;
server_name fe.;
location / {
root /usr/share/nginx/html/fe;
index index.html;
}
}
復(fù)制代碼
然后在 /usr/share/nginx/html 文件夾下新建 fe 文件夾,新建文件 index.html,內(nèi)容隨便寫點,改完 nginx -s reload 重新加載,瀏覽器中輸入 fe.,發(fā)現(xiàn)從二級域名就可以訪問到我們剛剛新建的 fe 文件夾:  7. 配置反向代理反向代理是工作中最常用的服務(wù)器功能,經(jīng)常被用來解決跨域問題,下面簡單介紹一下如何實現(xiàn)反向代理。 首先進入 Nginx 的主配置文件: vim /etc/nginx/nginx.conf
復(fù)制代碼
為了看起來方便,把行號顯示出來 :set nu (個人習(xí)慣),然后我們?nèi)?http 模塊的 server 塊中的 location /,增加一行將默認網(wǎng)址重定向到最大學(xué)習(xí)網(wǎng)站 Bilibili 的 proxy_pass 配置 ?? :  改完保存退出,nginx -s reload 重新加載,進入默認網(wǎng)址,那么現(xiàn)在就直接跳轉(zhuǎn)到 B 站了,實現(xiàn)了一個簡單的代理。 實際使用中,可以將請求轉(zhuǎn)發(fā)到本機另一個服務(wù)器上,也可以根據(jù)訪問的路徑跳轉(zhuǎn)到不同端口的服務(wù)中。 比如我們監(jiān)聽 9001 端口,然后把訪問不同路徑的請求進行反向代理: 把訪問 http://127.0.0.1:9001/edu 的請求轉(zhuǎn)發(fā)到 http://127.0.0.1:8080 把訪問 http://127.0.0.1:9001/vod 的請求轉(zhuǎn)發(fā)到 http://127.0.0.1:8081
這種要怎么配置呢,首先同樣打開主配置文件,然后在 http 模塊下增加一個 server 塊: server {
listen 9001;
server_name *.;
location ~ /edu/ {
proxy_pass http://127.0.0.1:8080;
}
location ~ /vod/ {
proxy_pass http://127.0.0.1:8081;
}
}
復(fù)制代碼
反向代理還有一些其他的指令,可以了解一下: proxy_set_header:在將客戶端請求發(fā)送給后端服務(wù)器之前,更改來自客戶端的請求頭信息。
proxy_connect_timeout:配置Nginx與后端代理服務(wù)器嘗試建立連接的超時時間。
proxy_read_timeout:配置Nginx向后端服務(wù)器組發(fā)出read請求后,等待相應(yīng)的超時時間。
proxy_send_timeout:配置Nginx向后端服務(wù)器組發(fā)出write請求后,等待相應(yīng)的超時時間。
proxy_redirect:用于修改后端服務(wù)器返回的響應(yīng)頭中的Location和Refresh。
8. 跨域 CORS 配置關(guān)于簡單請求、非簡單請求、跨域的概念,前面已經(jīng)介紹過了,還不了解的可以看看前面的講解。現(xiàn)在前后端分離的項目一統(tǒng)天下,經(jīng)常本地起了前端服務(wù),需要訪問不同的后端地址,不可避免遇到跨域問題。  要解決跨域問題,我們來制造一個跨域問題。首先和前面設(shè)置二級域名的方式一樣,先設(shè)置好 fe. 和 be. 二級域名,都指向本云服務(wù)器地址,雖然對應(yīng) IP 是一樣的,但是在 fe. 域名發(fā)出的請求訪問 be. 域名的請求還是跨域了,因為訪問的 host 不一致(如果不知道啥原因參見前面跨域的內(nèi)容)。 8.1 使用反向代理解決跨域在前端服務(wù)地址為 fe. 的頁面請求 be. 的后端服務(wù)導(dǎo)致的跨域,可以這樣配置: server {
listen 9001;
server_name fe.;
location / {
proxy_pass be.;
}
}
復(fù)制代碼
這樣就將對前一個域名 fe. 的請求全都代理到了 be.,前端的請求都被我們用服務(wù)器代理到了后端地址下,繞過了跨域。 這里對靜態(tài)文件的請求和后端服務(wù)的請求都以 fe. 開始,不易區(qū)分,所以為了實現(xiàn)對后端服務(wù)請求的統(tǒng)一轉(zhuǎn)發(fā),通常我們會約定對后端服務(wù)的請求加上 /apis/ 前綴或者其他的 path 來和對靜態(tài)資源的請求加以區(qū)分,此時我們可以這樣配置: # 請求跨域,約定代理后端服務(wù)請求path以/apis/開頭
location ^~/apis/ {
# 這里重寫了請求,將正則匹配中的第一個分組的path拼接到真正的請求后面,并用break停止后續(xù)匹配
rewrite ^/apis/(.*)$ /$1 break;
proxy_pass be.;
# 兩個域名之間cookie的傳遞與回寫
proxy_cookie_domain be. fe.;
}
復(fù)制代碼
這樣,靜態(tài)資源我們使用 fe./xx.html,動態(tài)資源我們使用 fe./apis/getAwo,瀏覽器頁面看起來仍然訪問的前端服務(wù)器,繞過了瀏覽器的同源策略,畢竟我們看起來并沒有跨域。 也可以統(tǒng)一一點,直接把前后端服務(wù)器地址直接都轉(zhuǎn)發(fā)到另一個 server.,只通過在后面添加的 path 來區(qū)分請求的是靜態(tài)資源還是后端服務(wù),看需求了。 8.2 配置 header 解決跨域當(dāng)瀏覽器在訪問跨源的服務(wù)器時,也可以在跨域的服務(wù)器上直接設(shè)置 Nginx,從而前端就可以無感地開發(fā),不用把實際上訪問后端的地址改成前端服務(wù)的地址,這樣可適性更高。 比如前端站點是 fe.,這個地址下的前端頁面請求 be. 下的資源,比如前者的 fe./index.html 內(nèi)容是這樣的: <html>
<body>
<h1>welcome fe.!!<h1>
<script type='text/javascript'>
var xmlhttp = new XMLHttpRequest()
xmlhttp.open("GET", "http://be./index.html", true);
xmlhttp.send();
</script>
</body>
</html>
復(fù)制代碼
打開瀏覽器訪問 fe./index.html 的結(jié)果如下:  很明顯這里是跨域請求,在瀏覽器中直接訪問 http://be./index.html 是可以訪問到的,但是在 fe. 的 html 頁面訪問就會出現(xiàn)跨域。 在 /etc/nginx/conf.d/ 文件夾中新建一個配置文件,對應(yīng)二級域名 be. : # /etc/nginx/conf.d/be..conf
server {
listen 80;
server_name be.;
add_header 'Access-Control-Allow-Origin' $http_origin; # 全局變量獲得當(dāng)前請求origin,帶cookie的請求不支持*
add_header 'Access-Control-Allow-Credentials' 'true'; # 為 true 可帶上 cookie
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS'; # 允許請求方法
add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers; # 允許請求的 header,可以為 *
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
if ($request_method = 'OPTIONS') {
add_header 'Access-Control-Max-Age' 1728000; # OPTIONS 請求的有效期,在有效期內(nèi)不用發(fā)出另一條預(yù)檢請求
add_header 'Content-Type' 'text/plain; charset=utf-8';
add_header 'Content-Length' 0;
return 204; # 200 也可以
}
location / {
root /usr/share/nginx/html/be;
index index.html;
}
}
復(fù)制代碼
然后 nginx -s reload 重新加載配置。這時再訪問 fe./index.html 結(jié)果如下,請求中出現(xiàn)了我們剛剛配置的 Header:  解決了跨域問題。 9. 開啟 gzip 壓縮gzip 是一種常用的網(wǎng)頁壓縮技術(shù),傳輸?shù)木W(wǎng)頁經(jīng)過 gzip 壓縮之后大小通常可以變?yōu)樵瓉淼囊话肷踔粮。ü倬W(wǎng)原話),更小的網(wǎng)頁體積也就意味著帶寬的節(jié)約和傳輸速度的提升,特別是對于訪問量巨大大型網(wǎng)站來說,每一個靜態(tài)資源體積的減小,都會帶來可觀的流量與帶寬的節(jié)省。 百度可以找到很多檢測站點來查看目標(biāo)網(wǎng)頁有沒有開啟 gzip 壓縮,在下隨便找了一個 <網(wǎng)頁GZIP壓縮檢測> 輸入掘金 來偷窺下掘金有沒有開啟 gzip。  這里可以看到掘金是開啟了 gzip 的,壓縮效果還挺不錯,達到了 52% 之多,本來 34kb 的網(wǎng)頁體積,壓縮完只需要 16kb,可以想象網(wǎng)頁傳輸速度提升了不少。 9.1 Nginx 配置 gzip使用 gzip 不僅需要 Nginx 配置,瀏覽器端也需要配合,需要在請求消息頭中包含 Accept-Encoding: gzip(IE5 之后所有的瀏覽器都支持了,是現(xiàn)代瀏覽器的默認設(shè)置)。一般在請求 html 和 css 等靜態(tài)資源的時候,支持的瀏覽器在 request 請求靜態(tài)資源的時候,會加上 Accept-Encoding: gzip 這個 header,表示自己支持 gzip 的壓縮方式,Nginx 在拿到這個請求的時候,如果有相應(yīng)配置,就會返回經(jīng)過 gzip 壓縮過的文件給瀏覽器,并在 response 相應(yīng)的時候加上 content-encoding: gzip 來告訴瀏覽器自己采用的壓縮方式(因為瀏覽器在傳給服務(wù)器的時候一般還告訴服務(wù)器自己支持好幾種壓縮方式),瀏覽器拿到壓縮的文件后,根據(jù)自己的解壓方式進行解析。 先來看看 Nginx 怎么進行 gzip 配置,和之前的配置一樣,為了方便管理,還是在 /etc/nginx/conf.d/ 文件夾中新建配置文件 gzip.conf : # /etc/nginx/conf.d/gzip.conf
gzip on; # 默認off,是否開啟gzip
gzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;
# 上面兩個開啟基本就能跑起了,下面的愿意折騰就了解一下
gzip_static on;
gzip_proxied any;
gzip_vary on;
gzip_comp_level 6;
gzip_buffers 16 8k;
# gzip_min_length 1k;
gzip_http_version 1.1;
復(fù)制代碼
稍微解釋一下: gzip_types:要采用 gzip 壓縮的 MIME 文件類型,其中 text/html 被系統(tǒng)強制啟用; gzip_static:默認 off,該模塊啟用后,Nginx 首先檢查是否存在請求靜態(tài)文件的 gz 結(jié)尾的文件,如果有則直接返回該 .gz 文件內(nèi)容; gzip_proxied:默認 off,nginx做為反向代理時啟用,用于設(shè)置啟用或禁用從代理服務(wù)器上收到相應(yīng)內(nèi)容 gzip 壓縮; gzip_vary:用于在響應(yīng)消息頭中添加 Vary:Accept-Encoding,使代理服務(wù)器根據(jù)請求頭中的 Accept-Encoding 識別是否啟用 gzip 壓縮; gzip_comp_level:gzip 壓縮比,壓縮級別是 1-9,1 壓縮級別最低,9 最高,級別越高壓縮率越大,壓縮時間越長,建議 4-6; gzip_buffers:獲取多少內(nèi)存用于緩存壓縮結(jié)果,16 8k 表示以 8k*16 為單位獲得; gzip_min_length:允許壓縮的頁面最小字節(jié)數(shù),頁面字節(jié)數(shù)從header頭中的 Content-Length 中進行獲取。默認值是 0,不管頁面多大都壓縮。建議設(shè)置成大于 1k 的字節(jié)數(shù),小于 1k 可能會越壓越大; gzip_http_version:默認 1.1,啟用 gzip 所需的 HTTP 最低版本;
這個配置可以插入到 http 模塊整個服務(wù)器的配置里,也可以插入到需要使用的虛擬主機的 server 或者下面的 location 模塊中,當(dāng)然像上面我們這樣寫的話就是被 include 到 http 模塊中了。 其他更全的配置信息可以查看 <官網(wǎng)文檔ngx_http_gzip_module>,配置前是這樣的:  配置之后 response 的 header 里面多了一個 Content-Encoding: gzip,返回信息被壓縮了:  注意了,一般 gzip 的配置建議加上 gzip_min_length 1k,不加的話:  由于文件太小,gzip 壓縮之后得到了 -48% 的體積優(yōu)化,壓縮之后體積還比壓縮之前體積大了,所以最好設(shè)置低于 1kb 的文件就不要 gzip 壓縮了 ?? 9.2 Webpack 的 gzip 配置當(dāng)前端項目使用 Webpack 進行打包的時候,也可以開啟 gzip 壓縮: // vue-cli3 的 vue.config.js 文件
const CompressionWebpackPlugin = require('compression-webpack-plugin')
module.exports = {
// gzip 配置
configureWebpack: config => {
if (process.env.NODE_ENV === 'production') {
// 生產(chǎn)環(huán)境
return {
plugins: [new CompressionWebpackPlugin({
test: /\.js$|\.html$|\.css/, // 匹配文件名
threshold: 10240, // 文件壓縮閾值,對超過10k的進行壓縮
deleteOriginalAssets: false // 是否刪除源文件
})]
}
}
},
...
}
復(fù)制代碼
由此打包出來的文件如下圖:  這里可以看到某些打包之后的文件下面有一個對應(yīng)的 .gz 經(jīng)過 gzip 壓縮之后的文件,這是因為這個文件超過了 10kb,有的文件沒有超過 10kb 就沒有進行 gzip 打包,如果你期望壓縮文件的體積閾值小一點,可以在 compression-webpack-plugin 這個插件的配置里進行對應(yīng)配置。 那么為啥這里 Nginx 已經(jīng)有了 gzip 壓縮,Webpack 這里又整了個 gzip 呢,因為如果全都是使用 Nginx 來壓縮文件,會耗費服務(wù)器的計算資源,如果服務(wù)器的 gzip_comp_level 配置的比較高,就更增加服務(wù)器的開銷,相應(yīng)增加客戶端的請求時間,得不償失。 如果壓縮的動作在前端打包的時候就做了,把打包之后的高壓縮等級文件作為靜態(tài)資源放在服務(wù)器上,Nginx 會優(yōu)先查找這些壓縮之后的文件返回給客戶端,相當(dāng)于把壓縮文件的動作從 Nginx 提前給 Webpack 打包的時候完成,節(jié)約了服務(wù)器資源,所以一般推介在生產(chǎn)環(huán)境應(yīng)用 Webpack 配置 gzip 壓縮。 10. 配置負載均衡負載均衡在之前已經(jīng)介紹了相關(guān)概念了,主要思想就是把負載均勻合理地分發(fā)到多個服務(wù)器上,實現(xiàn)壓力分流的目的。 主要配置如下: http {
upstream myserver {
# ip_hash; # ip_hash 方式
# fair; # fair 方式
server 127.0.0.1:8081; # 負載均衡目的服務(wù)地址
server 127.0.0.1:8080;
server 127.0.0.1:8082 weight=10; # weight 方式,不寫默認為 1
}
server {
location / {
proxy_pass http://myserver;
proxy_connect_timeout 10;
}
}
}
復(fù)制代碼
Nginx 提供了好幾種分配方式,默認為輪詢,就是輪流來。有以下幾種分配方式: 輪詢,默認方式,每個請求按時間順序逐一分配到不同的后端服務(wù)器,如果后端服務(wù)掛了,能自動剔除; weight,權(quán)重分配,指定輪詢幾率,權(quán)重越高,在被訪問的概率越大,用于后端服務(wù)器性能不均的情況; ip_hash,每個請求按訪問 IP 的 hash 結(jié)果分配,這樣每個訪客固定訪問一個后端服務(wù)器,可以解決動態(tài)網(wǎng)頁 session 共享問題。負載均衡每次請求都會重新定位到服務(wù)器集群中的某一個,那么已經(jīng)登錄某一個服務(wù)器的用戶再重新定位到另一個服務(wù)器,其登錄信息將會丟失,這樣顯然是不妥的; fair(第三方),按后端服務(wù)器的響應(yīng)時間分配,響應(yīng)時間短的優(yōu)先分配,依賴第三方插件 nginx-upstream-fair,需要先安裝;
11. 配置動靜分離動靜分離在之前也介紹過了,就是把動態(tài)和靜態(tài)的請求分開。方式主要有兩種,一種 是純粹把靜態(tài)文件獨立成單獨的域名,放在獨立的服務(wù)器上,也是目前主流推崇的方案。另外一種方法就是動態(tài)跟靜態(tài)文件混合在一起發(fā)布, 通過 Nginx 配置來分開。 通過 location 指定不同的后綴名實現(xiàn)不同的請求轉(zhuǎn)發(fā)。通過 expires 參數(shù)設(shè)置,可以使瀏覽器緩存過期時間,減少與服務(wù)器之前的請求和流量。具體 expires 定義:是給一個資源設(shè)定一個過期時間,也就是說無需去服務(wù)端驗證,直接通過瀏覽器自身確認是否過期即可,所以不會產(chǎn)生額外的流量。此種方法非常適合不經(jīng)常變動的資源。(如果經(jīng)常更新的文件,不建議使用 expires 來緩存),我這里設(shè)置 3d,表示在這 3 天之內(nèi)訪問這個URL,發(fā)送一個請求,比對服務(wù)器該文件最后更新時間沒有變化。則不會從服務(wù)器抓取,返回狀態(tài)碼 304,如果有修改,則直接從服務(wù)器重新下載,返回狀態(tài)碼 200。 server {
location /www/ {
root /data/;
index index.html index.htm;
}
location /image/ {
root /data/;
autoindex on;
}
}
復(fù)制代碼
12. 配置高可用集群(雙機熱備)當(dāng)主 Nginx 服務(wù)器宕機之后,切換到備份 Nginx 服務(wù)器  首先安裝 keepalived, yum install keepalived -y
復(fù)制代碼
然后編輯 /etc/keepalived/keepalived.conf 配置文件,并在配置文件中增加 vrrp_script 定義一個外圍檢測機制,并在 vrrp_instance 中通過定義 track_script 來追蹤腳本執(zhí)行過程,實現(xiàn)節(jié)點轉(zhuǎn)移: global_defs{
notification_email {
acassen@firewall.loc
}
notification_email_from Alexandre@firewall.loc
smtp_server 127.0.0.1
smtp_connect_timeout 30 // 上面都是郵件配置,沒卵用
router_id LVS_DEVEL // 當(dāng)前服務(wù)器名字,用hostname命令來查看
}
vrrp_script chk_maintainace { // 檢測機制的腳本名稱為chk_maintainace
script "[[ -e/etc/keepalived/down ]] && exit 1 || exit 0" // 可以是腳本路徑或腳本命令
// script "/etc/keepalived/nginx_check.sh" // 比如這樣的腳本路徑
interval 2 // 每隔2秒檢測一次
weight -20 // 當(dāng)腳本執(zhí)行成立,那么把當(dāng)前服務(wù)器優(yōu)先級改為-20
}
vrrp_instanceVI_1 { // 每一個vrrp_instance就是定義一個虛擬路由器
state MASTER // 主機為MASTER,備用機為BACKUP
interface eth0 // 網(wǎng)卡名字,可以從ifconfig中查找
virtual_router_id 51 // 虛擬路由的id號,一般小于255,主備機id需要一樣
priority 100 // 優(yōu)先級,master的優(yōu)先級比backup的大
advert_int 1 // 默認心跳間隔
authentication { // 認證機制
auth_type PASS
auth_pass 1111 // 密碼
}
virtual_ipaddress { // 虛擬地址vip
172.16.2.8
}
}
復(fù)制代碼
其中檢測腳本 nginx_check.sh,這里提供一個: #!/bin/bash
A=`ps -C nginx --no-header | wc -l`
if [ $A -eq 0 ];then
/usr/sbin/nginx # 嘗試重新啟動nginx
sleep 2 # 睡眠2秒
if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then
killall keepalived # 啟動失敗,將keepalived服務(wù)殺死。將vip漂移到其它備份節(jié)點
fi
fi
復(fù)制代碼
復(fù)制一份到備份服務(wù)器,備份 Nginx 的配置要將 state 后改為 BACKUP,priority 改為比主機小。 設(shè)置完畢后各自 service keepalived start 啟動,經(jīng)過訪問成功之后,可以把 Master 機的 keepalived 停掉,此時 Master 機就不再是主機了 service keepalived stop,看訪問虛擬 IP 時是否能夠自動切換到備機 ip addr。 再次啟動 Master 的 keepalived,此時 vip 又變到了主機上。 13. 適配 PC 或移動設(shè)備根據(jù)用戶設(shè)備不同返回不同樣式的站點,以前經(jīng)常使用的是純前端的自適應(yīng)布局,但無論是復(fù)雜性和易用性上面還是不如分開編寫的好,比如我們常見的淘寶、京東......這些大型網(wǎng)站就都沒有采用自適應(yīng),而是用分開制作的方式,根據(jù)用戶請求的 user-agent 來判斷是返回 PC 還是 H5 站點。 首先在 /usr/share/nginx/html 文件夾下 mkdir 分別新建兩個文件夾 PC 和 mobile,vim 編輯兩個 index.html 隨便寫點內(nèi)容。 cd /usr/share/nginx/html
mkdir pc mobile
cd pc
vim index.html # 隨便寫點比如 hello pc!
cd ../mobile
vim index.html # 隨便寫點比如 hello mobile!
復(fù)制代碼
然后和設(shè)置二級域名虛擬主機時候一樣,去 /etc/nginx/conf.d 文件夾下新建一個配置文件 fe..conf : # /etc/nginx/conf.d/fe..conf
server {
listen 80;
server_name fe.;
location / {
root /usr/share/nginx/html/pc;
if ($http_user_agent ~* '(Android|webOS|iPhone|iPod|BlackBerry)') {
root /usr/share/nginx/html/mobile;
}
index index.html;
}
}
復(fù)制代碼
配置基本沒什么不一樣的,主要多了一個 if 語句,然后使用 $http_user_agent 全局變量來判斷用戶請求的 user-agent,指向不同的 root 路徑,返回對應(yīng)站點。 在瀏覽器訪問這個站點,然后 F12 中模擬使用手機訪問:  可以看到在模擬使用移動端訪問的時候,Nginx 返回的站點變成了移動端對應(yīng)的 html 了。 14. 配置 HTTPS具體配置過程網(wǎng)上挺多的了,也可以使用你購買的某某云,一般都會有免費申請的服務(wù)器證書,安裝直接看所在云的操作指南即可。 我購買的騰訊云提供的亞洲誠信機構(gòu)頒發(fā)的免費證書只能一個域名使用,二級域名什么的需要另外申請,但是申請審批比較快,一般幾分鐘就能成功,然后下載證書的壓縮文件,里面有個 nginx 文件夾,把 xxx.crt 和 xxx.key 文件拷貝到服務(wù)器目錄,再配置下: server {
listen 443 ssl http2 default_server; # SSL 訪問端口號為 443
server_name ; # 填寫綁定證書的域名
ssl_certificate /etc/nginx/https/1__bundle.crt; # 證書文件地址
ssl_certificate_key /etc/nginx/https/2_.key; # 私鑰文件地址
ssl_session_timeout 10m;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #請按照以下協(xié)議配置
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
}
}
復(fù)制代碼
寫完 nginx -t -q 校驗一下,沒問題就 nginx -s reload,現(xiàn)在去訪問 https:/// 就能訪問 HTTPS 版的網(wǎng)站了。 一般還可以加上幾個增強安全性的命令: add_header X-Frame-Options DENY; # 減少點擊劫持
add_header X-Content-Type-Options nosniff; # 禁止服務(wù)器自動解析資源類型
add_header X-Xss-Protection 1; # 防XSS攻擊
復(fù)制代碼
15. 一些常用技巧15.1 靜態(tài)服務(wù)server {
listen 80;
server_name static.;
charset utf-8; # 防止中文文件名亂碼
location /download {
alias /usr/share/nginx/html/static; # 靜態(tài)資源目錄
autoindex on; # 開啟靜態(tài)資源列目錄
autoindex_exact_size off; # on(默認)顯示文件的確切大小,單位是byte;off顯示文件大概大小,單位KB、MB、GB
autoindex_localtime off; # off(默認)時顯示的文件時間為GMT時間;on顯示的文件時間為服務(wù)器時間
}
}
復(fù)制代碼
15.2 圖片防盜鏈server {
listen 80;
server_name *.;
# 圖片防盜鏈
location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {
valid_referers none blocked 192.168.0.2; # 只允許本機 IP 外鏈引用
if ($invalid_referer){
return 403;
}
}
}
復(fù)制代碼
15.3 請求過濾# 非指定請求全返回 403
if ( $request_method !~ ^(GET|POST|HEAD)$ ) {
return 403;
}
location / {
# IP訪問限制(只允許IP是 192.168.0.2 機器訪問)
allow 192.168.0.2;
deny all;
root html;
index index.html index.htm;
}
復(fù)制代碼
15.4 配置圖片、字體等靜態(tài)文件緩存由于圖片、字體、音頻、視頻等靜態(tài)文件在打包的時候通常會增加了 hash,所以緩存可以設(shè)置的長一點,先設(shè)置強制緩存,再設(shè)置協(xié)商緩存;如果存在沒有 hash 值的靜態(tài)文件,建議不設(shè)置強制緩存,僅通過協(xié)商緩存判斷是否需要使用緩存。 # 圖片緩存時間設(shè)置
location ~ .*\.(css|js|jpg|png|gif|swf|woff|woff2|eot|svg|ttf|otf|mp3|m4a|aac|txt)$ {
expires 10d;
}
# 如果不希望緩存
expires -1;
復(fù)制代碼
15.5 單頁面項目 history 路由配置server {
listen 80;
server_name fe.;
location / {
root /usr/share/nginx/html/dist; # vue 打包后的文件夾
index index.html index.htm;
try_files $uri $uri/ /index.html @rewrites;
expires -1; # 首頁一般沒有強制緩存
add_header Cache-Control no-cache;
}
# 接口轉(zhuǎn)發(fā),如果需要的話
#location ~ ^/api {
# proxy_pass http://be.;
#}
location @rewrites {
rewrite ^(.+)$ /index.html break;
}
}
復(fù)制代碼
15.6 HTTP 請求轉(zhuǎn)發(fā)到 HTTPS配置完 HTTPS 后,瀏覽器還是可以訪問 HTTP 的地址 http:/// 的,可以做一個 301 跳轉(zhuǎn),把對應(yīng)域名的 HTTP 請求重定向到 HTTPS 上 server {
listen 80;
server_name www.;
# 單域名重定向
if ($host = 'www.'){
return 301 https://www.$request_uri;
}
# 全局非 https 協(xié)議時重定向
if ($scheme != 'https') {
return 301 https://$server_name$request_uri;
}
# 或者全部重定向
return 301 https://$server_name$request_uri;
# 以上配置選擇自己需要的即可,不用全部加
}
復(fù)制代碼
15.7 泛域名路徑分離這是一個非常實用的技能,經(jīng)常有時候我們可能需要配置一些二級或者三級域名,希望通過 Nginx 自動指向?qū)?yīng)目錄,比如: test1.doc. 自動指向 /usr/share/nginx/html/doc/test1 服務(wù)器地址;
test2.doc. 自動指向 /usr/share/nginx/html/doc/test2 服務(wù)器地址;
server {
listen 80;
server_name ~^([\w-]+)\.doc\.sherlocked93\.club$;
root /usr/share/nginx/html/doc/$1;
}
復(fù)制代碼
15.8 泛域名轉(zhuǎn)發(fā)和之前的功能類似,有時候我們希望把二級或者三級域名鏈接重寫到我們希望的路徑,讓后端就可以根據(jù)路由解析不同的規(guī)則: test1.serv./api?name=a 自動轉(zhuǎn)發(fā)到 127.0.0.1:8080/test1/api?name=a;
test2.serv./api?name=a 自動轉(zhuǎn)發(fā)到 127.0.0.1:8080/test2/api?name=a ;
server {
listen 80;
server_name ~^([\w-]+)\.serv\.sherlocked93\.club$;
location / {
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_set_header X-NginX-Proxy true;
proxy_pass http://127.0.0.1:8080/$1$request_uri;
}
}
復(fù)制代碼
16. 最佳實踐為了使 Nginx 配置更易于維護,建議為每個服務(wù)創(chuàng)建一個單獨的配置文件,存儲在 /etc/nginx/conf.d 目錄,根據(jù)需求可以創(chuàng)建任意多個獨立的配置文件。 獨立的配置文件,建議遵循以下命名約定 <服務(wù)>.conf,比如域名是 ,那么你的配置文件的應(yīng)該是這樣的 /etc/nginx/conf.d/.conf,如果部署多個服務(wù),也可以在文件名中加上 Nginx 轉(zhuǎn)發(fā)的端口號,比如 .8080.conf,如果是二級域名,建議也都加上 fe..conf。 常用的、復(fù)用頻率比較高的配置可以放到 /etc/nginx/snippets 文件夾,在 Nginx 的配置文件中需要用到的位置 include 進去,以功能來命名,并在每個 snippet 配置文件的開頭注釋標(biāo)明主要功能和引入位置,方便管理。比如之前的 gzip、cors 等常用配置,我都設(shè)置了 snippet。 Nginx 日志相關(guān)目錄,內(nèi)以 域名.type.log 命名(比如 be..access.log 和 be..error.log )位于 /var/log/nginx/ 目錄中,為每個獨立的服務(wù)配置不同的訪問權(quán)限和錯誤日志文件,這樣查找錯誤時,會更加方便快捷。
|