Nginx詳解

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 //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;# 這個是門戶的訪問域名,指向//polaris-blog-portal
		
		#location ^~/shop/ {
		#	proxy_pass //api.mpolaris.net/; # 商城,還未開發
		#}
		
		location ^~/portal/ {
			proxy_pass   //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   //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   //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   //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   //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    //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 //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 //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
  • 訪問//192.168.204.130:9001/edu/,直接跳轉到127.0.0.1:8081
  • 訪問//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 //127.0.0.1:8080;  #反向代理
        }

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

5. 配置實例 – 負載均衡

5.1 實例

實現效果

瀏覽器地址欄輸入地址//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 //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