2015年9月18日 星期五

Linux、nginx、php-fpm 連線數優化

nginx + php-fpm,連線數一多會發生,502 Bad Gateway 或 504 Gateway Time-out 等問題。
  • 502 Bad Gateway:nginx 連不到 php-fpm。可以增加 php-fpm 連線數量。或將 nginx 連 php-fpm 等待連接的時間設長一點(fastcgi_connect_timeout)。
  • 504 Gateway Time-out:php-fpm 執行時間,超過 nginx 允許的接收時間。可以將 nginx 接收時間設長一點(fastcgi_read_timeout)。
影響連線數限制的設定有三個:linux 系統的限制、nginx 的限制、php-fpm 的限制。
修改時,須視執行情況調整,若設的太大,系統負擔太大,會執行的很慢,甚至崩潰。

[修改 Linux 作業系統設定]
$ vi /etc/sysctl.conf
net.core.somaxconn = 65535
net.ipv4.tcp_max_syn_backlog = 819200
net.core.netdev_max_backlog = 819200
net.ipv4.tcp_syncookies = 0
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1

#不重開機,立即套用設定
$ sysctl -p
#查看設定後的效果
$ cat /proc/sys/net/core/somaxconn
65535
$ cat /proc/sys/net/ipv4/tcp_max_syn_backlog
819200
$ cat /proc/sys/net/core/netdev_max_backlog
819200
$ cat /proc/sys/net/ipv4/tcp_syncookies
0
$ cat /proc/sys/net/ipv4/tcp_timestamps
1
$ cat /proc/sys/net/ipv4/tcp_tw_recycle
1
$ cat /proc/sys/net/ipv4/tcp_tw_reuse
1


[Nginx virtual host 設定]
server {
    #修改 backlog,多個 virtual host,backlog 只須在其中一個設定
    listen 80 backlog=1024;
    ....
}
重啟後,查看 backlog 設定是否生效。
這邊要注意的是,backlog 這個值不是越大越好,
若程式很耗費資源,當 backlog 太大時,可能耗盡 Server 資源,造成網站卡住所有連線反應都很慢,
這個設定值會受 linux 系統 net.core.somaxconn 設定的限制。
$ ss -nlt
State   Recv-Q Send-Q   Local Address:Port    Peer Address:Port
LISTEN    0     1024                *:80                 *:*
[Nginx 全域設定]
user  nginx;
worker_processes  8; #一般設定為 CPU 核心數

error_log  /var/log/nginx/error.log warn;
pid        /var/run/nginx.pid;

events {
    use epoll;
    worker_connections  65535;#每個 worker process 能同時接受的連線數
}
worker_rlimit_nofile 65535; #worker processes 能打開的檔案數限制

http {
    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        on;
    tcp_nopush     on;

    keepalive_timeout  65;

    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 8m;

    server_tokens  off;
    client_body_buffer_size  512k;

    #fastcgi
    #適當調整 fastcgi_connect_timeout、fastcgi_send_timeout、fastcgi_read_timeout 設定值
    fastcgi_connect_timeout 300; #太短可能發生 502 Bad Gateway
    fastcgi_send_timeout 300;
    fastcgi_read_timeout 300; #太短可能發生 504 Gateway Time-out
    fastcgi_buffer_size 64k;
    fastcgi_buffers 4 64k;
    fastcgi_busy_buffers_size 128k;
    fastcgi_temp_file_write_size 128k;
    fastcgi_intercept_errors on;

    #gzip
    gzip  off;
    gzip_min_length  1k;
    gzip_buffers 32  4k;
    gzip_http_version  1.0;
    gzip_comp_level  2;
    gzip_types  text/css text/xml application/javascript application/atom+xml application/rss+xml text/plain application/json;
    gzip_vary  on;

    include /etc/nginx/conf.d/*.conf;
}


[php-fpm 設定]
常駐的 process 數越多,系統越不用開開關關 process,會較節省 CPU。
但 process 數越多,使用的記憶體也會越大,所以,須視CPU與記憶體使用狀況,取一個平衡。
若設的太小,在 php-fpm.log 會記錄相關的訊息。
例如:WARNING: [pool www] server reached pm.max_children setting (50), consider raising it
listen.backlog = 65535
pm.max_children = 800
pm.start_servers = 200
pm.min_spare_servers = 100
pm.max_spare_servers = 800
pm.max_requests = 4000
rlimit_files = 51200


參考:
Need to increase nginx throughput to an upstream unix socket — linux kernel tuning?
怎样优化FastCGI与Nginx的搭配
nginx下关于PHP-FPM在高负载下的优化配置
Nginx Connection 不夠用 的參數調整
Nginx 502错误触发条件与解决办法汇总
https://trac.nginx.org/nginx/ticket/193
解决nginx莫名奇妙的“Resource temporarily unavailable”
nginx優化突破十萬並行連線數
nginx+php-fpm性能参数优化原则
nginx 并发数问题思考:worker_connections,worker_processes与 max clients

沒有留言:

張貼留言