Nginx詳解
2021-01-14 00:30:07 軟體

1. Nginx簡介

1.1 Nginx 的應用場景

Nginx ("engine x") 是一個 高效能的 HTTP 和反向代理伺服器,特點是佔有記憶體少,並行能力強。事實上 Nginx 的並行能力確實在同型別的網頁伺服器中表現較好,中國大陸使用 Nginx 的網站使用者有:百度、京東、新浪、網易、騰訊、淘寶等。

Nginx 可以作為靜態頁面的 web 伺服器,同時還支援 CGI 協定的動態語言比如 perl、php等,但是不支援 java,Java 程式只能通過與 tomcat 配合完成。Nginx 專為效能優化而開發,效能是其最重要的考量,實現上非常注重效率 ,能經受高負載的考驗,有報告表明能支援高達 50,000 個並行連線數。

Nginx 是 C語言開發,建議在 Linux 上執行,當然也可以安裝 Windows 版本。

1.2 反向代理與反向代理

正向代理

Nginx 不僅可以做反向代理實現負載均衡,還能用作為正向代理來進行上網等功能。正向代理:如果把區域網外的 Internet 想象成一個巨大的資源庫,則區域網中的使用者端要存取 Internet則需要通過代理伺服器來存取,這種代理服務就稱為正向代理。

image-20210101223821389

反向代理

其實使用者端對代理是無感知的,因為使用者端不需要任何設定就可以存取網頁,我們只需要將請求傳送到反向代理伺服器,由反向代理伺服器去選擇目標伺服器獲取資料後再返回給使用者端,此時反向代理伺服器和目標伺服器對外就是一個伺服器,暴露的是代理伺服器地址,隱藏了真實伺服器 IP 地址。

image-20210101223821389
1.3 負載均衡

使用者端傳送多個請求到伺服器,伺服器處理請求,有一些可能要與資料庫進行互動,伺服器處理完畢後再將結果返回給使用者端。 這種架構模式對於早期的系統相對單一,並行請求相對較少的情況下是比較適合的成本也低。但是隨著資訊數量的不斷增長,存取量和資料量的飛速增長,以及系統業務的複雜度增加,這種架構會造成伺服器相應使用者端的請求日益緩慢,並行量特別大的時候還容易造成伺服器直接崩潰。很明顯這是由於伺服器效能的瓶頸造成的問題,那麼如何解決這種情況呢?

我們首先想到的可能是升級伺服器的設定,比如提高 CPU 執行頻率,加大記憶體等提高機器的物理效能來解決此問題,但是我們知道摩爾定律的日益失效,硬體的效能提升已經不能滿足日益提升的需求了。最明顯的一個例子,天貓雙十一當天某個熱銷商品的瞬時存取量是極其龐大的,那麼類似上面的系統架構,將機器都增加到現有的頂級物理設定,都是不能夠滿足需求的。那麼怎麼辦呢?

上面的分析我們去掉了增加伺服器物理設定來解決問題的辦法也就是說縱向解決問題的辦法行不通了,那麼橫向增加伺服器的數量呢?這時候叢集的概念產生了,單個伺服器解決不了我們增加伺服器的數量,然後將請求分發到各個伺服器上,將原先請求集中到單個伺服器上的情況改為將請求分發到多個伺服器上,將負載分發到不同的伺服器,也就是我們所說的負載均衡

image-20210101223821389
1.4 動靜分離

為了加快網站的解析速度,可以把動態頁面和靜態頁面由不同的伺服器來解析加快解析速度。降低原來單個伺服器的壓力。

image-20210101223821389

2. 安裝

2.1 在Linux中安裝Nginx

GCC安裝(如果沒有的話)

安裝 nginx 需要先將官網下載的原始碼進行編譯,編譯依賴 gcc 環境,如果沒有 gcc 環境則需要安裝

yum install gcc-c++

pcre安裝

PCRE(Perl Compatible Regular Expressions) 是一個Perl庫,包括 perl 相容的正規表示式庫。nginx 的 http 模組使用 pcre 來解析正規表示式,所以需要在 linux 上安裝 pcre 庫,pcre-devel 是使用 pcre 開發的一個二次開發庫。nginx也需要此庫。

yum install -y pcre pcre-devel
# 檢視安裝版本
pcre-config --version

openssl安裝

OpenSSL 是一個強大的安全通訊端層密碼庫,囊括主要的密碼演演算法、常用的金鑰和證書封裝管理功能及 SSL 協定,並提供豐富的應用程式供測試或其它目的使用。nginx 不僅支援 http 協定,還支援 https(即在ssl協定上傳輸http),所以需要在 Centos 安裝 OpenSSL 庫。

yum install -y openssl openssl-devel

zlib安裝

zlib庫提供了很多種壓縮和解壓縮方式,nginx使用zlib對http包的內容進行gzip,所以需要安裝

yum install -y zlib zlib-devel

nginx安裝,啟動、停止

# 1.下載nginx安裝包
wget -c https://nginx.org/download/nginx-1.12.0.tar.gz
# 解壓壓縮包到指定目錄並切換到該目錄下
tar -zxvf nginx-1.12.0.tar.gz
cd nginx-1.12.0
# 執行三個命令
./configure #使用預設設定,其實在 nginx-1.12.0 版本中你就不需要去設定相關東西,預設就可以了。
make #編譯
make install #安裝
# 查詢安裝路徑並進入
whereis nginx
# 啟動、停止nginx
cd /usr/local/nginx/sbin/
./nginx -v		#檢視nginx版本號
./nginx 		#啟動
./nginx -s stop #此方式相當於先查出nginx程序id再使用kill命令強制殺掉程序
./nginx -s quit #此方式停止步驟是待nginx程序處理任務完畢進行停止
./nginx -s reload 

#啟動時報80埠被佔用解決辦法:安裝net-tool 包:
yum install net-tools
#查詢nginx程序
ps aux|grep nginx
#重啟 nginx
#  方式一:先停止再啟動(推薦)
./nginx -s quit
./nginx
#  方式二:重新載入組態檔,當 ngin x的組態檔 nginx.conf 修改後,要想讓設定生效需要重啟 nginx,使用下面的命令不用先停止 nginx 再啟動,nginx 即可將設定資訊在 nginx 中生效,如下:
./nginx -s reload
# 開機自啟動(在rc.local增加啟動程式碼即可)
vi /etc/rc.local  # 新增:/usr/local/nginx/sbin/nginx
chmod 755 rc.local # 設定執行許可權

防火牆相關

# 檢視開放的埠號
firewall-cmd --list-all
# 查詢埠號80 是否開啟:
firewall-cmd --query-port=80/tcp
# 永久開放80埠號:
firewall-cmd --permanent --zone=public --add-port=80/tcp
# 啟動|關閉|重新啟動  防火牆
systemctl [start|stop|restart] firewalld.service
2.2 使用docker-compose 安裝Nginx

下面以本人搭建的部落格系統為例,看不懂的先看後面章節

建立docker-compose.yml

version: '3.1'
services:
  nginx:
    restart: always
    image: nginx:1.19.2-alpine 
    container_name: polaris-nginx # nginx容器名
    ports:
      - 80:80       # http預設埠
      - 443:443     # https預設埠
    volumes:
      - "./conf/nginx.conf:/etc/nginx/nginx.conf"
      - "./wwwroot:/usr/share/nginx/wwwroot"
      - "./log:/var/log/nginx"

建立組態檔nginx.conf

user  nginx;
worker_processes  1; # 程序數,建議按照cpu 數目來指定,一般為它的倍數。

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;


events {
    worker_connections  1024; # 單個後臺worker process程序的最大並行連結數  
}


http {
	# upstream ↓
	# down 表示當前的server暫時不參與負載
	# weight 加權輪詢權重,預設為1。weight越大,負載的權重就越大。
	# backup 備用伺服器, 當其他所有的非backup機器出現故障或者忙的時候,才會請求backup機器,因此這臺機器的壓力最輕。
	# max_fails 允許請求失敗的次數預設為1。當超過最大次數時,返回proxy_next_upstream 模組定義的錯誤
	# fail_timeout max_fails次失敗後,暫停的時間。
	# 名字不能用下劃線,否則存取不到
	
	# 部落格後端,多個可以實現負載均衡(根據權重)
    upstream polaris-blog-system{
	   server 172.20.147.156:8080 weight=1;
    }
	
	# 門戶
	upstream polaris-blog-portal{
		server 172.20.147.156:3000 weight=1;      
	}

	#設定mime型別,型別由mime.type檔案定義
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

	# 設定紀錄檔格式
    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;


    #sendfile 指令指定 nginx 是否呼叫 sendfile 函數(zero copy 方式)來輸出檔案,
	# 對於普通應用,必須設為 on,
    # 如果用來進行下載等應用磁碟IO重負載應用,可設定為 off,
    # 以平衡磁碟與網路I/O處理速度,降低系統的uptime.
    sendfile on;
	
    # tcp_nopush     on;

	# 用於設定使用者端連線保持活動的超時時間,在超過這個時間之後伺服器會關閉該連結。
    keepalive_timeout  65;

    #開啟gzip壓縮
    gzip  on;
    gzip_disable "MSIE [1-6].";
	
	# 設定請求緩衝
    client_header_buffer_size    128k;
    large_client_header_buffers  4 128k;

	# 允許使用者端請求的最大單檔案位元組數
	client_max_body_size 50m;
   
	# 伺服器名字的hash表大小
	server_names_hash_bucket_size 128;
	
	# header中自定義變數時支援下劃線
	underscores_in_headers on; 
    
	
	server {
		listen       80;
		server_name  www.mpolaris.top;# 這個是門戶的存取域名,指向http://polaris-blog-portal
		
		#location ^~/shop/ {
		#	proxy_pass https://api.mpolaris.net/; # 商城,還未開發
		#}
		
		location ^~/portal/ {
			proxy_pass   http://polaris-blog-system;
			# 以下是一些反向代理的設定可刪除
			proxy_redirect             off;
			# 後端的Web伺服器可以通過X-Forwarded-For獲取使用者真實IP
			proxy_set_header           Host $host;
			proxy_set_header           Cookie $http_cookie;
			proxy_set_header           X-Real-IP $remote_addr;
			proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header           HTTP_X_FORWARDED_FOR $remote_addr;
			proxy_set_header           X-Forwarded-Server $host;
		}
		
		location ^~/user/ {
			proxy_pass   http://polaris-blog-system;
			# 以下是一些反向代理的設定可刪除
			proxy_redirect             off;
			# 後端的Web伺服器可以通過X-Forwarded-For獲取使用者真實IP
			proxy_set_header           Host $host;
			proxy_set_header           Cookie $http_cookie;
			proxy_set_header           X-Real-IP $remote_addr;
			proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header           HTTP_X_FORWARDED_FOR $remote_addr;
			proxy_set_header           X-Forwarded-Server $host;
		}

		location / {
			proxy_pass   http://polaris-blog-portal;
			# 以下是一些反向代理的設定可刪除
			proxy_redirect             off;
			# 後端的Web伺服器可以通過X-Forwarded-For獲取使用者真實IP
			proxy_set_header           Host $host;
			proxy_set_header           Cookie $http_cookie;
			proxy_set_header           X-Real-IP $remote_addr;
			proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header           HTTP_X_FORWARDED_FOR $remote_addr;
			proxy_set_header           X-Forwarded-Server $host;
		}
		
    }
	
	server {
		listen       80;
		server_name  mp.mpolaris.top; # 這個是管理中心的存取域名

		#charset koi8-r;
		#access_log  /var/log/nginx/host.access.log  main;
		
		
		# 使用者相關的請求,轉到polaris_blog
		location ^~/user/ {
            proxy_pass   http://polaris-blog-system;
			# 以下是一些反向代理的設定可刪除
			proxy_redirect             off; 
			# 後端的Web伺服器可以通過X-Forwarded-For獲取使用者真實IP
			proxy_set_header           Host $host;
			proxy_set_header 		   Cookie $http_cookie;
			proxy_set_header           X-Real-IP $remote_addr; 
			proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header           HTTP_X_FORWARDED_FOR $remote_addr;
			proxy_set_header           X-Forwarded-Server $host;
        }
        
		location ^~/admin/ {
           	proxy_pass   http://polaris-blog-system;
			# 以下是一些反向代理的設定可刪除
			proxy_redirect             off; 
			# 後端的Web伺服器可以通過X-Forwarded-For獲取使用者真實IP
			proxy_set_header           Host $host;
			proxy_set_header 		   Cookie $http_cookie;
			proxy_set_header           X-Real-IP $remote_addr; 
			proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header           HTTP_X_FORWARDED_FOR $remote_addr;
			proxy_set_header           X-Forwarded-Server $host;
        }
        
        location ^~/portal/ {
           	proxy_pass    http://polaris-blog-system;
			# 以下是一些反向代理的設定可刪除
			proxy_redirect             off; 
			# 後端的Web伺服器可以通過X-Forwarded-For獲取使用者真實IP
			proxy_set_header           Host $host;
			proxy_set_header 		   Cookie $http_cookie;
			proxy_set_header           X-Real-IP $remote_addr; 
			proxy_set_header           X-Forwarded-For $proxy_add_x_forwarded_for;
			proxy_set_header           HTTP_X_FORWARDED_FOR $remote_addr;
			proxy_set_header           X-Forwarded-Server $host;
        }

		# 其他存取存取wwwroot/mp
		location / {
			# 此處解決重新整理頁面出現404的問題
			try_files $uri $uri/ /index.html;
		    root   /usr/share/nginx/wwwroot/mp;
			index  index.html index.htm;
		}
	}
}

3. 組態檔

3.1 nginx.conf

nginx 安裝目錄下其預設的組態檔都放在這個目錄的 conf 目錄下,而主組態檔nginx.conf 也在其中,對 nginx 的使用基本上都是對此組態檔進行相應的修改。

image-20210101223821389

根據nginx.conf組態檔,可將其分為三部分

3.2 第一部分:全域性塊

從組態檔開始到 events 塊之間的內容,主要會設定一些影響 nginx 伺服器整體執行的設定指令,主要包括設定執行 Nginx 伺服器的使用者(組),允許生成的 worker process 數,程序 PID 存放路徑、紀錄檔存放路徑和型別以及組態檔的引入等。

如下設定,這是 Nginx 伺服器並行處理服務的關鍵設定,worker_processes 值越大,可以支援的並行處理量也越多,但是會受到硬體、軟體等裝置的制約。

worker_processes 1;
3.3 第二部分:events塊

events 塊涉及的指令主要影響 Nginx 伺服器與使用者的網路連線,常用的設定包括是否開啟對多 work process 下的網路連線進行序列化,是否允許同時接收多個網路連線,選取哪種事件驅動模型來處理連線請求,每個 word process 可以同時支援的最大連線數等。

這部分的設定對 Nginx 的效能影響較大,在實際中應該靈活設定。

如下例子就表示每個 work process 支援的最大連線數為 1024。

events {
	worker_connections 1024;
}
3.4 第三部分:http塊

http塊算是 Nginx 伺服器設定中最頻繁的部分,代理、快取和紀錄檔定義等絕大多數功能和第三方模組的設定都在這裡。 需要注意的是:http 塊也可以包括 http 全域性塊server 塊

http {
    include       mime.types;
    default_type  application/octet-stream;
    
    sendfile on;
    
    keepalive_timeout  65;   
	
	server {
		listen       80;
		server_name  localhost

		location / {
			root   html;
			index  index.html index.htm;
		}
		
		error_page 500 502 503 504 /50x.html;
		
		location = /50x.html {
			root   html;
		}
		
	}
}

http全域性塊

http 全域性塊設定的指令包括檔案引入、MIME-TYPE 定義、紀錄檔自定義、連線超時時間、單連結請求數上限等。

server塊

這塊和虛擬主機有密切關係,虛擬主機從使用者角度看,和一臺獨立的硬體主機是完全一樣的,該技術的產生是為了節省網際網路伺服器硬體成本。

每個 http 塊可以包括多個 server 塊,而每個 server 塊就相當於一個虛擬主機。而每個 server 塊也分為全域性 server 塊,以及可以同時包含多個 locaton 塊。

  • 全域性 server 塊:常見的設定是本虛擬機器器主機的監聽設定和本虛擬主機的名稱或 IP 設定。
  • location 塊:一個 server 塊可以設定多個 location 塊。這塊的主要作用是基於 Nginx 伺服器接收到的請求字串(例如 server_name/uri-string),對虛擬主機名稱(也可以是 IP 別名)之外的字串(例如 前面的 /uri-string)進行匹配,對特定的請求進行處理。地址定向、資料快取和應答控制等功能,還有許多第三方模組的設定也在這裡進行。
//location指令說明:location指令用於匹配URL,語法如下
location [ = | ~ | ~* | ^~] uri {
    
}
// ① = :用於不含正規表示式的 uri 前,要求請求字串與 uri 嚴格匹配,如果匹配成功,就停止繼續向下搜尋並立即處理該請求。
// ② ~ :用於表示 uri 包含正規表示式,並且區分大小寫。
// ③ ~* :用於表示 uri 包含正規表示式,並且不區分大小寫。
// ④ ^~ :用於不含正規表示式的 uri 前,要求 Nginx 伺服器找到標識 uri 和請求字串匹配度最高的 location 後,立即使用此 location 處理請求,而不再使用 location 塊中的正則 uri 和請求字串做匹配。

//注意:如果 uri 包含正規表示式,則必須要有 ~ 或者 ~* 標識。

4. 設定範例 - 反向代理

4.1 範例一

實現效果

在瀏覽器位址列輸入地址www.123.com,就會跳轉到Linux系統tomcat主頁面中

image-20210103010039415

準備內容

在Linux系統中安裝tomcat並啟動

# 下載
wget https://mirrors.tuna.tsinghua.edu.cn/apache/tomcat/tomcat-8/v8.5.61/bin/apache-tomcat-8.5.61.tar.gz
# 解壓
tar -zxvf apache-tomcat-8.5.61.tar.gz
# 進入bin目錄並啟動tomcat
cd apache-tomcat-8.5.61/bin
./startup.sh
# 檢視tomcat紀錄檔, -f 迴圈讀取(常用於查閱正在改變的紀錄檔檔案)
tail -f catalina.out

nginx.conf設定

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;
	
    keepalive_timeout  65;

    server {
        listen       80;
        # 存取192.168.204.130就會轉發到proxy設定的地址去
        server_name  192.168.204.130; 

        location / {
			proxy_pass http://127.0.0.1:8080;  #反向代理
			
            root   html;
            index  index.html index.htm;
        }

       
        error_page   500 502 503 504  /50x.html;
        location = /50x.html {
            root   html;
        }
    }
}
4.2 範例二

實現效果

使用nginx反向代理,根據存取的路徑跳轉到不同埠的服務中。

  • nginx監聽埠為9001
  • 存取http://192.168.204.130:9001/edu/,直接跳轉到127.0.0.1:8081
  • 存取http://192.168.204.130:9001/vod/,直接跳轉到127.0.0.1:8082

準備內容

  • 準備兩個tomcat,一個8081埠,一個8082埠,並在兩個tomcat中分別準備好測試的頁面
  • 修改nginx的組態檔,在http塊中編寫server{}邏輯

nginx.conf設定

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;

    server {
        listen       9001;
        server_name  192.168.204.130; # 存取該地址就會轉發到proxy設定的地址去

        location ~ /edu/ {
            proxy_pass http://127.0.0.1:8080;  #反向代理
        }

		location ~ /vod/ {
            proxy_pass http://127.0.0.1:8081;  #反向代理
        }
    }
}

5. 設定範例 - 負載均衡

5.1 範例

實現效果

瀏覽器位址列輸入地址http://192.168.204.130/Test/test.html,實現負載均衡效果,即將平均到8080和8081埠中

準備工作

  • 兩臺tomcat伺服器,一個為8080埠另一個為8081埠
  • 在兩臺tomcat的webapps目錄中,建立Test資料夾並在其中建立test.html頁面用於測試

nginx.conf設定

worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile        on;

    keepalive_timeout  65;
    
    upstream myserver {
        server 192.168.204.130:8080 weight=2;
        server 192.168.204.130:8081 weight=1;
    }

    server {
        listen       80;
        server_name  192.168.204.130;

        location / {
            proxy_pass http://myserver; # 負載均衡
            
            root html;
            index index.html index.htm;
        }
    }
}
5.2 nginx分配伺服器策略

第一種:輪詢(預設)

每個請求按時間順序逐一分配到不同的後端伺服器,如果後端伺服器down掉能自動剔除

第二種:weight

weight 代表權重預設為 1,權重越高被分配的使用者端越多

第三種:ip_hash

每個請求按存取ip的hash結果分配,這樣每個訪客固定存取一個後端伺服器。可以解決session共用的問題

upstream myServer {
	ip_hash;
	server server 192.168.204.130:8080;
	server server 192.168.204.130:8081;
}

第四種:fair(第三方)

按後端伺服器的響應時間來分配請求,響應時間短的優先分配

upstream myServer {
	server server 192.168.204.130:8080;
	server server 192.168.204.130:8081;
	fair;
}

6. 設定範例 - 動靜分離

6.1 理解

Nginx 動靜分離簡單來說就是把動態跟靜態請求分開,不能理解成只是單純的把動態頁面和靜態頁面物理分離。嚴格意義上說應該是動態請求跟靜態請求分開,可以理解成使用 Nginx 處理靜態頁面,Tomcat 處理動態頁面。

動靜分離從目前實現角度來講大致分為兩種,一種是純粹把靜態檔案獨立成單獨的域名放在獨立的伺服器上,也是目前主流推崇的方案;另外一種方法就是動態跟靜態檔案混合在一起釋出,通過 nginx 來分開。通過 location 指定不同的字尾名實現不同的請求轉發。

通過 expires 引數可以設定瀏覽器快取過期時間,減少與伺服器之前的請求和流量。具體 Expires 定義:是給一個資源設定一個過期時間,也就是說無需去伺服器端驗證,直接通過瀏覽器自身確認是否過期即可,不會產生額外的流量。此種方法非常適合不經常變動的資源。(如果經常更新的檔案,不建議使用 Expires 來快取),我這裡設定 3d,表示在這 3 天之記憶體取這個 URL,傳送一個請求,比對伺服器該檔案最後更新時間沒有變化,則不會從伺服器抓取返回狀態碼304,如果有修改則直接從伺服器重新下載,返回狀態碼 200。

6.2 範例

專案資源準備

nginx 設定

重點是新增 location,最後檢查 Nginx 設定是否正確即可,然後測試動靜分離是否成功,之需要刪除後端 tomcat 伺服器上的某個靜態檔案,檢視是否能存取,如果可以存取說明靜態資源 nginx 直接返回了,不走後端 tomcat 伺服器。

server {
    listen       80;
    server_name  192.168.204.130;

    location /image/ {
        root html/image/;
        autoindex on; #列出當前資料夾中的內容
        index index.html index.htm;
    }
}

7. 搭建Nginx高可用叢集

7.1 主從模式

圖示

image-20210113221825855

搭建環境

  1. 兩臺伺服器192.168.0.1與192.168.0.2
  2. 在兩臺伺服器上安裝Nginx,keepalived
  3. keepalived安裝成功後在/etc下生成一個檔案keepalived/keepalived.conf,對其進行設定
# 全域性定義
global_defs { 
   notification_email { 
       [email protected] 
       [email protected] 
       [email protected] 
   } 
   notification_email_from [email protected] 
   smtp_server 192.168.17.129 
   smtp_connect_timeout 30 
   # 主要設定該值,通過這個伺服器名字可以直接存取到ip
   router_id LVS_DEVEL   # /etc/host檔案中設定:127.0.0.1 LVS_DEVEL
} 

# 檢測指令碼 與 權重引數
vrrp_script chk_http_port { 
   script "/usr/local/src/nginx_check.sh"  # 指令碼路徑
   interval 2   #(檢測指令碼執行的間隔,單位s) 
   weight 2    # 設定當前伺服器的權重。例當指令碼成立時當前伺服器權重+2
} 
 
# 虛擬IP設定
vrrp_instance VI_1 { 
   state MASTER    # 備份伺服器上將 MASTER 改為 BACKUP 
   interface ens33   # 繫結的網路卡名 
   virtual_router_id 51   # 路由值,主、備機必須一樣,是一個的唯一標識
   priority 100   # 主、備機取不同的優先順序,主機值較大,備份機值較小 
   advert_int 1   # 每個多少時間(單位s)檢測一次當前伺服器
   authentication { # 許可權方式,如下密碼的形式,密碼為1111
     auth_type PASS 
     auth_pass 1111 
   } 
   virtual_ipaddress { 
     192.168.17.50   # 虛擬IP地址 ,可以繫結多個
   } 
}
  1. 編寫檢測指令碼檔案 nginx_check.sh
#!/bin/bash 
A=`ps -C nginx –no-header |wc -l` 
if [ $A -eq 0 ];then 
 /usr/local/nginx/sbin/nginx  # nginx啟動路徑
 sleep 2 
 if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then 
 killall keepalived 
 fi 
fi
  1. 將兩臺伺服器上的nginx和keepalived都啟動起來
./nginx
systemctl start keepalived.service
  1. 存取虛擬ip,檢視是否能存取到nginx主頁
  2. 停掉主Nginx伺服器後,存取虛擬ip,檢視是否能存取到nginx主頁
7.2 雙主模式

圖示

image-20210113234042092

搭建環境

其他步驟與主從模式類似,只是keepalived.conf組態檔有所變化

#全域性定義
global_defs { 
   notification_email { 
       [email protected] 
       [email protected] 
       [email protected] 
   } 
   notification_email_from [email protected] 
   smtp_server 192.168.17.129 
   smtp_connect_timeout 30 
   router_id LVS_DEVEL 
} 

# 檢測指令碼 與 權重引數
vrrp_script chk_http_port { 
   script "/usr/local/src/nginx_check.sh"  
   interval 2   
   weight 2  
} 
 
# 虛擬IP設定
vrrp_instance VI_1 { 
   state MASTER   
   interface ens33  
   virtual_router_id 51  
   priority 100   
   advert_int 1   
   authentication { 
     auth_type PASS 
     auth_pass 1111 
   } 
   virtual_ipaddress { 
     192.168.17.50 
   } 
}

# 虛擬IP設定
vrrp_instance VI_2 { 
   state BACKUP   
   interface ens33  
   virtual_router_id 52  
   priority 50   
   advert_int 1   
   authentication { 
     auth_type PASS 
     auth_pass 2222
   } 
   virtual_ipaddress { 
     192.168.17.80 
   } 
}

8. Nginx原理與優化引數設定

8.1 master & worker

master & worker機制

image-20210113235646531

master-workers 的機制的好處

首先對於每個 worker 程序來說獨立的程序不需要加鎖,省掉了鎖帶來的開銷,同時在程式設計以及問題查詢時也會方便很多。

其次採用獨立的程序可以讓互相之間不會影響,一個程序退出後其它程序還在工作,服務不會中斷,master 程序則很快啟動新的worker 程序,同時還支援 熱部署(nginx -s reload)。當然worker 程序的異常退出肯定是程式有 bug 了,異常退出會導致當前 worker 上的所有請求失敗,不過不會影響到所有請求降低了風險。

worker如何工作

image-20210114000115568

需要設定多少個worker

Nginx 同 Redis 類似都採用了 IO 多路複用機制(注意windows系統沒有該功能),每個 worker 都是一個獨立的程序,但每個程序裡只有一個主執行緒,通過非同步非阻塞的方式來處理請求, 即使是千上萬個請求也不在話下。每個 worker 的執行緒可以把一個 cpu 的效能發揮到極致。所以 worker 數和伺服器的 cpu數相等 是最為適宜的。設少了會浪費 cpu,設多了會造成 cpu 頻繁切換上下文帶來的損耗。

設定worker數量

worker_processes 4
#work 繫結 cpu(4 work 繫結 4cpu)。
worker_cpu_affinity 0001 0010 0100 1000
#work 繫結 cpu (4 work 繫結 8cpu 中的 4 個) 。
worker_cpu_affinity 0000001 00000010 00000100 00001000

連線數 worker_connection

這個值是表示每個 worker 程序所能建立連線的最大值,所以一個 nginx 能建立的最大連線數,應該是 worker_connections * worker_processes。當然這裡說的是最大連線數,對於HTTP 請 求 本 地 資 源 來 說 能 夠 支 持 的 最 大 並 發 數 量 worker_connections * worker_processes,如果是支援 http1.1 的瀏覽器每次存取要佔兩個連線,所以普通的靜態存取最大並行數是: worker_connections * 、worker_processes /2,而如果是 HTTP 作為反向代理來說,最大並行數量應該是 worker_connections * worker_processes/4。因為作為反向代理伺服器,每個並行建立與使用者端的連線和與後端服務的連線會佔用兩個連線。

image-20210114001632413