nginx服务器高并发配置详解(单机3w+并发)

释放双眼,带上耳机,听听看~!

文章目录

  • 前言

    • nginx配置
  • 部分异常

    • 系统配置
    • 压测
    • 测试部分问题

前言

以前没有动手实践高并发系统搭建,对它的认知局限在事务控制,异步处理,微服务,负载均衡的应用层处理上。这两天在服务器的实践调优,了解如何配置参数,更重要的是知道为什么要这么配置,从而认识到了应用与操作系统的一些相关联系。
这个过程遇到了许多bug和系统相关,在这次记录中也会一起提到。文章后面会附上实测情况。

nginx配置

下面是nginx的主要主要配置。


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
1# 避免权限问题
2user root;
3# 一般设置逻辑cpu数,可参看自身系统配置:cat /proc/cpuinfo| grep "processor"| wc -l
4worker_processes 6;
5# 内核一切皆文件,所以有客户端连接就会有文件使用。
6worker_rlimit_nofile 256000;
7
8events {
9   # Linux内核为处理大批量文件选择的模式
10    use epoll;
11    # 收到一个新连接通知后接受尽可能多的连接。
12    multi_accept on;
13    # 单个进程连接数
14    worker_connections 65535;
15}
16
17http {
18  # 负载均衡服务器,我这里用了10个节点不一一列举
19  upstream load{
20        server dc-sit-226:8881 max_fails=1 fail_timeout=60s;
21        ...
22        server dc-sit-226:8890 max_fails=1 fail_timeout=60s;
23    }
24    
25    open_file_cache max=102400 inactive=20s;    
26    client_header_buffer_size 4k;
27    sendfile            on;
28    tcp_nopush          on;
29    tcp_nodelay         on;
30    keepalive_timeout   30;
31    
32    server {
33        listen       80;
34        server_name  dc-sit-226;
35      location / {
36            proxy_pass http://load;
37        }
38    }
39}
40
41

配置完成后记得重新加载配置:nginx -s reload。可先测试请求是否正常,并查看nginx日志是否存在异常。

部分异常

  • connect() to 192.168.9.226:8885 failed (13: Permission denied) while connecting to upstream, client: 192.168.64.243, server: dc-sit-226, request: “GET /value HTTP/1.1”, upstream: “http://192.168.9.226:8885/value”, host: “dc-sit-226”

设置网络访问配置:setsebool -P httpd_can_network_connect 1

  • [alert] 12637#0: setrlimit(RLIMIT_NOFILE, 50000) failed (1: Operation not permitted)

很多人知道nginx配置了worker_rlimit_nofile这个参数,但是成功没有就不知道了,reload时如果error.log日志中有这个异常我们就需要先执行:setsebool -P httpd_setrlimit 1,当然除了nginx需要配置文件限制,内核也不要进行修改。

  • [alert] 12291#0: *55710 socket() failed (24: Too many open files) while connecting to upstream, client: 192.168.9.226, server: dc-sit-226, request: “GET /value HTTP/1.0”, upstream: “http://192.168.9.226:8882/value”, host: “dc-sit-226”

当我们worker_rlimit_nofile没有设置成功,超过1024文件访问会抛出这种异常,当然除了设置nginx的值,linux也需要做ulimit配置。下面我们会讲到系统配置。

系统配置

网上的实践配置每篇不是写的很全,或者适配自身系统,有时候还是要通过实际bug针对性的进行配置的添加、修改。这里你也更有机会了解其背后实际作用。

  • /etc/sysctl.conf


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
1# 打开文件句柄数量
2fs.file-max = 655360
3# 最大ip跟踪数
4net.nf_conntrack_max = 655360
5#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为2分钟。
6net.netfilter.nf_conntrack_tcp_timeout_established = 120
7
8# 允许系统打开的端口范围,扩大端口数
9net.ipv4.ip_local_port_range = 10000 65535
10
11# 用来限制监听(LISTEN)队列最大数据包的数量,超过这个数量就会导致链接超时或者触发重传机制,
12net.core.somaxconn = 65535
13# 每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目。
14net.core.netdev_max_backlog = 262144
15
16# 开启时就是同一个源IP来连接同一个目的端口的数据包时间戳必须是递增的,否则就丢弃
17net.ipv4.tcp_timestamps = 0
18# 是否启用timewait 快速回收。如果服务器身处NAT环境,tcp_timestamps为1,安全起见,要禁止
19net.ipv4.tcp_tw_recycle = 1
20# 开启重用。允许将TIME-WAIT sockets 重新用于新的TCP 连接。
21net.ipv4.tcp_tw_reuse = 1
22# timeout状态时间
23net.ipv4.tcp_fin_timeout = 15
24
25# 在TIME_WAIT数量等于该值时,不会有新的产生,
26net.ipv4.tcp_max_tw_buckets = 262144
27# 系统中最多有多少个TCP 套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,孤儿连接将即刻被复位并打印出警告信息。
28net.ipv4.tcp_max_orphans = 262144
29# 是指定所能接受SYN同步包的最大客户端数量。
30net.ipv4.tcp_max_syn_backlog = 262144
31# 为了打开对端的连接,内核需要发送一个SYN,以确认收到上一个 SYN连接请求包。也就是所谓三次握手中的第二次握手。
32# 这个设置决定了内核放弃连接之前发送SYN+ACK 包的数量。
33net.ipv4.tcp_synack_retries = 1
34# 对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,测试感觉两个更稳定
35net.ipv4.tcp_syn_retries = 2
36# 开启SYN Cookies,当出现SYN 等待队列溢出时,启用cookies 来处理,目的是为了防止syn flood攻击。合法用户的高负载应该调整tcp_max_syn_backlog、tcp_synack_retries属性,
37net.ipv4.tcp_syncookies = 0
38
39
  • /etc/security/limits.conf 末尾添加文件打开数量


1
2
3
4
5
6
1* soft nofile 65535
2* hard nofile 65535
3* soft nproc 65535
4* hard nproc 65535
5
6

通过sysctl -p 使得配置生效,可用通过ulimit -a查看file配置是否生效,临时设置也可用通过ulimit -u 65535 配置。

压测

  • apache-ab

ab单条测试-c 不能超过1w。下面是测试发送60w请求,服务器每秒处理1.3w,90%响应在1.4s内。
nginx服务器高并发配置详解(单机3w+并发)


1
2
3
4
5
6
7
8
9
1# 通过脚本多线程压测,3个线程每个并发1w,实现3w Concurrency Level,总共24w请求
2#!/bin/bash
3for((i=1;i<=3;i++));  
4do  
5  ab -k -n 80000 -c 10000 http://dc-sit-226/value > request.log${i} &
6done
7sleep 10
8
9

下面为执行成功结果,单个分析打印在request.log${i} 中,
nginx服务器高并发配置详解(单机3w+并发)
我们抽选一个结果可能看到3w 并发的情况下,服务器90% 的响应时长在3.3s内。高并发以响应90%请求5s内返回指标来看,服务器的理论极限承载应该可以调整到4w左右RPS(requests per second)
nginx服务器高并发配置详解(单机3w+并发)

  • webbench

webbench据说可以直接实现3w并发、测试前两次数据量小还正常,后面就有问题了,通过命令netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}',才发现测试请求全部变CLOSE_WAIT占用资源。

  • jmeter

因为服务器没有GUI界面,生成jmt文件又比较繁琐,所以没选择这个工具。大家可以根据自己情况选择压测工具。

测试部分问题

  1. apr_socket_connect(): Cannot assign requested address (99)

查看net.ipv4.ip_local_port_range、net.ipv4.tcp_tw_recycle、net.ipv4.tcp_tw_reuse、net.ipv4.tcp_timestamps 等系统配置

  1. connect() failed (110: Connection timed out) while connecting to upstream

要查看系统日志:dmesg
异常信息:nf_conntrack: table full, dropping packet.
解决方案:查看系统上述net.nf_conntrack_max 配置。
当然如果并发数达到一定数量、业务系统服务器也会超过承载极限,出现请求超时。

  1. apr_pollset_poll: The timeout specified has expired (70007)

主要是timeout连接超时了,可以加个-k参数,让连接KeepAlive,另外注意nginx的超时配置。

  1. apr_socket_connect(): 由于目标系统积极拒绝

业务系统服务器引起,可能是请求过载。

  1. no live upstreams while connecting to upstream, client: 192.168.9.226, server: dc-sit-226, request: “GET /value HTTP/1.0”, upstream: “http://load/value”, host: “dc-sit-226”

与第二个问题类似,这里的load 我配置的负载均衡服务名,所以nginx应该是端时间找不到后端可用server,就会报no live upstream。可以考虑增加业务服务器数据或者改进接口效率。

给TA打赏
共{{data.count}}人
人已打赏
安全经验

如何避免Adsense违规封号

2021-10-11 16:36:11

安全经验

安全咨询服务

2022-1-12 14:11:49

个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索