1. 程式人生 > >Nginx 效能優化實踐

Nginx 效能優化實踐

概要:

  1. Nginx 反向代理與負載均衡
  2. Nginx 實現快取記憶體
  3. Nginx 效能引數調優

一、Nginx 反向代理實現

知識點:

  1. 反向代理基本配置
  2. 負載均衡配置與引數解析
  3. 負載均衡演算法詳解
  1. 反向代理基本配置

提問:什麼是反向代理其與正向代理有什麼區別?

正向代理的概念:

正向代理是指客戶端與目標伺服器之間增加一個代理伺服器,客戶端直接訪問代理伺服器,在由代理伺服器訪問目標伺服器並返回客戶端並返回 。這個過程當中客戶端需要知道代理伺服器地址,並配置連線。

反向代理的概念:

反向代理是指 客戶端訪問目標伺服器,在目標服務內部有一個統一接入閘道器將請求轉發至後端真正處理的伺服器並返回結果。這個過程當中客戶端不需要知道代理伺服器地址,代理對客戶端而言是透明的。

反向代理與正向代理的區別

正向代理

反向代理

代理伺服器位置

客戶端與服務都能連線的們位置

目標伺服器內部

主要作用

遮蔽客戶端IP、集中式快取、解決客戶端不能直連服務端的問題。

遮蔽服務端內部實現、負載均衡、快取。

應用場景

爬蟲、翻牆、maven 的nexus 服務

Nginx 、Apache負載均衡應用

Nginx代理基本配置

Nginx 代理只需要配置 location 中配置proxy_pass 屬性即可。其指向代理的伺服器地址。

# 正向代理到baidu 服務

location = /baidu.html {

         proxy_pass http://www.baidu.com;

}

# 反向代理至 本機的8010服務

location /luban/ {

     proxy_pass http://127.0.0.1:8010;  

}

代理相關引數:

proxy_pass           # 代理服務

proxy_redirect off;   # 是否允許重定向

proxy_set_header Host $host; # 傳 header 引數至後端服務

proxy_set_header X-Forwarded-For $remote_addr; # 設定request header 即客戶端IP 地址

proxy_connect_timeout 90; # 連線代理服務超時時間

proxy_send_timeout 90; # 請求傳送最大時間

proxy_read_timeout 90;  # 讀取最大時間

proxy_buffer_size 4k; 

proxy_buffers 4 32k;

proxy_busy_buffers_size 64k; 

proxy_temp_file_write_size 64k;

2.負載均衡配置與引數解析

通過proxy_pass 可以把請求代理至後端服務,但是為了實現更高的負載及效能, 我們的後端服務通常是多個, 這個是時候可以通過upstream 模組實現負載均衡。

演示upstream 的實現。

upstream backend {     

   server 127.0.0.1:8010 weight=1;

   server 127.0.0.1:8080 weight=2;

}

location / {

          proxy_pass http://backend;

}

upstream 相關引數:

  1. service反向服務地址 加埠
  2. weight權重
  3. max_fails失敗多少次 認為主機已掛掉則,踢出
  4. fail_timeout踢出後重新探測時間
  5. backup備用服務
  6. max_conns允許最大連線數
  7. slow_start當節點恢復,不立即加入,而是等待 slow_start 後加入服務對列。

3.upstream 負載均衡演算法介紹

  1. ll+weight: 輪詢加權重 (預設)
  2. ip_hash : 基於Hash 計算 ,用於保持session 一至性
  3. url_hash: 靜態資源快取,節約儲存,加快速度(第三方)
  4. least_conn :最少連結(第三方)
  5. least_time  :最小的響應時間,計算節點平均響應時間,然後取響應最快的那個,分配更高權重(第三方)

二、Nginx 快取記憶體

知識點:

  1. 快取案例分析
  2. Nginx 靜態快取基本配置
  3. 快取更新

1、案例分析:

某電商平臺商品詳情頁需要實現 700+ QPS,如何著手去做?

  1. 首先為分析一下一個商品詳情頁有哪些資訊

從中得出 商品詳情頁依懶了

對於商品詳情頁涉及瞭如下主要服務: 

  1. 商品詳情頁HTML頁面渲染
  2. 價格服務
  3.  促銷服務
  4.  庫存狀態/配送至服務
  5.  廣告詞服務
  6.  預售/秒殺服務
  7.  評價服務
  8.  試用服務
  9.  推薦服務
  10.  商品介紹服務
  11.  各品類相關的一些特殊服務

解決方案:

  1. 採用Ajax 動態載入 價格、廣告、庫存等服務
  2. 採用key value 快取詳情頁主體html。

方案架構:

問題:

當達到500QPS 的時候很難繼續壓測上去。

分析原因:一個詳情頁html  主體達平均150 kb  那麼在500QPS 已接近千M區域網寬頻極限。必須減少內網通訊。

基於Nginx 靜態快取的解決方案:

2.Nginx 靜態快取基本配置

一、在http元素下新增快取區宣告。

#proxy_cache_path 快取路徑

#levels 快取層級及目錄位數

#keys_zone 快取區記憶體大小

#inactive 有效期

#max_size 硬碟大小

proxy_cache_path /data/nginx/cache_luban levels=1:2 keys_zone=cache_luban:500m inactive=20d max_size=1g;

二、為指定location 設定快取策略。 

# 指定快取區

proxy_cache cache_luban;

#以全路徑md5值做做為Key 

proxy_cache_key $host$uri$is_args$args;

#對不同的HTTP狀態碼設定不同的快取時間

proxy_cache_valid 200 304 12h;

演示快取生效過程

  1. 配置宣告快取路徑
  1. 為location 配置快取策略
  1. 重啟nginx(修改了)
  1. 檢視快取目錄生成

快取引數詳細說明

父元素

名稱

描述

http

proxy_cache_path

指定快取區的根路徑

levels

快取目錄層級最高三層,每層1~2個字元表示。如1:1:2 表示三層。

keys_zone

快取塊名稱 及記憶體塊大小。如 cache_item:500m 。表示宣告一個名為cache_item 大小為500m。超出大小後最早的資料將會被清除。

inactive

最長閒置時間 如:10d 如果一個數據被閒置10天將會被清除

max_size

快取區硬碟最大值。超出閒置資料將會被清除

location

proxy_cache

指定快取區,對應keys_zone 中設定的值

proxy_cache_key

通過引數拼裝快取key 如:$host$uri$is_args$args 則會以全路徑md5值做做為Key

proxy_cache_valid

為不同的狀態碼設定快取有效期

3.快取的清除:

該功能可以採用第三方模組 ngx_cache_purge 實現。

為nginx 新增 ngx_cache_purge  模組

#下載ngx_cache_purge 模組包 ,這裡nginx 版本為1.6.2 purge 對應2.0版

wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz

#檢視已安裝模組

./sbin/nginx -V

#進入nginx安裝包目錄 重新安裝 --add-module為模組解壓的全路徑

./configure --prefix=/root/svr/nginx --with-http_stub_status_module --with-http_ssl_module --add-module=/root/svr/nginx/models/ngx_cache_purge-2.0

#重新編譯

make

#拷貝 安裝目錄/objs/nginx 檔案用於替換原nginx 檔案

#檢測檢視安裝是否成功

nginx -t 

清除配置:

location ~ /clear(/.*) {

  #允許訪問的IP

   allow           127.0.0.1;

   allow           192.168.0.193;

   #禁止訪問的IP

   deny            all;

   #配置清除指定快取區和路徑(與proxy_cache_key一至)

   proxy_cache_purge    cache_item $host$1$is_args$args;

}                       

配置好以後 直接訪問 :

# 訪問生成快取檔案

http://www.luban.com/?a=1

# 清除生成的快取,如果指定快取不存在 則會報404 錯誤。

http://www.luban.com/clear/?a=1

三、Nginx 效能引數調優

worker_processes number;

每個worker程序都是單執行緒的程序,它們會呼叫各個模組以實現多種多樣的功能。如果這些模組確認不會出現阻塞式的呼叫,那麼,有多少CPU核心就應該配置多少個程序;反之,如果有可能出現阻塞式呼叫,那麼需要配置稍多一些的worker程序。例如,如果業務方面會致使使用者請求大量讀取本地磁碟上的靜態資原始檔,而且伺服器上的記憶體較小,以至於大部分的請求訪問靜態資原始檔時都必須讀取磁碟(磁頭的定址是緩慢的),而不是記憶體中的磁碟快取,那麼磁碟I/O呼叫可能會阻塞住worker程序少量時間,進而導致服務整體效能下降。

每個worker 程序的最大連線數

語法:worker_connections number;

預設:worker_connections 1024

worker_cpu_affinity cpumask[cpumask……]

繫結Nginx worker程序到指定的CPU核心

為什麼要繫結worker程序到指定的CPU核心呢?假定每一個worker程序都是非常繁忙的,如果多個worker程序都在搶同一個CPU,那麼這就會出現同步問題。反之,如果每一個worker程序都獨享一個CPU,就在核心的排程策略上實現了完全的併發。

例如,如果有4顆CPU核心,就可以進行如下配置:

worker_processes 4;

worker_cpu_affinity 1000 0100 0010 0001;

注意 worker_cpu_affinity配置僅對Linux作業系統有效。

Nginx worker 程序優先順序設定

語法:worker_priority nice;

預設:worker_priority 0;

優先順序由靜態優先順序和核心根據程序執行情況所做的動態調整(目前只有±5的調整)共同決定。nice值是程序的靜態優先順序,它的取值範圍是–20~+19,–20是最高優先順序,+19是最低優先順序。因此,如果使用者希望Nginx佔有更多的系統資源,那麼可以把nice值配置得更小一些,但不建議比核心程序的nice值(通常為–5)還要小

Nginx worker程序可以開啟的最大控制代碼描述符個數

語法: worker_rlimit_nofile limit;

預設:

更改worker程序的最大開啟檔案數限制。如果沒設定的話,這個值為作業系統的限制。設定後你的作業系統和Nginx可以處理比“ulimit -a”更多的檔案,所以把這個值設高,這樣nginx就不會有“too many open files”問題了。

是否開啟accept鎖

語法:accept_mutex[on|off]

預設:accept_mutext on;

accept_mutex是Nginx的負載均衡鎖,當某一個worker程序建立的連線數量達到worker_connections配置的最大連線數的7/8時,會大大地減小該worker程序試圖建立新TCP連線的機會,accept鎖預設是開啟的,如果關閉它,那麼建立TCP連線的耗時會更短,但worker程序之間的負載會非常不均衡,因此不建議關閉它。

使用accept鎖後到真正建立連線之間的延遲時間

語法:accept_mutex_delay Nms; 

預設:accept_mutex_delay 500ms; 

在使用accept鎖後,同一時間只有一個worker程序能夠取到accept鎖。這個accept鎖不是堵塞鎖,如果取不到會立刻返回。如果只有一個worker程序試圖取鎖而沒有取到,他至少要等待accept_mutex_delay定義的時間才能再次試圖取鎖。