Breakthrough 100,000 high concurrency nginx performance optimization experience

Summary of nginx service application under linux (2) -- nginx performance optimization experience with breakthrough 100,000 high concurrency (including kernel parameter optimization)

November 28, 2016 10:32:13

Readings: 4498

Reprinted: http://www.cnblogs.com/kevingrace/p/6094007.html

 

In the daily operation and maintenance work, the nginx service is often used, and the performance bottleneck caused by the high concurrency of nginx is often encountered. Today, here is a brief summary of the configuration of nginx performance optimization (only based on my actual combat experience, if there is anything wrong, please point out~)

1. The optimization here mainly refers to the configuration optimization of nginx. Generally speaking, the nginx configuration files have the following effects on optimization:
1) The number of nginx processes is recommended to be specified according to the number of cpus, generally the same as the number of cpu cores. the same number or a multiple of it.
worker_processes 8;
2) Allocate cpu to each process. In the above example, 8 processes are allocated to 8 cpus. Of course, multiple can be written, or one process can be allocated to multiple cpus.
worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000 10000000;
3) The following command refers to the maximum number of file descriptors opened by an nginx process, the theoretical value should be the maximum number of open files of the system (ulimit -n) divided by the number of nginx processes , but nginx does not distribute requests so evenly, so it's best to be consistent with the value of ulimit -n.
worker_rlimit_nofile 65535;
4) Use epoll's I/O model to efficiently process asynchronous events
use epoll;
5) The maximum number of connections allowed per process, in theory, the maximum number of connections per nginx server is worker_processes*worker_connections.
worker_connections 65535;
6) http connection timeout, the default is 60s, the function is to make the connection between the client and the server continue to be valid within the set time, when there is a subsequent request to the server, this function avoids establishing or re-establishing the connection . Remember that this parameter cannot be set too large! Otherwise, many invalid http connections will occupy the number of nginx connections, and eventually nginx will crash!
keepalive_timeout 60;
7) The buffer size of the client request header, which can be set according to your system paging size. Generally, the header size of a request will not exceed 1k, but since the general system paging is larger than 1k, so here Set to pagination size. The page size can be obtained with the command getconf PAGESIZE.
client_header_buffer_size 4k;
8) The following parameter will specify the cache for open files. It is not enabled by default. Max specifies the number of caches. It is recommended to be consistent with the number of open files. Inactive refers to how long the file has not been requested to delete the cache.
open_file_cache max=102400 inactive=20s;
9) The following refers to how often to check the valid information of the cache.
open_file_cache_valid 30s;
10) The minimum number of times the file is used during the inactive parameter time in the open_file_cache directive. If it exceeds this number, the file descriptor will always be opened in the cache. As in the above example, if a file is not used once during the inactive time , it will be removed.
open_file_cache_min_uses 1;

-------------------------------------------------- -------------- 
The following is a simple nginx configuration file that I use:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

[root@dev-huanqiu ~]# cat /usr/local/nginx/conf/nginx.conf

user   www www;

worker_processes 8;

worker_cpu_affinity 00000001 00000010 00000100 00001000 00010000 00100000 01000000;

error_log   /www/log/nginx_error.log   crit;

pid         /usr/local/nginx/nginx.pid;

worker_rlimit_nofile 65535;

 

events

{

   use epoll;

   worker_connections 65535;

}

 

http

{

   include       mime.types;

   default_type   application/octet-stream;

 

   charset   utf-8;

 

   server_names_hash_bucket_size 128;

   client_header_buffer_size 2k;

   large_client_header_buffers 4 4k;

   client_max_body_size 8m;

 

   sendfile on;

   tcp_nopush     on;

 

   keepalive_timeout 60;

 

   fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2

                 keys_zone=TEST:10m

                 inactive=5m;

   fastcgi_connect_timeout 300;

   fastcgi_send_timeout 300;

   fastcgi_read_timeout 300;

   fastcgi_buffer_size 16k;

   fastcgi_buffers 16 16k;

   fastcgi_busy_buffers_size 16k;

   fastcgi_temp_file_write_size 16k;

   fastcgi_cache TEST;

   fastcgi_cache_valid 200 302 1h;

   fastcgi_cache_valid 301 1d;

   fastcgi_cache_valid any 1m;

   fastcgi_cache_min_uses 1;

   fastcgi_cache_use_stale error timeout invalid_header http_500; 

   open_file_cache max=204800 inactive=20s;

   open_file_cache_min_uses 1;

   open_file_cache_valid 30s; 

 

   tcp_nodelay on;

   

   gzip on;

   gzip_min_length   1k;

   gzip_buffers     4 16k;

   gzip_http_version 1.0;

   gzip_comp_level 2;

   gzip_types       text/plain application/x-javascript text/css application/xml;

   gzip_vary on;

 

   server

   {

     listen       8080;

     server_name   huan.wangshibo.com;

     index index.php index.htm;

     root   /www/html/;

 

     location /status

     {

         stub_status on;

     }

 

     location ~ .*\.(php|php5)?$

     {

         fastcgi_pass 127.0.0.1:9000;

         fastcgi_index index.php;

         include fcgi.conf;

     }

 

     location ~ .*\.(gif|jpg|jpeg|png|bmp|swf|js|css)$

     {

       expires       30d;

     }

 

     log_format   access   '$remote_addr - $remote_user [$time_local] "$request" '

               '$status $body_bytes_sent "$http_referer" '

               '"$http_user_agent" $http_x_forwarded_for';

     access_log   /www/log/access.log   access;

       }

}

 

二、关于FastCGI的几个指令

1)这个指令为FastCGI缓存指定一个路径,目录结构等级,关键字区域存储时间和非活动删除时间。
fastcgi_cache_path /usr/local/nginx/fastcgi_cache levels=1:2 keys_zone=TEST:10m inactive=5m;
2)指定连接到后端FastCGI的超时时间。
fastcgi_connect_timeout 300;
3)向FastCGI传送请求的超时时间,这个值是指已经完成两次握手后向FastCGI传送请求的超时时间。
fastcgi_send_timeout 300;
4)接收FastCGI应答的超时时间,这个值是指已经完成两次握手后接收FastCGI应答的超时时间。
fastcgi_read_timeout 300;
5)指定读取FastCGI应答第一部分 需要用多大的缓冲区,这里可以设置为fastcgi_buffers指令指定的缓冲区大小,上面的指令指定它将使用1个 16k的缓冲区去读取应答的第一部分,即应答头,其实这个应答头一般情况下都很小(不会超过1k),但是你如果在fastcgi_buffers指令中指 定了缓冲区的大小,那么它也会分配一个fastcgi_buffers指定的缓冲区大小去缓存。
fastcgi_buffer_size 16k;
6)指定本地需要用多少和多大的缓冲区来 缓冲FastCGI的应答,如上所示,如果一个php脚本所产生的页面大小为256k,则会为其分配16个16k的缓冲区来缓存,如果大于256k,增大 于256k的部分会缓存到fastcgi_temp指定的路径中, 当然这对服务器负载来说是不明智的方案,因为内存中处理数据速度要快于硬盘,通常这个值 的设置应该选择一个你的站点中的php脚本所产生的页面大小的中间值,比如你的站点大部分脚本所产生的页面大小为 256k就可以把这个值设置为16 16k,或者4 64k 或者64 4k,但很显然,后两种并不是好的设置方法,因为如果产生的页面只有32k,如果用4 64k它会分配1个64k的缓冲区去缓存,而如果使用64 4k它会分配8个4k的缓冲区去缓存,而如果使用16 16k则它会分配2个16k去缓存页面,这样看起来似乎更加合理。
fastcgi_buffers 16 16k;
7)这个指令我也不知道是做什么用,只知道默认值是fastcgi_buffers的两倍。
fastcgi_busy_buffers_size 32k;
8)在写入fastcgi_temp_path时将用多大的数据块,默认值是fastcgi_buffers的两倍。
fastcgi_temp_file_write_size 32k;
9)开启FastCGI缓存并且为其制定一个名称。个人感觉开启缓存非常有用,可以有效降低CPU负载,并且防止502错误。但是这个缓存会引起很多问题,因为它缓存的是动态页面。具体使用还需根据自己的需求。
fastcgi_cache TEST
10)为指定的应答代码指定缓存时间,如上例中将200,302应答缓存一小时,301应答缓存1天,其他为1分钟。
fastcgi_cache_valid 200 302 1h;
fastcgi_cache_valid 301 1d;
fastcgi_cache_valid any 1m;
11)缓存在fastcgi_cache_path指令inactive参数值时间内的最少使用次数,如上例,如果在5分钟内某文件1次也没有被使用,那么这个文件将被移除。
fastcgi_cache_min_uses 1;
12)不知道这个参数的作用,猜想应该是让nginx知道哪些类型的缓存是没用的。
fastcgi_cache_use_stale error timeout invalid_header http_500;

-----------------------------------
以上为nginx中FastCGI相关参数,
另外,FastCGI自身也有一些配置需要进行优化,如果你使用php-fpm来管理FastCGI,可以修改配置文件中的以下值:
1)同时处理的并发请求数,即它将开启最多60个子线程来处理并发连接。
<value name="max_children">60</value>
2)最多打开文件数。
<value name="rlimit_files">65535</value>
3)每个进程在重置之前能够执行的最多请求数。
<value name="max_requests">65535</value>

 

三、关于内核参数的优化,在/etc/sysctl.conf文件内
1)timewait的数量,默认是180000。(Deven:因此如果想把timewait降下了就要把tcp_max_tw_buckets值减小)
net.ipv4.tcp_max_tw_buckets = 6000
2)允许系统打开的端口范围。
net.ipv4.ip_local_port_range = 1024 65000
3)启用TIME-WAIT状态sockets快速回收功能;用于快速减少在TIME-WAIT状态TCP连接数。1表示启用;0表示关闭。这个选项一般不推荐启用,因为在NAT(Network Address Translation)网络下,会导致大量的TCP连接建立错误,从而引起网站访问故障。
net.ipv4.tcp_tw_recycle = 0
----------------------------------------------------------------------------------------------------------------------------------
实际上,net.ipv4.tcp_tw_recycle功能的开启,要需要net.ipv4.tcp_timestamps(一般系统默认是开启这个功能的)这个开关开启后才有效果;
当tcp_tw_recycle 开启时(tcp_timestamps 同时开启,快速回收 socket 的效果达到),对于位于NAT设备后面的 Client来说,是一场灾难!
会导致到NAT设备后面的Client连接Server不稳定(有的 Client 能连接 server,有的 Client 不能连接 server)。
也就是说,tcp_tw_recycle这个功能,是为内部网络(网络环境自己可控 ” ——不存在NAT 的情况)设计的,对于公网环境下,不宜使用。
通常来说,回收TIME_WAIT状态的socket是因为“无法主动连接远端”,因为无可用的端口,而不应该是要回收内存(没有必要)。
即:需求是Client的需求,Server会有“端口不够用”的问题吗?
除非是前端机,需要大量的连接后端服务,也就是充当着Client的角色。

正确的解决这个总是办法应该是:
net.ipv4.ip_local_port_range = 9000 6553 #默认值范围较小
net.ipv4.tcp_max_tw_buckets = 10000 #默认值较小,还可适当调小
net.ipv4.tcp_tw_reuse = 1 
net.ipv4.tcp_fin_timeout = 10 
----------------------------------------------------------------------------------------------------------------------------------

4)开启重用功能,允许将TIME-WAIT状态的sockets重新用于新的TCP连接。这个功能启用是安全的,一般不要去改动!
net.ipv4.tcp_tw_reuse = 1
5)开启SYN Cookies,当出现SYN等待队列溢出时,启用cookies来处理。
net.ipv4.tcp_syncookies = 1
6)web应用中listen函数的backlog默认会给我们内核参数的net.core.somaxconn限制到128,而nginx定义的NGX_LISTEN_BACKLOG默认为511,所以有必要调整这个值。
net.core.somaxconn = 262144
7)每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
net.core.netdev_max_backlog = 262144
8)系统中最多有多少个TCP套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。这个限制仅仅是为了防止简单的DoS攻击,不能过分依靠它或者人为地减小这个值,更应该增加这个值(如果增加了内存之后)。
net.ipv4.tcp_max_orphans = 262144
9)记录的那些尚未收到客户端确认信息的连接请求的最大值。对于有128M内存的系统而言,缺省值是1024,小内存的系统则是128。
net.ipv4.tcp_max_syn_backlog = 262144
10)时间戳可以避免序列号的卷绕。一个1Gbps的链路肯定会遇到以前用过的序列号。时间戳能够让内核接受这种“异常”的数据包。
net.ipv4.tcp_timestamps = 1
-------------------------------------------------------------------------------------------------------------------------------------------------------
有不少服务器为了提高性能,开启net.ipv4.tcp_tw_recycle选项,在NAT网络环境下,容易导致网站访问出现了一些connect失败的问题
个人建议:
关闭net.ipv4.tcp_tw_recycle选项,而不是net.ipv4.tcp_timestamps;
因为在net.ipv4.tcp_timestamps关闭的条件下,开启net.ipv4.tcp_tw_recycle是不起作用的;而net.ipv4.tcp_timestamps可以独立开启并起作用。
-------------------------------------------------------------------------------------------------------------------------------------------------------
11)为了打开对端的连接,内核需要发送一个SYN并附带一个回应前面一个SYN的ACK。也就是所谓三次握手中的第二次握手。这个设置决定了内核放弃连接之前发送SYN+ACK包的数量。
net.ipv4.tcp_synack_retries = 1
12)在内核放弃建立连接之前发送SYN包的数量。
net.ipv4.tcp_syn_retries = 1
13)如果套接字由本端要求关闭,这个参数 决定了它保持在FIN-WAIT-2状态的时间。对端可以出错并永远不关闭连接,甚至意外当机。缺省值是60秒。2.2 内核的通常值是180秒,你可以按这个设置,但要记住的是,即使你的机器是一个轻载的WEB服务器,也有因为大量的死套接字而内存溢出的风险,FIN- WAIT-2的危险性比FIN-WAIT-1要小,因为它最多只能吃掉1.5K内存,但是它们的生存期长些。
net.ipv4.tcp_fin_timeout = 1
14)当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时。
net.ipv4.tcp_keepalive_time = 30

----------------------------------------------------------------------
下面贴出一个本人常用的内核参数的标准配置
[root@dev-huanqiu ~]# cat /etc/sysctl.conf
net.ipv4.ip_forward = 0
net.ipv4.conf.default.rp_filter = 1
net.ipv4.conf.default.accept_source_route = 0
kernel.sysrq = 0
kernel.core_uses_pid = 1
net.ipv4.tcp_syncookies = 1
kernel.msgmnb = 65536
kernel.msgmax = 65536
kernel.shmmax = 68719476736
kernel.shmall = 4294967296
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.tcp_sack = 1
net.ipv4.tcp_window_scaling = 1
net.ipv4.tcp_rmem = 4096 87380 4194304
net.ipv4.tcp_wmem = 4096 16384 4194304
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.core.netdev_max_backlog = 262144
net.core.somaxconn = 262144
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4.tcp_timestamps = 1
net.ipv4.tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_tw_recycle = 0
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.ip_conntrack_max = 6553500 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325166267&siteId=291194637