Nginx性能調優

Nginx配置參數優化

Nginx做爲高性能web服務器,即便不特地調整配置參數也能夠處理大量的併發請求。
如下的配置參數是借鑑網上的一些調優參數,僅做爲參考,不見得適於你的線上業務。

worker進程javascript

  • worker_processescss

    該參數表示啓動幾個工做進程,建議和本機CPU核數保持一致,每一核CPU處理一個進程。
  • worker_rlimit_nofilejava

    它表示Nginx最大可用的文件描述符個數,須要配合系統的最大描述符,建議設置爲102400。
    還須要在系統裏執行ulimit -n 102400才能夠。
    也能夠直接修改配置文件/etc/security/limits.conf修改
    增長:
    #* soft nofile 655350 (去掉前面的#)
    #* hard nofile 655350 (去掉前面的#)
  • worker_connectionsnode

    該參數用來配置每一個Nginx worker進程最大處理的鏈接數,這個參數也決定了該Nginx服務器最多能處理多少客戶端請求
    (worker_processes * worker_connections),建議把該參數設置爲10240,不建議太大。

http和tcp鏈接nginx

  • use epollweb

    使用epoll模式的事件驅動模型,該模型爲Linux系統下最優方式。
  • multi_accept on算法

    使每一個worker進程能夠同時處理多個客戶端請求。
  • sendfile on瀏覽器

    使用內核的FD文件傳輸功能,能夠減小user mode和kernel mode的切換,從而提高服務器性能。
  • tcp_nopush on緩存

    當tcp_nopush設置爲on時,會調用tcp_cork方法進行數據傳輸。
    使用該方法會產生這樣的效果:當應用程序產生數據時,內核不會立馬封裝包,而是當數據量積累到必定量時纔會封裝,而後傳輸。
  • tcp_nodelay on服務器

    不緩存data-sends(關閉 Nagle 算法),這個可以提升高頻發送小數據報文的實時性。
    (關於Nagle算法)
    【假如須要頻繁的發送一些小包數據,好比說1個字節,以IPv4爲例的話,則每一個包都要附帶40字節的頭,
    也就是說,總計41個字節的數據裏,其中只有1個字節是咱們須要的數據。
    爲了解決這個問題,出現了Nagle算法。
    它規定:若是包的大小知足MSS,那麼能夠當即發送,不然數據會被放到緩衝區,等到已經發送的包被確認了以後才能繼續發送。
    經過這樣的規定,能夠下降網絡裏小包的數量,從而提高網絡性能。】
  • keepalive_timeout

    定義長鏈接的超時時間,建議30s,過短或者太長都不必定合適,固然,最好是根據業務自身的狀況來動態地調整該參數。
  • keepalive_requests

    定義當客戶端和服務端處於長鏈接的狀況下,每一個客戶端最多能夠請求多少次,能夠設置很大,好比50000.
  • reset_timeout_connection on

    設置爲on的話,當客戶端再也不向服務端發送請求時,容許服務端關閉該鏈接。
  • client_body_timeout

    客戶端若是在該指定時間內沒有加載完body數據,則斷開鏈接,單位是秒,默認60,能夠設置爲10。
  • send_timeout

    這個超時時間是發送響應的超時時間,即Nginx服務器向客戶端發送了數據包,但客戶端一直沒有去接收這個數據包。
    若是某個鏈接超過send_timeout定義的超時時間,那麼Nginx將會關閉這個鏈接。單位是秒,能夠設置爲3。

buffer和cache(如下配置都是針對單個請求)

  • client_body_buffer_size

    當客戶端以POST方法提交一些數據到服務端時,會先寫入到client_body_buffer中,若是buffer寫滿會寫到臨時文件裏,建議調整爲128k。
  • client_max_body_size

    瀏覽器在發送含有較大HTTP body的請求時,其頭部會有一個Content-Length字段,client_max_body_size是用來限制Content-Length所示值的大小的。
    這個限制body的配置不用等Nginx接收完全部的HTTP包體,就能夠告訴用戶請求過大不被接受。會返回413狀態碼。
    例如,用戶試圖上傳一個1GB的文件,Nginx在收完包頭後,發現Content-Length超過client_max_body_size定義的值,
    就直接發送413(Request Entity Too Large)響應給客戶端。
    將該數值設置爲0,則禁用限制,建議設置爲10m。
  • client_header_buffer_size

    設置客戶端header的buffer大小,建議4k。
  • large_client_header_buffers

    對於比較大的header(超過client_header_buffer_size)將會使用該部分buffer,兩個數值,第一個是個數,第二個是每一個buffer的大小。
    建議設置爲4 8k
  • open_file_cache

    該參數會對如下信息進行緩存:
    打開文件描述符的文件大小和修改時間信息;
    存在的目錄信息;
    搜索文件的錯誤信息(文件不存在無權限讀取等信息)。
    格式:open_file_cache max=size inactive=time;
    max設定緩存文件的數量,inactive設定通過多長時間文件沒被請求後刪除緩存。
    建議設置 open_file_cache max=102400 inactive=20s;
  • open_file_cache_valid

    指多長時間檢查一次緩存的有效信息。建議設置爲30s。
  • open_file_cache_min_uses

    open_file_cache指令中的inactive參數時間內文件的最少使用次數,
    如,將該參數設置爲1,則表示,若是文件在inactive時間內一次都沒被使用,它將被移除。
    建議設置爲2。

壓縮

對於純文本的內容,Nginx是可使用gzip壓縮的。使用壓縮技術能夠減小對帶寬的消耗。
由ngx_http_gzip_module模塊支持

配置以下:
gzip on; //開啓gzip功能
gzip_min_length 1024; //設置請求資源超過該數值才進行壓縮,單位字節
gzip_buffers 16 8k; //設置壓縮使用的buffer大小,第一個數字爲數量,第二個爲每一個buffer的大小
gzip_comp_level 6; //設置壓縮級別,範圍1-9,9壓縮級別最高,也最耗費CPU資源
gzip_types text/plain application/x-javascript text/css application/xml image/jpeg image/gif image/png; //指定哪些類型的文件須要壓縮
gzip_disable "MSIE 6\."; //IE6瀏覽器不啓用壓縮

測試:
curl -I -H "Accept-Encoding: gzip, deflate" http://www.wangzb.com/1.css

日誌

  • 錯誤日誌級別調高,好比crit級別,儘可能少記錄可有可無的日誌。
  • 對於訪問日誌,若是不要求記錄日誌,能夠關閉,
  • 靜態資源的訪問日誌關閉

靜態文件過時

對於靜態文件,須要設置一個過時時間,這樣可讓這些資源緩存到客戶端瀏覽器,
在緩存未失效前,客戶端再也不向服務期請求相同的資源,從而節省帶寬和資源消耗。

配置示例以下:
location ~* ^.+\.(gif|jpg|png|css|js)$                                      
{
    expires 1d; //1d表示1天,也能夠用24h表示一天。
}

做爲代理服務器

Nginx絕大多數狀況下都是做爲代理或者負載均衡的角色。
由於前面章節已經介紹過如下參數的含義,在這裏只提供對應的配置參數:
http
{
    proxy_cache_path /data/nginx_cache/ levels=1:2 keys_zone=my_zone:10m inactive=300s max_size=5g;
    ...;
    server
    {
	proxy_buffering on;
	proxy_buffer_size 4k;
	proxy_buffers 2 4k;
	proxy_busy_buffers_size 4k;
	proxy_temp_path /tmp/nginx_proxy_tmp 1 2;
	proxy_max_temp_file_size 20M;
	proxy_temp_file_write_size 8k;
	
	location /
	{
	    proxy_cache my_zone;
	    ...;
	}
    }
}

SSL優化

  • 適當減小worker_processes數量,由於ssl功能須要使用CPU的計算。

  • 使用長鏈接,由於每次創建ssl會話,都會耗費必定的資源(加密、解密)

  • 開啓ssl緩存,簡化服務端和客戶端的「握手」過程。

    ssl_session_cache   shared:SSL:10m; //緩存爲10M
    ssl_session_timeout 10m; //會話超時時間爲10分鐘

 調整Linux內核參數

做爲高性能WEB服務器,只調整Nginx自己的參數是不行的,由於Nginx服務依賴於高性能的操做系統。
如下爲常見的幾個Linux內核參數優化方法。
  • 1 net.ipv4.tcp_max_tw_buckets

    對於tcp鏈接,服務端和客戶端通訊完後狀態變爲timewait,假如某臺服務器很是忙,鏈接數特別多的話,那麼這個timewait數量就會愈來愈大。
    畢竟它也是會佔用必定的資源,因此應該有一個最大值,當超過這個值,系統就會刪除最先的鏈接,這樣始終保持在一個數量級。
    這個數值就是由net.ipv4.tcp_max_tw_buckets這個參數來決定的。
    CentOS7系統,你可使用sysctl -a |grep tw_buckets來查看它的值,默認爲32768,
    你能夠適當把它調低,好比調整到8000,畢竟這個狀態的鏈接太多也是會消耗資源的。
    但你不要把它調到幾10、幾百這樣,由於這種狀態的tcp鏈接也是有用的,
    若是一樣的客戶端再次和服務端通訊,就不用再次創建新的鏈接了,用這個舊的通道,省時省力。
  • 2 net.ipv4.tcp_tw_recycle = 1

    該參數的做用是快速回收timewait狀態的鏈接。上面雖然提到系統會自動刪除掉timewait狀態的鏈接,但若是把這樣的鏈接從新利用起來豈不是更好。
    因此該參數設置爲1就可讓timewait狀態的鏈接快速回收,它須要和下面的參數配合一塊兒使用。
  • 3 net.ipv4.tcp_tw_reuse = 1

    該參數設置爲1,將timewait狀態的鏈接從新用於新的TCP鏈接,要結合上面的參數一塊兒使用。
  • 4 net.ipv4.tcp_syncookies = 1

    tcp三次握手中,客戶端向服務端發起syn請求,服務端收到後,也會向客戶端發起syn請求同時連帶ack確認,
    假如客戶端發送請求後直接斷開和服務端的鏈接,不接收服務端發起的這個請求,服務端會重試屢次,
    這個重試的過程會持續一段時間(一般高於30s),當這種狀態的鏈接數量很是大時,服務器會消耗很大的資源,從而形成癱瘓,
    正常的鏈接進不來,這種惡意的半鏈接行爲其實叫作syn flood攻擊。
    設置爲1,是開啓SYN Cookies,開啓後能夠避免發生上述的syn flood攻擊。
    開啓該參數後,服務端接收客戶端的ack後,再向客戶端發送ack+syn以前會要求client在短期內迴應一個序號,
    若是客戶端不能提供序號或者提供的序號不對則認爲該客戶端不合法,因而不會發ack+syn給客戶端,更涉及不到重試。
  • 5 net.ipv4.tcp_max_syn_backlog

    該參數定義系統能接受的最大半鏈接狀態的tcp鏈接數。客戶端向服務端發送了syn包,服務端收到後,會記錄一下,
    該參數決定最多能記錄幾個這樣的鏈接。在CentOS7,默認是256,當有syn flood攻擊時,這個數值過小則很容易致使服務器癱瘓,
    實際上此時服務器並無消耗太多資源(cpu、內存等),因此能夠適當調大它,好比調整到30000。
  • 6 net.ipv4.tcp_syn_retries

    該參數適用於客戶端,它定義發起syn的最大重試次數,默認爲6,建議改成2。
  • 7 net.ipv4.tcp_synack_retries

    該參數適用於服務端,它定義發起syn+ack的最大重試次數,默認爲5,建議改成2,能夠適當預防syn flood攻擊。
  • 8 net.ipv4.ip_local_port_range

    該參數定義端口範圍,系統默認保留端口爲1024及如下,以上部分爲自定義端口。這個參數適用於客戶端,
    當客戶端和服務端創建鏈接時,好比說訪問服務端的80端口,客戶端隨機開啓了一個端口和服務端發起鏈接,
    這個參數定義隨機端口的範圍。默認爲32768    61000,建議調整爲1025 61000。
  • 9 net.ipv4.tcp_fin_timeout

    tcp鏈接的狀態中,客戶端上有一個是FIN-WAIT-2狀態,它是狀態變遷爲timewait前一個狀態。
    該參數定義不屬於任何進程的該鏈接狀態的超時時間,默認值爲60,建議調整爲6。
  • 10 net.ipv4.tcp_keepalive_time

    tcp鏈接狀態裏,有一個是established狀態,只有在這個狀態下,客戶端和服務端才能通訊。正常狀況下,當通訊完畢,
    客戶端或服務端會告訴對方要關閉鏈接,此時狀態就會變爲timewait,若是客戶端沒有告訴服務端,
    而且服務端也沒有告訴客戶端關閉的話(例如,客戶端那邊斷網了),此時須要該參數來斷定。
    好比客戶端已經斷網了,但服務端上本次鏈接的狀態依然是established,服務端爲了確認客戶端是否斷網,
    就須要每隔一段時間去發一個探測包去確認一下看看對方是否在線。這個時間就由該參數決定。它的默認值爲7200秒,建議設置爲30秒。
  • 11 net.ipv4.tcp_keepalive_intvl

    該參數和上面的參數是一塊兒的,服務端在規定時間內發起了探測,查看客戶端是否在線,若是客戶端並無確認,
    此時服務端還不能認定爲對方不在線,而是要嘗試屢次。該參數定義從新發送探測的時間,即第一次發現對方有問題後,過多久再次發起探測。
    默認值爲75秒,能夠改成3秒。
  • 12 net.ipv4.tcp_keepalive_probes

    第10和第11個參數規定了什麼時候發起探測和探測失敗後再過多久再發起探測,但並無定義一共探測幾回纔算結束。
    該參數定義發起探測的包的數量。默認爲9,建議設置2。

設置和範例

在Linux下調整內核參數,能夠直接編輯配置文件/etc/sysctl.conf,而後執行sysctl -p命令生效

結合以上分析的各內核參數,範例以下
net.ipv4.tcp_fin_timeout = 6
net.ipv4.tcp_keepalive_time = 30
net.ipv4.tcp_max_tw_buckets = 8000
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog = 30000
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
net.ipv4.ip_local_port_range = 1025 61000
net.ipv4.tcp_keepalive_intvl = 3
net.ipv4.tcp_keepalive_probes = 2
相關文章
相關標籤/搜索