免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費(fèi)電子書等14項(xiàng)超值服

開通VIP
Nginx 從入門到實(shí)踐,萬字詳解!

最近越來越頻繁地遇到需要配置反向代理的場(chǎng)景,在自己搭建博客的時(shí)候,也不可避免要用到 Nginx,所以這段時(shí)間集中學(xué)習(xí)了一下 Nginx,同時(shí)做了一些筆記,希望也可以幫助到大家~ ??

這篇文章會(huì)在 CentOS 環(huán)境下安裝和使用 Nginx,如果對(duì) CentOS 基本操作還不太清楚的,可以先看看 <半小時(shí)搞會(huì) CentOS 入門必備基礎(chǔ)知識(shí)> 一文先做了解。

相信作為開發(fā)者,大家都知道 Nginx 的重要,廢話不多說,一起來學(xué)習(xí)吧。

CentOS 版本: 7.6

Nginx 版本: 1.16.1

1. Nginx 介紹

傳統(tǒng)的 Web 服務(wù)器,每個(gè)客戶端連接作為一個(gè)單獨(dú)的進(jìn)程或線程處理,需在切換任務(wù)時(shí)將 CPU 切換到新的任務(wù)并創(chuàng)建一個(gè)新的運(yùn)行時(shí)上下文,消耗額外的內(nèi)存和 CPU 時(shí)間,當(dāng)并發(fā)請(qǐng)求增加時(shí),服務(wù)器響應(yīng)變慢,從而對(duì)性能產(chǎn)生負(fù)面影響。

Nginx 是開源、高性能、高可靠的 Web 和反向代理服務(wù)器,而且支持熱部署,幾乎可以做到 7 * 24 小時(shí)不間斷運(yùn)行,即使運(yùn)行幾個(gè)月也不需要重新啟動(dòng),還能在不間斷服務(wù)的情況下對(duì)軟件版本進(jìn)行熱更新。性能是 Nginx 最重要的考量,其占用內(nèi)存少、并發(fā)能力強(qiáng)、能支持高達(dá) 5w 個(gè)并發(fā)連接數(shù),最重要的是,Nginx 是免費(fèi)的并可以商業(yè)化,配置使用也比較簡(jiǎn)單。

Nginx 的最重要的幾個(gè)使用場(chǎng)景:

  1. 靜態(tài)資源服務(wù),通過本地文件系統(tǒng)提供服務(wù);

  2. 反向代理服務(wù),延伸出包括緩存、負(fù)載均衡等;

  3. API 服務(wù),OpenResty ;

對(duì)于前端來說 Node.js 不陌生了,Nginx 和 Node.js 的很多理念類似,HTTP 服務(wù)器、事件驅(qū)動(dòng)、異步非阻塞等,且 Nginx 的大部分功能使用 Node.js 也可以實(shí)現(xiàn),但 Nginx 和 Node.js 并不沖突,都有自己擅長的領(lǐng)域。Nginx 擅長于底層服務(wù)器端資源的處理(靜態(tài)資源處理轉(zhuǎn)發(fā)、反向代理,負(fù)載均衡等),Node.js 更擅長上層具體業(yè)務(wù)邏輯的處理,兩者可以完美組合,共同助力前端開發(fā)。

下面我們著重學(xué)習(xí)一下 Nginx 的使用。

2. 相關(guān)概念

2.1 簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求

首先我們來了解一下簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求,如果同時(shí)滿足下面兩個(gè)條件,就屬于簡(jiǎn)單請(qǐng)求:

  1. 請(qǐng)求方法是 HEAD、GET、POST 三種之一;

  2. HTTP 頭信息不超過右邊著幾個(gè)字段:Accept、Accept-Language、Content-Language、Last-Event-IDContent-Type 只限于三個(gè)值 application/x-www-form-urlencodedmultipart/form-data、text/plain

凡是不同時(shí)滿足這兩個(gè)條件的,都屬于非簡(jiǎn)單請(qǐng)求。

瀏覽器處理簡(jiǎn)單請(qǐng)求和非簡(jiǎn)單請(qǐng)求的方式不一樣:

簡(jiǎn)單請(qǐng)求

對(duì)于簡(jiǎn)單請(qǐng)求,瀏覽器會(huì)在頭信息中增加 Origin 字段后直接發(fā)出,Origin 字段用來說明,本次請(qǐng)求來自的哪個(gè)源(協(xié)議+域名+端口)。

如果服務(wù)器發(fā)現(xiàn) Origin 指定的源不在許可范圍內(nèi),服務(wù)器會(huì)返回一個(gè)正常的 HTTP 回應(yīng),瀏覽器取到回應(yīng)之后發(fā)現(xiàn)回應(yīng)的頭信息中沒有包含 Access-Control-Allow-Origin 字段,就拋出一個(gè)錯(cuò)誤給 XHR 的 error 事件;

如果服務(wù)器發(fā)現(xiàn) Origin 指定的域名在許可范圍內(nèi),服務(wù)器返回的響應(yīng)會(huì)多出幾個(gè) Access-Control- 開頭的頭信息字段。

非簡(jiǎn)單請(qǐng)求

非簡(jiǎn)單請(qǐng)求是那種對(duì)服務(wù)器有特殊要求的請(qǐng)求,比如請(qǐng)求方法是 PUTDELETE,或 Content-Type 值為 application/json。瀏覽器會(huì)在正式通信之前,發(fā)送一次 HTTP 預(yù)檢 OPTIONS 請(qǐng)求,先詢問服務(wù)器,當(dāng)前網(wǎng)頁所在的域名是否在服務(wù)器的許可名單之中,以及可以使用哪些 HTTP 請(qǐng)求方法和頭信息字段。只有得到肯定答復(fù),瀏覽器才會(huì)發(fā)出正式的 XHR 請(qǐng)求,否則報(bào)錯(cuò)。

2.2 跨域

在瀏覽器上當(dāng)前訪問的網(wǎng)站向另一個(gè)網(wǎng)站發(fā)送請(qǐng)求獲取數(shù)據(jù)的過程就是跨域請(qǐng)求。

跨域是瀏覽器的同源策略決定的,是一個(gè)重要的瀏覽器安全策略,用于限制一個(gè) origin 的文檔或者它加載的腳本與另一個(gè)源的資源進(jìn)行交互,它能夠幫助阻隔惡意文檔,減少可能被攻擊的媒介,可以使用 CORS 配置解除這個(gè)限制。

關(guān)于跨域網(wǎng)上已經(jīng)有很多解釋,這里就不啰嗦,也可以直接看 MDN 的 <瀏覽器的同源策略> 文檔進(jìn)一步了解,這里就列舉幾個(gè)同源和不同元的例子,相信程序員都能看得懂。

# 同源的例子http://example.com/app1/index.html  # 只是路徑不同http://example.com/app2/index.htmlhttp://Example.com:80  # 只是大小寫差異http://example.com# 不同源的例子http://example.com/app1   # 協(xié)議不同https://example.com/app2http://example.com        # host 不同http://www.example.comhttp://myapp.example.comhttp://example.com        # 端口不同http://example.com:8080復(fù)制代碼

2.3 正向代理和反向代理

反向代理(Reverse Proxy)對(duì)應(yīng)的是正向代理(Forward Proxy),他們的區(qū)別:

正向代理: 一般的訪問流程是客戶端直接向目標(biāo)服務(wù)器發(fā)送請(qǐng)求并獲取內(nèi)容,使用正向代理后,客戶端改為向代理服務(wù)器發(fā)送請(qǐng)求,并指定目標(biāo)服務(wù)器(原始服務(wù)器),然后由代理服務(wù)器和原始服務(wù)器通信,轉(zhuǎn)交請(qǐng)求并獲得的內(nèi)容,再返回給客戶端。正向代理隱藏了真實(shí)的客戶端,為客戶端收發(fā)請(qǐng)求,使真實(shí)客戶端對(duì)服務(wù)器不可見;

舉個(gè)具體的例子 ??,你的瀏覽器無法直接訪問谷哥,這時(shí)候可以通過一個(gè)代理服務(wù)器來幫助你訪問谷哥,那么這個(gè)服務(wù)器就叫正向代理。

反向代理: 與一般訪問流程相比,使用反向代理后,直接收到請(qǐng)求的服務(wù)器是代理服務(wù)器,然后將請(qǐng)求轉(zhuǎn)發(fā)給內(nèi)部網(wǎng)絡(luò)上真正進(jìn)行處理的服務(wù)器,得到的結(jié)果返回給客戶端。反向代理隱藏了真實(shí)的服務(wù)器,為服務(wù)器收發(fā)請(qǐng)求,使真實(shí)服務(wù)器對(duì)客戶端不可見。一般在處理跨域請(qǐng)求的時(shí)候比較常用?,F(xiàn)在基本上所有的大型網(wǎng)站都設(shè)置了反向代理。

舉個(gè)具體的例子 ??,去飯店吃飯,可以點(diǎn)川菜、粵菜、江浙菜,飯店也分別有三個(gè)菜系的廚師 ?????,但是你作為顧客不用管哪個(gè)廚師給你做的菜,只用點(diǎn)菜即可,小二將你菜單中的菜分配給不同的廚師來具體處理,那么這個(gè)小二就是反向代理服務(wù)器。

簡(jiǎn)單的說,一般給客戶端做代理的都是正向代理,給服務(wù)器做代理的就是反向代理。

正向代理和反向代理主要的原理區(qū)別可以參見下圖:

2.4 負(fù)載均衡

一般情況下,客戶端發(fā)送多個(gè)請(qǐng)求到服務(wù)器,服務(wù)器處理請(qǐng)求,其中一部分可能要操作一些資源比如數(shù)據(jù)庫、靜態(tài)資源等,服務(wù)器處理完畢后,再將結(jié)果返回給客戶端。

這種模式對(duì)于早期的系統(tǒng)來說,功能要求不復(fù)雜,且并發(fā)請(qǐng)求相對(duì)較少的情況下還能勝任,成本也低。隨著信息數(shù)量不斷增長,訪問量和數(shù)據(jù)量飛速增長,以及系統(tǒng)業(yè)務(wù)復(fù)雜度持續(xù)增加,這種做法已無法滿足要求,并發(fā)量特別大時(shí),服務(wù)器容易崩。

很明顯這是由于服務(wù)器性能的瓶頸造成的問題,除了堆機(jī)器之外,最重要的做法就是負(fù)載均衡。

請(qǐng)求爆發(fā)式增長的情況下,單個(gè)機(jī)器性能再強(qiáng)勁也無法滿足要求了,這個(gè)時(shí)候集群的概念產(chǎn)生了,單個(gè)服務(wù)器解決不了的問題,可以使用多個(gè)服務(wù)器,然后將請(qǐng)求分發(fā)到各個(gè)服務(wù)器上,將負(fù)載分發(fā)到不同的服務(wù)器,這就是負(fù)載均衡,核心是「分?jǐn)倝毫Α?。Nginx 實(shí)現(xiàn)負(fù)載均衡,一般來說指的是將請(qǐng)求轉(zhuǎn)發(fā)給服務(wù)器集群。

舉個(gè)具體的例子 ??,晚高峰乘坐地鐵的時(shí)候,入站口經(jīng)常會(huì)有地鐵工作人員大喇叭“請(qǐng)走 B 口,B 口人少車空....”,這個(gè)工作人員的作用就是負(fù)載均衡。

2.5 動(dòng)靜分離

為了加快網(wǎng)站的解析速度,可以把動(dòng)態(tài)頁面和靜態(tài)頁面由不同的服務(wù)器來解析,加快解析速度,降低原來單個(gè)服務(wù)器的壓力。

一般來說,都需要將動(dòng)態(tài)資源和靜態(tài)資源分開,由于 Nginx 的高并發(fā)和靜態(tài)資源緩存等特性,經(jīng)常將靜態(tài)資源部署在 Nginx 上。如果請(qǐng)求的是靜態(tài)資源,直接到靜態(tài)資源目錄獲取資源,如果是動(dòng)態(tài)資源的請(qǐng)求,則利用反向代理的原理,把請(qǐng)求轉(zhuǎn)發(fā)給對(duì)應(yīng)后臺(tái)應(yīng)用去處理,從而實(shí)現(xiàn)動(dòng)靜分離。

使用前后端分離后,可以很大程度提升靜態(tài)資源的訪問速度,即使動(dòng)態(tài)服務(wù)不可用,靜態(tài)資源的訪問也不會(huì)受到影響。

3. Nginx 快速安裝

3.1 安裝

我們可以先看看

yum list | grep nginx復(fù)制代碼

來看看

然后

yum install nginx復(fù)制代碼

來安裝 Nginx,然后我們?cè)诿钚兄?nginx -v 就可以看到具體的 Nginx 版本信息,也就安裝完畢了。

3.2 相關(guān)文件夾

然后我們可以使用 rpm -ql nginx 來查看 Nginx 被安裝到了什么地方,有哪些相關(guān)目錄,其中位于 /etc 目錄下的主要是配置文件,還有一些文件見下圖:

主要關(guān)注的文件夾有兩個(gè):

  1. /etc/nginx/conf.d/ 文件夾,是我們進(jìn)行子配置的配置項(xiàng)存放處,/etc/nginx/nginx.conf 主配置文件會(huì)默認(rèn)把這個(gè)文件夾中所有子配置項(xiàng)都引入;

  2. /usr/share/nginx/html/ 文件夾,通常靜態(tài)文件都放在這個(gè)文件夾,也可以根據(jù)你自己的習(xí)慣放其他地方;

3.3 跑起來康康

安裝之后開啟 Nginx,如果系統(tǒng)開啟了防火墻,那么需要設(shè)置一下在防火墻中加入需要開放的端口,下面列舉幾個(gè)常用的防火墻操作(沒開啟的話不用管這個(gè)):

systemctl start firewalld  # 開啟防火墻systemctl stop firewalld   # 關(guān)閉防火墻systemctl status firewalld # 查看防火墻開啟狀態(tài),顯示running則是正在運(yùn)行firewall-cmd --reload      # 重啟防火墻,永久打開端口需要reload一下# 添加開啟端口,--permanent表示永久打開,不加是臨時(shí)打開重啟之后失效firewall-cmd --permanent --zone=public --add-port=8888/tcp# 查看防火墻,添加的端口也可以看到firewall-cmd --list-all復(fù)制代碼

然后設(shè)置 Nginx 的開機(jī)啟動(dòng):

systemctl enable nginx復(fù)制代碼

啟動(dòng) Nginx (其他命令后面有詳細(xì)講解):

systemctl start nginx復(fù)制代碼

然后訪問你的 IP,這時(shí)候就可以看到 Nginx 的歡迎頁面了~ Welcome to nginx! ??

3.4 安裝 nvm & node & git

# 下載 nvm,或者看官網(wǎng)的步驟 https://github.com/nvm-sh/nvm#install--update-scriptcurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.35.3/install.sh | bashsource   ~/.bashrc    # 安裝完畢后,更新配置文件即可使用 nvm 命令nvm ls-remote         # 查看遠(yuǎn)程 node 版本nvm install v12.16.3  # 選一個(gè)你要安裝的版本安裝,我這里選擇 12.16.3nvm list              # 安裝完畢查看安裝的 node 版本node -v               # 查看是否安裝好了yum install git   # git 安裝復(fù)制代碼

4. Nginx 操作常用命令

Nginx 的命令在控制臺(tái)中輸入 nginx -h 就可以看到完整的命令,這里列舉幾個(gè)常用的命令:

nginx -s reload  # 向主進(jìn)程發(fā)送信號(hào),重新加載配置文件,熱重啟nginx -s reopen	 # 重啟 Nginxnginx -s stop    # 快速關(guān)閉nginx -s quit    # 等待工作進(jìn)程處理完成后關(guān)閉nginx -T         # 查看當(dāng)前 Nginx 最終的配置nginx -t -c <配置路徑>    # 檢查配置是否有問題,如果已經(jīng)在配置目錄,則不需要-c復(fù)制代碼

systemctl 是 Linux 系統(tǒng)應(yīng)用管理工具 systemd 的主命令,用于管理系統(tǒng),我們也可以用它來對(duì) Nginx 進(jìn)行管理,相關(guān)命令如下:

systemctl start nginx    # 啟動(dòng) Nginxsystemctl stop nginx     # 停止 Nginxsystemctl restart nginx  # 重啟 Nginxsystemctl reload nginx   # 重新加載 Nginx,用于修改配置后systemctl enable nginx   # 設(shè)置開機(jī)啟動(dòng) Nginxsystemctl disable nginx  # 關(guān)閉開機(jī)啟動(dòng) Nginxsystemctl status nginx   # 查看 Nginx 運(yùn)行狀態(tài)復(fù)制代碼

5. Nginx 配置語法

就跟前面文件作用講解的圖所示,Nginx 的主配置文件是 /etc/nginx/nginx.conf,你可以使用 cat -n nginx.conf 來查看配置。

nginx.conf 結(jié)構(gòu)圖可以這樣概括:

main        # 全局配置,對(duì)全局生效├── events  # 配置影響 Nginx 服務(wù)器或與用戶的網(wǎng)絡(luò)連接├── http    # 配置代理,緩存,日志定義等絕大多數(shù)功能和第三方模塊的配置│   ├── upstream # 配置后端服務(wù)器具體地址,負(fù)載均衡配置不可或缺的部分│   ├── server   # 配置虛擬主機(jī)的相關(guān)參數(shù),一個(gè) http 塊中可以有多個(gè) server 塊│   ├── server│   │   ├── location  # server 塊可以包含多個(gè) location 塊,location 指令用于匹配 uri│   │   ├── location│   │   └── ...│   └── ...└── ...復(fù)制代碼

一個(gè) Nginx 配置文件的結(jié)構(gòu)就像 nginx.conf 顯示的那樣,配置文件的語法規(guī)則:

  1. 配置文件由指令與指令塊構(gòu)成;

  2. 每條指令以 ; 分號(hào)結(jié)尾,指令與參數(shù)間以空格符號(hào)分隔;

  3. 指令塊以 {} 大括號(hào)將多條指令組織在一起;

  4. include 語句允許組合多個(gè)配置文件以提升可維護(hù)性;

  5. 使用 # 符號(hào)添加注釋,提高可讀性;

  6. 使用 $ 符號(hào)使用變量;

  7. 部分指令的參數(shù)支持正則表達(dá)式;

5.1 典型配置

Nginx 的典型配置:

user  nginx;                        # 運(yùn)行用戶,默認(rèn)即是nginx,可以不進(jìn)行設(shè)置worker_processes  1;                # Nginx 進(jìn)程數(shù),一般設(shè)置為和 CPU 核數(shù)一樣error_log  /var/log/nginx/error.log warn;   # Nginx 的錯(cuò)誤日志存放目錄pid        /var/run/nginx.pid;      # Nginx 服務(wù)啟動(dòng)時(shí)的 pid 存放位置events {    use epoll;     # 使用epoll的I/O模型(如果你不知道Nginx該使用哪種輪詢方法,會(huì)自動(dòng)選擇一個(gè)最適合你操作系統(tǒng)的)    worker_connections 1024;   # 每個(gè)進(jìn)程允許最大并發(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ò)報(bào)文段的數(shù)量    tcp_nodelay         on;    keepalive_timeout   65;   # 保持連接的時(shí)間,也叫超時(shí)時(shí)間,單位秒    types_hash_max_size 2048;    include             /etc/nginx/mime.types;      # 文件擴(kuò)展名與類型映射表    default_type        application/octet-stream;   # 默認(rèn)文件類型    include /etc/nginx/conf.d/*.conf;   # 加載子配置項(xiàng)        server {    	listen       80;       # 配置監(jiān)聽的端口    	server_name  localhost;    # 配置的域名    	    	location / {    		root   /usr/share/nginx/html;  # 網(wǎng)站根目錄    		index  index.html index.htm;   # 默認(rèn)首頁文件    		deny 172.168.22.11;   # 禁止訪問的ip地址,可以為all    		allow 172.168.33.44; # 允許訪問的ip地址,可以為all    	}    	    	error_page 500 502 503 504 /50x.html;  # 默認(rèn)50x對(duì)應(yīng)的訪問頁面    	error_page 400 404 error.html;   # 同上    }}復(fù)制代碼

server 塊可以包含多個(gè) location 塊,location 指令用于匹配 uri,語法:

location [ = | ~ | ~* | ^~] uri {	...}復(fù)制代碼

指令后面:

  1. = 精確匹配路徑,用于不含正則表達(dá)式的 uri 前,如果匹配成功,不再進(jìn)行后續(xù)的查找;

  2. ^~ 用于不含正則表達(dá)式的 uri; 前,表示如果該符號(hào)后面的字符是最佳匹配,采用該規(guī)則,不再進(jìn)行后續(xù)的查找;

  3. ~ 表示用該符號(hào)后面的正則去匹配路徑,區(qū)分大小寫;

  4. ~* 表示用該符號(hào)后面的正則去匹配路徑,不區(qū)分大小寫。跟 ~ 優(yōu)先級(jí)都比較低,如有多個(gè)location的正則能匹配的話,則使用正則表達(dá)式最長的那個(gè);

如果 uri 包含正則表達(dá)式,則必須要有 ~~* 標(biāo)志。

5.2 全局變量

Nginx 有一些常用的全局變量,你可以在配置的任何位置使用它們,如下表:

全局變量名功能
$host請(qǐng)求信息中的 Host,如果請(qǐng)求中沒有 Host 行,則等于設(shè)置的服務(wù)器名,不包含端口
$request_method客戶端請(qǐng)求類型,如 GET、POST
$remote_addr客戶端的 IP 地址
$args請(qǐng)求中的參數(shù)
$arg_PARAMETERGET 請(qǐng)求中變量名 PARAMETER 參數(shù)的值,例如:$http_user_agent(Uaer-Agent 值), $http_referer...
$content_length請(qǐng)求頭中的 Content-length 字段
$http_user_agent客戶端agent信息
$http_cookie客戶端cookie信息
$remote_addr客戶端的IP地址
$remote_port客戶端的端口
$http_user_agent客戶端agent信息
$server_protocol請(qǐng)求使用的協(xié)議,如 HTTP/1.0HTTP/1.1
$server_addr服務(wù)器地址
$server_name服務(wù)器名稱
$server_port服務(wù)器的端口號(hào)
$schemeHTTP 方法(如http,https)

還有更多的內(nèi)置預(yù)定義變量,可以直接搜索關(guān)鍵字「nginx內(nèi)置預(yù)定義變量」可以看到一堆博客寫這個(gè),這些變量都可以在配置文件中直接使用。

6. 設(shè)置二級(jí)域名虛擬主機(jī)

在某某云 ?? 上購買了域名之后,就可以配置虛擬主機(jī)了,一般配置的路徑在 域名管理 -> 解析 -> 添加記錄 中添加二級(jí)域名,配置后某某云會(huì)把二級(jí)域名也解析到我們配置的服務(wù)器 IP 上,然后我們?cè)?Nginx 上配置一下虛擬主機(jī)的訪問監(jiān)聽,就可以拿到從這個(gè)二級(jí)域名過來的請(qǐng)求了。

現(xiàn)在我自己的服務(wù)器上配置了一個(gè) fe 的二級(jí)域名,也就是說在外網(wǎng)訪問 fe.sherlocked93.club 的時(shí)候,也可以訪問到我們的服務(wù)器了。

由于默認(rèn)配置文件 /etc/nginx/nginx.conf 的 http 模塊中有一句 include /etc/nginx/conf.d/*.conf 也就是說 conf.d 文件夾下的所有 *.conf 文件都會(huì)作為子配置項(xiàng)被引入配置文件中。為了維護(hù)方便,我在 /etc/nginx/conf.d 文件夾中新建一個(gè) fe.sherlocked93.club.conf

# /etc/nginx/conf.d/fe.sherlocked93.club.confserver {  listen 80;	server_name fe.sherlocked93.club;	location / {		root  /usr/share/nginx/html/fe;		index index.html;	}}復(fù)制代碼

然后在 /usr/share/nginx/html 文件夾下新建 fe 文件夾,新建文件 index.html,內(nèi)容隨便寫點(diǎn),改完 nginx -s reload 重新加載,瀏覽器中輸入 fe.sherlocked93.club,發(fā)現(xiàn)從二級(jí)域名就可以訪問到我們剛剛新建的 fe 文件夾:

7. 配置反向代理

反向代理是工作中最常用的服務(wù)器功能,經(jīng)常被用來解決跨域問題,下面簡(jiǎn)單介紹一下如何實(shí)現(xiàn)反向代理。

首先進(jìn)入 Nginx 的主配置文件:

vim /etc/nginx/nginx.conf復(fù)制代碼

為了看起來方便,把行號(hào)顯示出來 :set nu (個(gè)人習(xí)慣),然后我們?nèi)?http 模塊的 server 塊中的 location /,增加一行將默認(rèn)網(wǎng)址重定向到最大學(xué)習(xí)網(wǎng)站 Bilibili 的 proxy_pass 配置 ?? :

改完保存退出,nginx -s reload 重新加載,進(jìn)入默認(rèn)網(wǎng)址,那么現(xiàn)在就直接跳轉(zhuǎn)到 B 站了,實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的代理。

實(shí)際使用中,可以將請(qǐng)求轉(zhuǎn)發(fā)到本機(jī)另一個(gè)服務(wù)器上,也可以根據(jù)訪問的路徑跳轉(zhuǎn)到不同端口的服務(wù)中。

比如我們監(jiān)聽 9001 端口,然后把訪問不同路徑的請(qǐng)求進(jìn)行反向代理:

  1. 把訪問 http://127.0.0.1:9001/edu 的請(qǐng)求轉(zhuǎn)發(fā)到 http://127.0.0.1:8080

  2. 把訪問 http://127.0.0.1:9001/vod 的請(qǐng)求轉(zhuǎn)發(fā)到 http://127.0.0.1:8081

這種要怎么配置呢,首先同樣打開主配置文件,然后在 http 模塊下增加一個(gè) server 塊:

server {  listen 9001;  server_name *.sherlocked93.club;  location ~ /edu/ {    proxy_pass http://127.0.0.1:8080;  }    location ~ /vod/ {    proxy_pass http://127.0.0.1:8081;  }}復(fù)制代碼

反向代理還有一些其他的指令,可以了解一下:

  1. proxy_set_header:在將客戶端請(qǐng)求發(fā)送給后端服務(wù)器之前,更改來自客戶端的請(qǐng)求頭信息。

  2. proxy_connect_timeout:配置Nginx與后端代理服務(wù)器嘗試建立連接的超時(shí)時(shí)間。

  3. proxy_read_timeout:配置Nginx向后端服務(wù)器組發(fā)出read請(qǐng)求后,等待相應(yīng)的超時(shí)時(shí)間。

  4. proxy_send_timeout:配置Nginx向后端服務(wù)器組發(fā)出write請(qǐng)求后,等待相應(yīng)的超時(shí)時(shí)間。

  5. proxy_redirect:用于修改后端服務(wù)器返回的響應(yīng)頭中的Location和Refresh。

8. 跨域 CORS 配置

關(guān)于簡(jiǎn)單請(qǐng)求、非簡(jiǎn)單請(qǐng)求、跨域的概念,前面已經(jīng)介紹過了,還不了解的可以看看前面的講解?,F(xiàn)在前后端分離的項(xiàng)目一統(tǒng)天下,經(jīng)常本地起了前端服務(wù),需要訪問不同的后端地址,不可避免遇到跨域問題。

要解決跨域問題,我們來制造一個(gè)跨域問題。首先和前面設(shè)置二級(jí)域名的方式一樣,先設(shè)置好 fe.sherlocked93.clubbe.sherlocked93.club 二級(jí)域名,都指向本云服務(wù)器地址,雖然對(duì)應(yīng) IP 是一樣的,但是在 fe.sherlocked93.club 域名發(fā)出的請(qǐng)求訪問 be.sherlocked93.club 域名的請(qǐng)求還是跨域了,因?yàn)樵L問的 host 不一致(如果不知道啥原因參見前面跨域的內(nèi)容)。

8.1 使用反向代理解決跨域

在前端服務(wù)地址為 fe.sherlocked93.club 的頁面請(qǐng)求 be.sherlocked93.club 的后端服務(wù)導(dǎo)致的跨域,可以這樣配置:

server {  listen 9001;  server_name fe.sherlocked93.club;  location / {    proxy_pass be.sherlocked93.club;  }}復(fù)制代碼

這樣就將對(duì)前一個(gè)域名 fe.sherlocked93.club 的請(qǐng)求全都代理到了 be.sherlocked93.club,前端的請(qǐng)求都被我們用服務(wù)器代理到了后端地址下,繞過了跨域。

這里對(duì)靜態(tài)文件的請(qǐng)求和后端服務(wù)的請(qǐng)求都以 fe.sherlocked93.club 開始,不易區(qū)分,所以為了實(shí)現(xiàn)對(duì)后端服務(wù)請(qǐng)求的統(tǒng)一轉(zhuǎn)發(fā),通常我們會(huì)約定對(duì)后端服務(wù)的請(qǐng)求加上 /apis/ 前綴或者其他的 path 來和對(duì)靜態(tài)資源的請(qǐng)求加以區(qū)分,此時(shí)我們可以這樣配置:

# 請(qǐng)求跨域,約定代理后端服務(wù)請(qǐng)求path以/apis/開頭location ^~/apis/ {    # 這里重寫了請(qǐng)求,將正則匹配中的第一個(gè)分組的path拼接到真正的請(qǐng)求后面,并用break停止后續(xù)匹配    rewrite ^/apis/(.*)$ /$1 break;    proxy_pass be.sherlocked93.club;      # 兩個(gè)域名之間cookie的傳遞與回寫    proxy_cookie_domain be.sherlocked93.club fe.sherlocked93.club;}復(fù)制代碼

這樣,靜態(tài)資源我們使用 fe.sherlocked93.club/xx.html,動(dòng)態(tài)資源我們使用 fe.sherlocked93.club/apis/getAwo,瀏覽器頁面看起來仍然訪問的前端服務(wù)器,繞過了瀏覽器的同源策略,畢竟我們看起來并沒有跨域。

也可以統(tǒng)一一點(diǎn),直接把前后端服務(wù)器地址直接都轉(zhuǎn)發(fā)到另一個(gè) server.sherlocked93.club,只通過在后面添加的 path 來區(qū)分請(qǐng)求的是靜態(tài)資源還是后端服務(wù),看需求了。

8.2 配置 header 解決跨域

當(dāng)瀏覽器在訪問跨源的服務(wù)器時(shí),也可以在跨域的服務(wù)器上直接設(shè)置 Nginx,從而前端就可以無感地開發(fā),不用把實(shí)際上訪問后端的地址改成前端服務(wù)的地址,這樣可適性更高。

比如前端站點(diǎn)是 fe.sherlocked93.club,這個(gè)地址下的前端頁面請(qǐng)求 be.sherlocked93.club 下的資源,比如前者的 fe.sherlocked93.club/index.html 內(nèi)容是這樣的:

<html><body>    <h1>welcome fe.sherlocked93.club!!<h1>    <script type='text/javascript'>    var xmlhttp = new XMLHttpRequest()    xmlhttp.open("GET", "http://be.sherlocked93.club/index.html", true);    xmlhttp.send();    </script></body></html>復(fù)制代碼

打開瀏覽器訪問 fe.sherlocked93.club/index.html 的結(jié)果如下:

很明顯這里是跨域請(qǐng)求,在瀏覽器中直接訪問 http://be.sherlocked93.club/index.html 是可以訪問到的,但是在 fe.sherlocked93.club 的 html 頁面訪問就會(huì)出現(xiàn)跨域。

/etc/nginx/conf.d/ 文件夾中新建一個(gè)配置文件,對(duì)應(yīng)二級(jí)域名 be.sherlocked93.club

# /etc/nginx/conf.d/be.sherlocked93.club.confserver {  listen       80;  server_name  be.sherlocked93.club;  	add_header 'Access-Control-Allow-Origin' $http_origin;   # 全局變量獲得當(dāng)前請(qǐng)求origin,帶cookie的請(qǐng)求不支持*	add_header 'Access-Control-Allow-Credentials' 'true';    # 為 true 可帶上 cookie	add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';  # 允許請(qǐng)求方法	add_header 'Access-Control-Allow-Headers' $http_access_control_request_headers;  # 允許請(qǐng)求的 header,可以為 *	add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';	  if ($request_method = 'OPTIONS') {		add_header 'Access-Control-Max-Age' 1728000;   # OPTIONS 請(qǐng)求的有效期,在有效期內(nèi)不用發(fā)出另一條預(yù)檢請(qǐng)求		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 重新加載配置。這時(shí)再訪問 fe.sherlocked93.club/index.html 結(jié)果如下,請(qǐng)求中出現(xiàn)了我們剛剛配置的 Header:

解決了跨域問題。

9. 開啟 gzip 壓縮

gzip 是一種常用的網(wǎng)頁壓縮技術(shù),傳輸?shù)木W(wǎng)頁經(jīng)過 gzip 壓縮之后大小通??梢宰?yōu)樵瓉淼囊话肷踔粮。ü倬W(wǎng)原話),更小的網(wǎng)頁體積也就意味著帶寬的節(jié)約和傳輸速度的提升,特別是對(duì)于訪問量巨大大型網(wǎng)站來說,每一個(gè)靜態(tài)資源體積的減小,都會(huì)帶來可觀的流量與帶寬的節(jié)省。

百度可以找到很多檢測(cè)站點(diǎn)來查看目標(biāo)網(wǎng)頁有沒有開啟 gzip 壓縮,在下隨便找了一個(gè) <網(wǎng)頁GZIP壓縮檢測(cè)> 輸入掘金 juejin.im 來偷窺下掘金有沒有開啟 gzip。

這里可以看到掘金是開啟了 gzip 的,壓縮效果還挺不錯(cuò),達(dá)到了 52% 之多,本來 34kb 的網(wǎng)頁體積,壓縮完只需要 16kb,可以想象網(wǎng)頁傳輸速度提升了不少。

9.1 Nginx 配置 gzip

使用 gzip 不僅需要 Nginx 配置,瀏覽器端也需要配合,需要在請(qǐng)求消息頭中包含 Accept-Encoding: gzip(IE5 之后所有的瀏覽器都支持了,是現(xiàn)代瀏覽器的默認(rèn)設(shè)置)。一般在請(qǐng)求 html 和 css 等靜態(tài)資源的時(shí)候,支持的瀏覽器在 request 請(qǐng)求靜態(tài)資源的時(shí)候,會(huì)加上 Accept-Encoding: gzip 這個(gè) header,表示自己支持 gzip 的壓縮方式,Nginx 在拿到這個(gè)請(qǐng)求的時(shí)候,如果有相應(yīng)配置,就會(huì)返回經(jīng)過 gzip 壓縮過的文件給瀏覽器,并在 response 相應(yīng)的時(shí)候加上 content-encoding: gzip 來告訴瀏覽器自己采用的壓縮方式(因?yàn)闉g覽器在傳給服務(wù)器的時(shí)候一般還告訴服務(wù)器自己支持好幾種壓縮方式),瀏覽器拿到壓縮的文件后,根據(jù)自己的解壓方式進(jìn)行解析。

先來看看 Nginx 怎么進(jìn)行 gzip 配置,和之前的配置一樣,為了方便管理,還是在 /etc/nginx/conf.d/ 文件夾中新建配置文件 gzip.conf

# /etc/nginx/conf.d/gzip.confgzip on; # 默認(rèn)off,是否開啟gzipgzip_types text/plain text/css application/json application/x-javascript text/xml application/xml application/xml+rss text/javascript;# 上面兩個(gè)開啟基本就能跑起了,下面的愿意折騰就了解一下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ù)制代碼

稍微解釋一下:

  1. gzip_types:要采用 gzip 壓縮的 MIME 文件類型,其中 text/html 被系統(tǒng)強(qiáng)制啟用;

  2. gzip_static:默認(rèn) off,該模塊啟用后,Nginx 首先檢查是否存在請(qǐng)求靜態(tài)文件的 gz 結(jié)尾的文件,如果有則直接返回該 .gz 文件內(nèi)容;

  3. gzip_proxied:默認(rèn) off,nginx做為反向代理時(shí)啟用,用于設(shè)置啟用或禁用從代理服務(wù)器上收到相應(yīng)內(nèi)容 gzip 壓縮;

  4. gzip_vary:用于在響應(yīng)消息頭中添加 Vary:Accept-Encoding,使代理服務(wù)器根據(jù)請(qǐng)求頭中的 Accept-Encoding 識(shí)別是否啟用 gzip 壓縮;

  5. gzip_comp_level:gzip 壓縮比,壓縮級(jí)別是 1-9,1 壓縮級(jí)別最低,9 最高,級(jí)別越高壓縮率越大,壓縮時(shí)間越長,建議 4-6;

  6. gzip_buffers:獲取多少內(nèi)存用于緩存壓縮結(jié)果,16 8k 表示以 8k*16 為單位獲得;

  7. gzip_min_length:允許壓縮的頁面最小字節(jié)數(shù),頁面字節(jié)數(shù)從header頭中的 Content-Length 中進(jìn)行獲取。默認(rèn)值是 0,不管頁面多大都?jí)嚎s。建議設(shè)置成大于 1k 的字節(jié)數(shù),小于 1k 可能會(huì)越壓越大;

  8. gzip_http_version:默認(rèn) 1.1,啟用 gzip 所需的 HTTP 最低版本;

這個(gè)配置可以插入到 http 模塊整個(gè)服務(wù)器的配置里,也可以插入到需要使用的虛擬主機(jī)的 server 或者下面的 location 模塊中,當(dāng)然像上面我們這樣寫的話就是被 include 到 http 模塊中了。

其他更全的配置信息可以查看 <官網(wǎng)文檔ngx_http_gzip_module>,配置前是這樣的:

配置之后 response 的 header 里面多了一個(gè) Content-Encoding: gzip,返回信息被壓縮了:

注意了,一般 gzip 的配置建議加上 gzip_min_length 1k,不加的話:

由于文件太小,gzip 壓縮之后得到了 -48% 的體積優(yōu)化,壓縮之后體積還比壓縮之前體積大了,所以最好設(shè)置低于 1kb 的文件就不要 gzip 壓縮了 ??

9.2 Webpack 的 gzip 配置

當(dāng)前端項(xiàng)目使用 Webpack 進(jìn)行打包的時(shí)候,也可以開啟 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,               // 文件壓縮閾值,對(duì)超過10k的進(jìn)行壓縮          deleteOriginalAssets: false     // 是否刪除源文件        })]      }    }  },  ...}復(fù)制代碼

由此打包出來的文件如下圖:

這里可以看到某些打包之后的文件下面有一個(gè)對(duì)應(yīng)的 .gz 經(jīng)過 gzip 壓縮之后的文件,這是因?yàn)檫@個(gè)文件超過了 10kb,有的文件沒有超過 10kb 就沒有進(jìn)行 gzip 打包,如果你期望壓縮文件的體積閾值小一點(diǎn),可以在 compression-webpack-plugin 這個(gè)插件的配置里進(jìn)行對(duì)應(yīng)配置。

那么為啥這里 Nginx 已經(jīng)有了 gzip 壓縮,Webpack 這里又整了個(gè) gzip 呢,因?yàn)槿绻际鞘褂?Nginx 來壓縮文件,會(huì)耗費(fèi)服務(wù)器的計(jì)算資源,如果服務(wù)器的 gzip_comp_level 配置的比較高,就更增加服務(wù)器的開銷,相應(yīng)增加客戶端的請(qǐng)求時(shí)間,得不償失。

如果壓縮的動(dòng)作在前端打包的時(shí)候就做了,把打包之后的高壓縮等級(jí)文件作為靜態(tài)資源放在服務(wù)器上,Nginx 會(huì)優(yōu)先查找這些壓縮之后的文件返回給客戶端,相當(dāng)于把壓縮文件的動(dòng)作從 Nginx 提前給 Webpack 打包的時(shí)候完成,節(jié)約了服務(wù)器資源,所以一般推介在生產(chǎn)環(huán)境應(yīng)用 Webpack 配置 gzip 壓縮。

10. 配置負(fù)載均衡

負(fù)載均衡在之前已經(jīng)介紹了相關(guān)概念了,主要思想就是把負(fù)載均勻合理地分發(fā)到多個(gè)服務(wù)器上,實(shí)現(xiàn)壓力分流的目的。

主要配置如下:

http {  upstream myserver {  	# ip_hash;  # ip_hash 方式    # fair;   # fair 方式    server 127.0.0.1:8081;  # 負(fù)載均衡目的服務(wù)地址    server 127.0.0.1:8080;    server 127.0.0.1:8082 weight=10;  # weight 方式,不寫默認(rèn)為 1  }   server {    location / {    	proxy_pass http://myserver;      proxy_connect_timeout 10;    }  }}復(fù)制代碼

Nginx 提供了好幾種分配方式,默認(rèn)為輪詢,就是輪流來。有以下幾種分配方式:

  1. 輪詢,默認(rèn)方式,每個(gè)請(qǐng)求按時(shí)間順序逐一分配到不同的后端服務(wù)器,如果后端服務(wù)掛了,能自動(dòng)剔除;

  2. weight,權(quán)重分配,指定輪詢幾率,權(quán)重越高,在被訪問的概率越大,用于后端服務(wù)器性能不均的情況;

  3. ip_hash,每個(gè)請(qǐng)求按訪問 IP 的 hash 結(jié)果分配,這樣每個(gè)訪客固定訪問一個(gè)后端服務(wù)器,可以解決動(dòng)態(tài)網(wǎng)頁 session 共享問題。負(fù)載均衡每次請(qǐng)求都會(huì)重新定位到服務(wù)器集群中的某一個(gè),那么已經(jīng)登錄某一個(gè)服務(wù)器的用戶再重新定位到另一個(gè)服務(wù)器,其登錄信息將會(huì)丟失,這樣顯然是不妥的;

  4. fair(第三方),按后端服務(wù)器的響應(yīng)時(shí)間分配,響應(yīng)時(shí)間短的優(yōu)先分配,依賴第三方插件 nginx-upstream-fair,需要先安裝;

11. 配置動(dòng)靜分離

動(dòng)靜分離在之前也介紹過了,就是把動(dòng)態(tài)和靜態(tài)的請(qǐng)求分開。方式主要有兩種,一種 是純粹把靜態(tài)文件獨(dú)立成單獨(dú)的域名,放在獨(dú)立的服務(wù)器上,也是目前主流推崇的方案。另外一種方法就是動(dòng)態(tài)跟靜態(tài)文件混合在一起發(fā)布, 通過 Nginx 配置來分開。

通過 location 指定不同的后綴名實(shí)現(xiàn)不同的請(qǐng)求轉(zhuǎn)發(fā)。通過 expires 參數(shù)設(shè)置,可以使瀏覽器緩存過期時(shí)間,減少與服務(wù)器之前的請(qǐng)求和流量。具體 expires 定義:是給一個(gè)資源設(shè)定一個(gè)過期時(shí)間,也就是說無需去服務(wù)端驗(yàn)證,直接通過瀏覽器自身確認(rèn)是否過期即可,所以不會(huì)產(chǎn)生額外的流量。此種方法非常適合不經(jīng)常變動(dòng)的資源。(如果經(jīng)常更新的文件,不建議使用 expires 來緩存),我這里設(shè)置 3d,表示在這 3 天之內(nèi)訪問這個(gè)URL,發(fā)送一個(gè)請(qǐng)求,比對(duì)服務(wù)器該文件最后更新時(shí)間沒有變化。則不會(huì)從服務(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. 配置高可用集群(雙機(jī)熱備)

當(dāng)主 Nginx 服務(wù)器宕機(jī)之后,切換到備份 Nginx 服務(wù)器

首先安裝 keepalived,

yum install keepalived -y復(fù)制代碼

然后編輯 /etc/keepalived/keepalived.conf 配置文件,并在配置文件中增加 vrrp_script 定義一個(gè)外圍檢測(cè)機(jī)制,并在 vrrp_instance 中通過定義 track_script 來追蹤腳本執(zhí)行過程,實(shí)現(xiàn)節(jié)點(diǎn)轉(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 { // 檢測(cè)機(jī)制的腳本名稱為chk_maintainace    script "[[ -e/etc/keepalived/down ]] && exit 1 || exit 0" // 可以是腳本路徑或腳本命令    // script "/etc/keepalived/nginx_check.sh"    // 比如這樣的腳本路徑    interval 2  // 每隔2秒檢測(cè)一次    weight -20  // 當(dāng)腳本執(zhí)行成立,那么把當(dāng)前服務(wù)器優(yōu)先級(jí)改為-20}vrrp_instanceVI_1 {   // 每一個(gè)vrrp_instance就是定義一個(gè)虛擬路由器    state MASTER      // 主機(jī)為MASTER,備用機(jī)為BACKUP    interface eth0    // 網(wǎng)卡名字,可以從ifconfig中查找    virtual_router_id 51 // 虛擬路由的id號(hào),一般小于255,主備機(jī)id需要一樣    priority 100      // 優(yōu)先級(jí),master的優(yōu)先級(jí)比backup的大    advert_int 1      // 默認(rèn)心跳間隔    authentication {  // 認(rèn)證機(jī)制        auth_type PASS        auth_pass 1111   // 密碼    }    virtual_ipaddress {  // 虛擬地址vip       172.16.2.8    }}復(fù)制代碼

其中檢測(cè)腳本 nginx_check.sh,這里提供一個(gè):

#!/bin/bashA=`ps -C nginx --no-header | wc -l`if [ $A -eq 0 ];then    /usr/sbin/nginx # 嘗試重新啟動(dòng)nginx    sleep 2         # 睡眠2秒    if [ `ps -C nginx --no-header | wc -l` -eq 0 ];then        killall keepalived # 啟動(dòng)失敗,將keepalived服務(wù)殺死。將vip漂移到其它備份節(jié)點(diǎn)    fifi復(fù)制代碼

復(fù)制一份到備份服務(wù)器,備份 Nginx 的配置要將 state 后改為 BACKUP,priority 改為比主機(jī)小。

設(shè)置完畢后各自 service keepalived start 啟動(dòng),經(jīng)過訪問成功之后,可以把 Master 機(jī)的 keepalived 停掉,此時(shí) Master 機(jī)就不再是主機(jī)了 service keepalived stop,看訪問虛擬 IP 時(shí)是否能夠自動(dòng)切換到備機(jī) ip addr。

再次啟動(dòng) Master 的 keepalived,此時(shí) vip 又變到了主機(jī)上。

13. 適配 PC 或移動(dòng)設(shè)備

根據(jù)用戶設(shè)備不同返回不同樣式的站點(diǎn),以前經(jīng)常使用的是純前端的自適應(yīng)布局,但無論是復(fù)雜性和易用性上面還是不如分開編寫的好,比如我們常見的淘寶、京東......這些大型網(wǎng)站就都沒有采用自適應(yīng),而是用分開制作的方式,根據(jù)用戶請(qǐng)求的 user-agent 來判斷是返回 PC 還是 H5 站點(diǎn)。

首先在 /usr/share/nginx/html 文件夾下 mkdir 分別新建兩個(gè)文件夾 PCmobile,vim 編輯兩個(gè) index.html 隨便寫點(diǎn)內(nèi)容。

cd /usr/share/nginx/htmlmkdir pc mobilecd pcvim index.html   # 隨便寫點(diǎn)比如 hello pc!cd ../mobilevim index.html   # 隨便寫點(diǎn)比如 hello mobile!復(fù)制代碼

然后和設(shè)置二級(jí)域名虛擬主機(jī)時(shí)候一樣,去 /etc/nginx/conf.d 文件夾下新建一個(gè)配置文件 fe.sherlocked93.club.conf

# /etc/nginx/conf.d/fe.sherlocked93.club.confserver {  listen 80;	server_name fe.sherlocked93.club;	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ù)制代碼

配置基本沒什么不一樣的,主要多了一個(gè) if 語句,然后使用 $http_user_agent 全局變量來判斷用戶請(qǐng)求的 user-agent,指向不同的 root 路徑,返回對(duì)應(yīng)站點(diǎn)。

在瀏覽器訪問這個(gè)站點(diǎn),然后 F12 中模擬使用手機(jī)訪問:

可以看到在模擬使用移動(dòng)端訪問的時(shí)候,Nginx 返回的站點(diǎn)變成了移動(dòng)端對(duì)應(yīng)的 html 了。

14. 配置 HTTPS

具體配置過程網(wǎng)上挺多的了,也可以使用你購買的某某云,一般都會(huì)有免費(fèi)申請(qǐng)的服務(wù)器證書,安裝直接看所在云的操作指南即可。

我購買的騰訊云提供的亞洲誠信機(jī)構(gòu)頒發(fā)的免費(fèi)證書只能一個(gè)域名使用,二級(jí)域名什么的需要另外申請(qǐng),但是申請(qǐng)審批比較快,一般幾分鐘就能成功,然后下載證書的壓縮文件,里面有個(gè) nginx 文件夾,把 xxx.crtxxx.key 文件拷貝到服務(wù)器目錄,再配置下:

server {  listen 443 ssl http2 default_server;   # SSL 訪問端口號(hào)為 443  server_name sherlocked93.club;         # 填寫綁定證書的域名  ssl_certificate /etc/nginx/https/1_sherlocked93.club_bundle.crt;   # 證書文件地址  ssl_certificate_key /etc/nginx/https/2_sherlocked93.club.key;      # 私鑰文件地址  ssl_session_timeout 10m;  ssl_protocols TLSv1 TLSv1.1 TLSv1.2;      #請(qǐng)按照以下協(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 校驗(yàn)一下,沒問題就 nginx -s reload,現(xiàn)在去訪問 https://sherlocked93.club/ 就能訪問 HTTPS 版的網(wǎng)站了。

一般還可以加上幾個(gè)增強(qiáng)安全性的命令:

add_header X-Frame-Options DENY;           # 減少點(diǎn)擊劫持add_header X-Content-Type-Options nosniff; # 禁止服務(wù)器自動(dòng)解析資源類型add_header X-Xss-Protection 1;             # 防XSS攻擊復(fù)制代碼

15. 一些常用技巧

15.1 靜態(tài)服務(wù)

server {  listen       80;  server_name  static.sherlocked93.club;  charset utf-8;    # 防止中文文件名亂碼  location /download {    alias	          /usr/share/nginx/html/static;  # 靜態(tài)資源目錄        autoindex               on;    # 開啟靜態(tài)資源列目錄    autoindex_exact_size    off;   # on(默認(rèn))顯示文件的確切大小,單位是byte;off顯示文件大概大小,單位KB、MB、GB    autoindex_localtime     off;   # off(默認(rèn))時(shí)顯示的文件時(shí)間為GMT時(shí)間;on顯示的文件時(shí)間為服務(wù)器時(shí)間  }}復(fù)制代碼

15.2 圖片防盜鏈

server {  listen       80;          server_name  *.sherlocked93.club;    # 圖片防盜鏈  location ~* \.(gif|jpg|jpeg|png|bmp|swf)$ {    valid_referers none blocked 192.168.0.2;  # 只允許本機(jī) IP 外鏈引用    if ($invalid_referer){      return 403;    }  }}復(fù)制代碼

15.3 請(qǐng)求過濾

# 非指定請(qǐng)求全返回 403if ( $request_method !~ ^(GET|POST|HEAD)$ ) {  return 403;}location / {  # IP訪問限制(只允許IP是 192.168.0.2 機(jī)器訪問)  allow 192.168.0.2;  deny all;    root   html;  index  index.html index.htm;}復(fù)制代碼

15.4 配置圖片、字體等靜態(tài)文件緩存

由于圖片、字體、音頻、視頻等靜態(tài)文件在打包的時(shí)候通常會(huì)增加了 hash,所以緩存可以設(shè)置的長一點(diǎn),先設(shè)置強(qiáng)制緩存,再設(shè)置協(xié)商緩存;如果存在沒有 hash 值的靜態(tài)文件,建議不設(shè)置強(qiáng)制緩存,僅通過協(xié)商緩存判斷是否需要使用緩存。

# 圖片緩存時(shí)間設(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 單頁面項(xiàng)目 history 路由配置

server {  listen       80;  server_name  fe.sherlocked93.club;    location / {    root       /usr/share/nginx/html/dist;  # vue 打包后的文件夾    index      index.html index.htm;    try_files  $uri $uri/ /index.html @rewrites;          expires -1;                          # 首頁一般沒有強(qiáng)制緩存    add_header Cache-Control no-cache;  }    # 接口轉(zhuǎn)發(fā),如果需要的話  #location ~ ^/api {  #  proxy_pass http://be.sherlocked93.club;  #}    location @rewrites {    rewrite ^(.+)$ /index.html break;  }}復(fù)制代碼

15.6 HTTP 請(qǐng)求轉(zhuǎn)發(fā)到 HTTPS

配置完 HTTPS 后,瀏覽器還是可以訪問 HTTP 的地址 http://sherlocked93.club/ 的,可以做一個(gè) 301 跳轉(zhuǎn),把對(duì)應(yīng)域名的 HTTP 請(qǐng)求重定向到 HTTPS 上

server {    listen      80;    server_name www.sherlocked93.club;    # 單域名重定向    if ($host = 'www.sherlocked93.club'){        return 301 https://www.sherlocked93.club$request_uri;    }    # 全局非 https 協(xié)議時(shí)重定向    if ($scheme != 'https') {        return 301 https://$server_name$request_uri;    }    # 或者全部重定向    return 301 https://$server_name$request_uri;    # 以上配置選擇自己需要的即可,不用全部加}復(fù)制代碼

15.7 泛域名路徑分離

這是一個(gè)非常實(shí)用的技能,經(jīng)常有時(shí)候我們可能需要配置一些二級(jí)或者三級(jí)域名,希望通過 Nginx 自動(dòng)指向?qū)?yīng)目錄,比如:

  1. test1.doc.sherlocked93.club 自動(dòng)指向 /usr/share/nginx/html/doc/test1 服務(wù)器地址;

  2. test2.doc.sherlocked93.club 自動(dòng)指向 /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ā)

和之前的功能類似,有時(shí)候我們希望把二級(jí)或者三級(jí)域名鏈接重寫到我們希望的路徑,讓后端就可以根據(jù)路由解析不同的規(guī)則:

  1. test1.serv.sherlocked93.club/api?name=a 自動(dòng)轉(zhuǎn)發(fā)到 127.0.0.1:8080/test1/api?name=a;

  2. test2.serv.sherlocked93.club/api?name=a 自動(dòng)轉(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. 最佳實(shí)踐

  1. 為了使 Nginx 配置更易于維護(hù),建議為每個(gè)服務(wù)創(chuàng)建一個(gè)單獨(dú)的配置文件,存儲(chǔ)在 /etc/nginx/conf.d 目錄,根據(jù)需求可以創(chuàng)建任意多個(gè)獨(dú)立的配置文件。

  2. 獨(dú)立的配置文件,建議遵循以下命名約定 <服務(wù)>.conf,比如域名是 sherlocked93.club,那么你的配置文件的應(yīng)該是這樣的 /etc/nginx/conf.d/sherlocked93.club.conf,如果部署多個(gè)服務(wù),也可以在文件名中加上 Nginx 轉(zhuǎn)發(fā)的端口號(hào),比如 sherlocked93.club.8080.conf,如果是二級(jí)域名,建議也都加上 fe.sherlocked93.club.conf

  3. 常用的、復(fù)用頻率比較高的配置可以放到 /etc/nginx/snippets 文件夾,在 Nginx 的配置文件中需要用到的位置 include 進(jìn)去,以功能來命名,并在每個(gè) snippet 配置文件的開頭注釋標(biāo)明主要功能和引入位置,方便管理。比如之前的 gzipcors 等常用配置,我都設(shè)置了 snippet。

  4. Nginx 日志相關(guān)目錄,內(nèi)以 域名.type.log 命名(比如 be.sherlocked93.club.access.logbe.sherlocked93.club.error.log )位于 /var/log/nginx/ 目錄中,為每個(gè)獨(dú)立的服務(wù)配置不同的訪問權(quán)限和錯(cuò)誤日志文件,這樣查找錯(cuò)誤時(shí),會(huì)更加方便快捷。

本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
web服務(wù)器 IIS、Apache和Ngnix基礎(chǔ)
nginx+tomcat的安裝配置
nginx配置vue 工程并支持對(duì)文件壓縮與優(yōu)化
Nginx參考
Nginx主配置參數(shù)詳解,Nginx配置網(wǎng)站
Nginx 開啟Gzip壓縮的方法(非常的詳解)
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服