nginx效能優化

2021-09-07 07:49:43 字數 3643 閱讀 6564

1、執行緒池

預設情況下,nginx的work process按照順序乙個個處理http請求,因此如果後台處理時間較長,則work process會長時間等待io狀態,因此限制併發性。如下所示:

所以,對於可能存在的這類http請求,一般會啟用執行緒池。預設情況下,執行緒池特性並不啟用,需要在編譯時增加編譯選項--with-threads包含該特性,然後在nginx.conf配置檔案中定義執行緒池:

thread_pool mypool threads=64;

…location /downloads/ {

aio threads=mypool;

directio 8k;

sendfile on;

這樣的話,當客戶端請求的檔案超過8k時,就會適用aio,否則使用sendfile。

2、tcp_nodelay

nginx的 tcp_nodelay 選項使得在開啟乙個新的 socket 時增加了tcp_nodelay選項。但這時會造成一種情況:

終端應用程式每產生一次操作就會傳送乙個包,而典型情況下乙個包會擁有乙個位元組的資料以及40個位元組長的包頭,於是產生4000%的過載,很輕易地就能令網路發生擁塞。為了避免這種情況,tcp堆疊實現了等待資料 0.2秒鐘,因此操作後它不會傳送乙個資料報,而是將這段時間內的資料打成乙個大的包。這一機制是由nagle演算法保證。

nagle化後來成了一種標準並且立即在網際網路上得以實現。它現在已經成為預設配置了,但有些場合下把這一選項關掉也是合乎需要的。現在假設某個應用程式發出了乙個請求,希望傳送小塊資料。我們可以選擇立即傳送資料或者等待產生更多的資料然後再一次傳送兩種策略。

如果我們馬上傳送資料,那麼互動性的以及客戶/伺服器型的應用程式將極大地受益。如果請求立即發出那麼響應時間也會快一些。以上操作可以通過設定套接字的 tcp_nodelay = on 選項來完成,這樣就禁用了nagle 演算法。(不需要等待0.2s)

3、tcp_nopush和sendfile

tcp_nopush 配置和 tcp_nodelay 「互斥」。它可以配置一次傳送資料的包大小。也就是說,它不是按時間累計 0.2 秒後傳送包,而是當包累計到一定大小後就傳送。

注:在 nginx 中,tcp_nopush 必須和 sendfile 搭配使用。

sendfile是 linux2.0+以後的推出的乙個系統呼叫,web伺服器可以通過調整自身的配置來決定是否利用 sendfile這個系統呼叫。先來看一下不用 sendfile的傳統網路傳輸過程:

read(file,tmp_buf, len);

write(socket,tmp_buf, len);

硬碟 >> kernel buffer >> user buffer>> kernel socket buffer >>協議棧

1)一般來說乙個網路應用是通過讀硬碟資料,然後寫資料到socket 來完成網路傳輸的。上面2行用**解釋了這一點,不過上面2行簡單的**掩蓋了底層的很多操作。來看看底層是怎麼執行上面2行**的:

系統呼叫 read()產生乙個上下文切換:從 user mode 切換到 kernel mode,然後 dma 執行拷貝,把檔案資料從硬碟讀到乙個 kernel buffer 裡。

資料從 kernel buffer拷貝到 user buffer,然後系統呼叫 read() 返回,這時又產生乙個上下文切換:從kernel mode 切換到 user mode。

系統呼叫write()產生乙個上下文切換:從 user mode切換到 kernel mode,然後把步驟2讀到 user buffer的資料拷貝到 kernel buffer(資料第2次拷貝到 kernel buffer),不過這次是個不同的 kernel buffer,這個 buffer和 socket相關聯。

系統呼叫 write()返回,產生乙個上下文切換:從 kernel mode 切換到 user mode(第4次切換了),然後 dma 從 kernel buffer拷貝資料到協議棧(第4次拷貝了)。

上面4個步驟有4次上下文切換,有4次拷貝,我們發現如果能減少切換次數和拷貝次數將會有效提公升效能。在kernel2.0+ 版本中,系統呼叫 sendfile() 就是用來簡化上面步驟提公升效能的。sendfile() 不但能減少切換次數而且還能減少拷貝次數。

2)再來看一下用 sendfile()來進行網路傳輸的過程:

sendfile(socket,file, len);

硬碟 >> kernel buffer (快速拷貝到kernelsocket buffer) >>協議棧

系統呼叫sendfile()通過 dma把硬碟資料拷貝到 kernel buffer,然後資料被 kernel直接拷貝到另外乙個與 socket相關的 kernel buffer。這裡沒有 user mode和 kernel mode之間的切換,在 kernel中直接完成了從乙個 buffer到另乙個 buffer的拷貝。

dma 把資料從 kernelbuffer 直接拷貝給協議棧,沒有切換,也不需要資料從 user mode 拷貝到 kernel mode,因為資料就在 kernel 裡。

步驟減少了,切換減少了,拷貝減少了,自然效能就提公升了。這就是為什麼說在nginx 配置檔案裡開啟 sendfile on 選項能提高 web server效能的原因。

綜上,這三個引數都應該配置成on:sendfile on; tcp_nopush on; tcp_nodelay on;

4、ssl加密

對於ssl來說,最消耗資源的部分是ssl握手,所以應使用下列方式最大化效能:

1、使用keepalive一次處理多個請求;

2、重用ssl會話引數;

ssl_session_cache   shared:ssl:10m;   # 1m大概可以支援4000個會話

ssl_session_timeout 10m;

同時,

nginx預設使用dhe演算法來產生密匙,該加密演算法效率很低。可以通過如下命令,刪掉了kedh演算法。

ssl_ciphers all:!kedh!adh:rc4+rsa:+high:+exp;

ssl_prefer_server_ciphers on;

5、長連線

當使用nginx作為反向**時,為了支援長連線,需要做到兩點:

客戶端:

keepalive_timeout:客戶端長連線超時時間

keepalive_requests:一次keep-alive連線上可以服務的請求的最大數量

服務端:

即使是client和nginx之間是短連線,nginx和upstream之間也是可以開啟長連線的。

keepalive 200-1000之間

proxy_http_version 1.1; // 這兩個最好也設定

proxy_set_header connection "";

6、基於cookie的負載均衡

nginx預設不支援基於cookie的連線親和性,可以適用第三方模組實現基於該特性,對於很多不是直接面向wan的nginx來說,基於ip的機制將使得其效果極差。

參考:

Nginx效能優化

在http裡面新增一行 server tokens off 預設可以設定為cpu的核數相等,併發比較大的時候,可以設定為cpu核數 2 worker cpu affinity 0001 0010 0100 1000 四核worker cpu affinity 00000001 00000010 00...

Nginx效能優化

簡介 在大多數情況下,乙個常規安裝的nginx對 來說已經能很好地工作了。然而如果想擠壓出nginx的效能,就需要了解哪些指令會影響nginx效能,在本文中將解釋nginx的哪些設定可以微調。需要注意一點,這是乙個簡單的預覽 那些可以通過微調來提高效能設定的概述,不同的環境可能情況不太一樣。對於ng...

Nginx 效能優化

如何有效使用cpu worker processes number auto為什麼乙個cpu就可以同時執行多個程序?cup巨集觀上並行,微觀上序列 阻塞api引發的時間片內主動讓出cup 業務場景產生的阻塞api 對於cpu的優化的點 盡可能的減少程序間的切換 減少主動切換 減少被動切換 鎖定cpu...