Nginx-性能優化

前言

這篇關於 Nginx 的性能優化,是我查閱資料研究所成,並無用於實際生產環境,<font color=red>如若你想用於實踐,請謹慎測試以後使用。</font>javascript

Nginx 性能優化,主要是減小磁盤 iocss

  • 請求頭、請求體、響應體都在緩衝區操做。
  • 文件信息的讀取

減小網絡 io。前端

  • gzip 壓縮。前端資源也能夠提早進行 gzip 壓縮,這樣請求的時候就不用再壓縮了,減小對 cpu 的損耗。
  • 強緩存。減小對後端的靜態資源的請求。

http 連接的儘快釋放,減小請求的堆積。java

linux 內核優化。這部分主要是查閱資料加上本身的理解。內容來自 《深刻理解 Nginx 模塊開發與架構設計》。node

調帳參數以後可使用 abjmeter 進行壓測,根據實際效果來進行調優。linux

Nginx 必定要在安全的狀況下作性能優化。否則 tcp 攻擊就能給你服務器搞掛了,能用纔是王道。安全訪問第一,性能第二。nginx

調優以後,必定記得要作限流哦。web

下個系列準備寫 Mysql 相關,已經在作準備了。sql

linux 內核優化

能夠修改 /etc/sysctl.conf 來修改內核參數。<font color=red>這部分優化慎重</font>json

  • 查看 tcp 相關係統參數
sysctl -a | grep 'net.ipv4.tcp' | grep -v grep
fs.file-max = 999999
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_keepalive_time = 15
net.ipv4.tcp_fin_timeout = 15
net.ipv4.tcp_max_tw_buckets = 5000
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_rmem = 4096 32768 262144
net.ipv4.tcp_wmem = 4096 32768 262144
net.ipv4.tcp_max_orphans = 262144 
net.core.netdev_max_backlog = 262144
net.core.rmem_default = 262144
net.core.wmem_default = 262144
net.core.rmem_max = 2097152
net.core.wmem_max = 2097152
net.core.somaxconn = 262144 
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_max_syn_backlog=262144

修改以後執行如下命令,使配置生效。

sysctl -p

上面的參數意義解釋以下:

  • fs.file-max:999999

    這個參數表示進程(好比一個worker進程)能夠同時打開的最大句柄數,這 個參數直接限制最大併發鏈接數,需根據實際狀況配置。
  • net.ipv4.tcp_tw_reuse:

    這個參數設置爲1,表示容許將TIME-WAIT狀態的socket從新用於新的 TCP鏈接,這對於服務器來講頗有意義,由於服務器上總會有大量TIME-WAIT狀態的鏈接。
  • net.ipv4.tcp_keepalive_time:

    這個參數表示當keepalive啓用時,TCP發送keepalive消息的頻度。 默認是2小時,若將其設置得小一些,能夠更快地清理無效的鏈接。
  • net.ipv4.tcp_fin_timeout:

    這個參數表示當服務器主動關閉鏈接時,socket保持在FIN-WAIT-2狀態的最大時間。
  • net.ipv4.tcp_max_tw_buckets:

    這個參數表示操做系統容許TIME_WAIT套接字數量的最大值, 若是超過這個數字,TIME_WAIT套接字將馬上被清除並打印警告信息。該參數默認爲 180000,過多的TIME_WAIT套接字會使Web服務器變慢。
  • net.ipv4.ip_local_port_range:

    這個參數定義了在UDP和TCP鏈接中本地(不包括鏈接的遠端) 端口的取值範圍。
  • net.ipv4.tcp_rmem:

    這個參數定義了TCP接收緩存(用於TCP接收滑動窗口)的最小 值、默認值、最大值。
  • net.ipv4.tcp_wmem:

    這個參數定義了TCP發送緩存(用於TCP發送滑動窗口)的最小 值、默認值、最大值。
  • net.ipv4.tcp_max_orphans

    選項用於記錄那些還沒有收到客戶端確認信息的鏈接請求的最大值。對於有128MB內存的系統而言,此參數的默認值是1024,對小內存的系統則是128。
  • net.core.netdev_max_backlog:

    當網卡接收數據包的速度大於內核處理的速度時,會有一個隊列 保存這些數據包。這個參數表示該隊列的最大值。
  • net.core.net.core.rmem_default:

    這個參數表示內核套接字接收緩存區默認的大小。
  • net.core.wmem_default:

    這個參數表示內核套接字發送緩存區默認的大小。
  • net.core.rmem_max:

    這個參數表示內核套接字接收緩存區的最大大小。
  • net.core.wmem_max:

    這個參數表示內核套接字發送緩存區的最大大小。

滑動窗口的大小與套接字緩存區會在必定程度上影響併發鏈接的數目。

每一個 TCP鏈接都會爲維護TCP滑動窗口而消耗內存,這個窗口會根據服務器的處理速度收縮或擴 張。

參數wmem_max的設置,須要平衡物理內存的總大小、Nginx併發處理的最大鏈接數量 (由nginx.conf中的worker_processes和worker_connections參數決定)而肯定。

固然,若是僅僅 爲了提升併發量使服務器不出現Out Of Memory問題而去下降滑動窗口大小,那麼並不合 適,由於滑動窗口太小會影響大數據量的傳輸速度。

rmem_default、wmem_default、 rmem_max、wmem_max這4個參數的設置須要根據咱們的業務特性以及實際的硬件成原本綜 合考慮。

  • net.core.somaxconn

    選項表示當每一個網絡接口接收數據包的速率比內核處理這些包的速率快時,容許發送到隊列的數據包的最大數目。
  • net.ipv4.tcp_syncookies:

    設置爲 1。該參數與性能無關,用於解決TCP的SYN攻擊。
  • net.ipv4.tcp_max_syn_backlog:

    這個參數表示TCP三次握手創建階段接收SYN請求隊列的最大 長度,默認爲1024,將其設置得大一些可使出現Nginx繁忙來不及accept新鏈接的狀況時, Linux不至於丟失客戶端發起的鏈接請求。

內存及磁盤資料優化

client_header_buffer_size 1k;

做爲靜態資源訪問 1k 足夠了。

客戶端請求頭部的緩衝區大小,默認 1k,當請求接口的時候,根據請求頭數據設置 4k 整數倍。

4k 爲系統內存頁大小,命令 getconf PAGESIZE 內存頁大小

large_client_header_buffers

image-20200329190558284

client_body_in_single_buffer

設置爲 on,http 包一概寫入到內存 buffer 中,若是包體超過 client_body_buffer_size 的大小,仍是會寫入到磁盤文件中。

client_body_buffer_size

x64 默認 16K。定義接受請求體內存緩衝區大小,請求先寫入到緩存區,超過在寫入臨時文件中。

client_max_body_size 100m;

設置客戶端請求體最大容許大小,默認 1m。檢查的是 Content-Length。設置爲 0 不檢查。針對具體 location 配置。防止被請求攻擊,在須要調大的地方設置,不要全局設置。

sendflie on;

文件內容讀取減小了內核態到用戶態的拷貝,直接從內核態到網卡設備,提升了發送效率。

open_file_cache

緩存文件的存儲信息。max 表示最大存儲數量,超過這個數量,採用 LRU 淘汰

inactive 指定時間段,該時間段內沒有被訪問過的元素,會被淘汰

open_file_cache max=65535 inactive=20s;

open_file_cache_min_uses

默認爲 1。與 open_file_cache 的 inactive 配合使用,若是在 inactive 指定的時間內,訪問次數超過 open_file_cache_min_uses 指定的次數,不會淘汰緩存。

調大文件句柄限制

linux 一切皆文件,可是進程打開的文件數會有限制。可針對用戶和進程來限制文件句柄數。

  • 文件句柄,能夠針對用戶,進程設置

    • 全局設置 /etc/security/limits.conf
* hard nofile 65535
* soft nofile 65535
root hard nofile 65535
- nginx 進程配置
worker_rlimit_nofile 20480;

日誌優化

可適當減小日誌操做。好比訪問靜態資料的日誌記錄,若是你感受不重要,能夠取消日誌記錄。這樣請求資源的時候就會減小日誌的磁盤 io。

# 關閉日誌
access_log off;
# 禁用文件未找到的錯誤到日誌中去
log_not_found off;

反向代理優化

若是你用 nginx 做爲代理服務器,也要減小磁盤 io 的讀取。

proxy_buffering on;
proxy_buffer_size 4k;
proxy_buffers 16 64k;
proxy_busy_buffers_size 128k;
proxy_temp_file_write_size 128k;
proxy_set_header Host $http_host;
proxy_set_header X-REAL-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

Nginx 優化配置

# 配置 worker 進程所屬用戶,用戶組
user nginx nginx;

# 配置 worker 進程數量,爲避免 cpu 切換損耗,配置和系統內核數同樣便可,或者 auto
worker_processes auto;

# 配置 cpu 親和,auto 表明自動綁定
worker_cpu_affinity auto;

# nginx 進程打開文件描述符數目,此值覆蓋 ulimit -n 的值。
worker_rlimit_nofile 65535;

events {
    # 用這個模型來高效處理異步事件
    use epoll;

    # 設置爲 on worker 進程輪流接受新連接,官方推薦設置爲 off.高負載的狀況下設置爲 on.
    accept_mutex on;

    # worker進程是否同時接受鏈接全部新請求。默認爲off,表示一次只接受一個新的請求。官方推薦 off
    multi_accept on;

    # 配置 一個 woker 進程處理的鏈接數
    worker_connections 65535;
}
http {
    # 關閉日誌
    access_log off;
    # 隱藏響應頭中的有關操做系統和web server(Nginx)版本號的信息,這樣對於安全性是有好處的。
    server_tokens off;
    sendfile on;
    # 設置爲非零值時,可限制單個 sendfile() 調用時傳輸的數據量。若是沒有限制,一個快速 鏈接可能會徹底佔用工做進程。
    sendfile_max_chunk 5m;
    # tcp_nopush 和 tcp_nodeny 能夠一塊兒生效
    # 等數據包累計到必定大小發送,啓用 sendfile 生效
    tcp_nopush on;
    # 該選項僅在鏈接轉換到 keep-alive ,長鏈接狀態時啓用。讓 tcp 儘快發包。
    tcp_nodelay on;
    # 爲了儘快釋放鏈接,能夠設置小點. 15 至 30
    keepalive_timeout 15;

    # 客戶端請求頭部的緩衝區大小,默認 1k,當請求接口的時候須要設置 4k 整數倍.內存設置爲系統內存頁大小,命令 getconf PAGESIZE 內存頁大小
    client_header_buffer_size 4k;

    large_client_header_buffers 8 8k;

    # 根據需求設置,接口請求能夠設置大些
    client_body_buffer_size 128k;

    # 設置客戶端請求體最大容許大小,默認 1m。檢查的是 Content-Length。設置爲 0 不檢查。針對具體 location 配置
    client_max_body_size 1m;


    # 下面這個參數將爲打開文件指定緩存,默認是沒有啓用的,max指定緩存數量,建議和打開文件數一致,
    # inactive是指通過多長時間文件沒被請求後刪除緩存。
    open_file_cache max=262140 inactive=20s;
    # 下面這個是指多長時間檢查一次緩存的有效信息。
    open_file_cache_valid 30s;
    # open_file_cache指令中的inactive參數時間內文件的最少訪問次數,低於這個數,緩存清除
    open_file_cache_min_uses 1;
    open_file_cache_errors on;

    reset_timedout_connection on;
    client_body_timeout 10;
    send_timeout 2;

    # 限制每一個 ip 的鏈接數
    limit_conn_zone $binary_remote_addr zone=conn_limit_per_ip:10m;

    # 限制每一個 ip 每秒的請求數
    limit_req_zone $binary_remote_addr zone=req_limit_per_ip:10m rate=10r/s;

    gzip on;
    # 在響應頭中增長,Vary: Accept-Encoding
    gzip_vary on;
    # gzip壓縮級別1-9,數字越大壓縮效果越好,壓縮時間也就越長CPU越高
    gzip_comp_level 5;
    # 申請內存時大小,若是源文件 9k,超過了 8K,那會申請 16*8K。
    gzip_buffers 8 128k;
    gzip_min_length 5K;
    gzip_proxied any;
    gzip_disable msie6;
    gzip_http_version 1.1;
    # 文本(js、text、css、xml、json)壓縮比較好,圖片已經進行過壓縮,在壓縮,效果不是很明顯,還浪費 cpu
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/json application/xml+rss application/rss+xml application/atom+xml image/svg+xml;

    # 安全相關 header
    add_header X-Frame-Options "SAMEORIGIN" always;
    add_header Feature-Policy "autoplay 'none'; camera 'none'" always;
    add_header X-XSS-Protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Referrer-Policy "no-referrer-when-downgrade" always;
    add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;


    server {
        listen 80 backlog=262144;

        limit_conn conn_limit_per_ip 10;
        limit_req zone=req_limit_per_ip burst=10 nodelay;
        # assets, media
        location ~* \.(?:css(\.map)?|js(\.map)?|jpe?g|png|gif|ico|cur|heic|webp|tiff?|mp3|m4a|aac|ogg|midi?|wav|mp4|mov|webm|mpe?g|avi|ogv|flv|wmv)$ {
            # 強緩存,時間爲一年,瀏覽器和 cdn 中間件能夠緩存
            add_header Cache-Control "max-age=31536000";
            etag off;
            access_log off;
            # 禁用文件未找到的錯誤到日誌中去
            log_not_found off;
        }

        # svg, fonts
        location ~* \.(?:svgz?|ttf|ttc|otf|eot|woff2?)$ {
            # 強緩存,時間爲一年,瀏覽器和 cdn 中間件能夠緩存
            add_header Cache-Control "max-age=31536000";
            etag off;
            access_log off;
            # 禁用文件未找到的錯誤到日誌中去
            log_not_found off;
        }
    }

}

資料參考

http-security-headers

Nginx Performance Tuning – Tips & Tricks

《深刻理解 Nginx 模塊開發與架構設計》。


本文由 張攀欽的博客 http://www.mflyyou.cn/ 創做。 可自由轉載、引用,但需署名做者且註明文章出處。

如轉載至微信公衆號,請在文末添加做者公衆號二維碼。微信公衆號名稱:Mflyyou

img

相關文章
相關標籤/搜索