Skip to content

高并发需要注意的点

一、服务器连接

这里的“服务器连接”包含应用服务与 MySQL、Redis、消息队列等中间件之间的 TCP 连接。

当并发量持续升高时,应用服务到中间件的连接数可能迅速放大。如果操作系统和应用本身的连接参数没有提前调优,就容易出现连接堆积、连接被拒绝或请求超时等问题。

vi /etc/sysctl.conf

重点关注 net.core.somaxconnnet.ipv4.tcp_max_syn_backlog 等参数。

#对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃,不应该大于255,默认值是5,对应于180秒左右时间
net.ipv4.tcp_syn_retries=2
#net.ipv4.tcp_synack_retries=2
#表示当keepalive起用的时候,TCP发送keepalive消息的频度。缺省是2小时,改为300秒
net.ipv4.tcp_keepalive_time=1200
net.ipv4.tcp_orphan_retries=3
#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间
net.ipv4.tcp_fin_timeout=30
#表示SYN队列的长度,默认为1024,加大队列长度为8192,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_syn_backlog = 4096
#表示开启SYN Cookies。当出现SYN等待队列溢出时,启用cookies来处理,可防范少量SYN攻击,默认为0,表示关闭
net.ipv4.tcp_syncookies = 1

#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
net.ipv4.tcp_tw_reuse = 1
# `tcp_tw_recycle` 已废弃,不建议继续开启
# 减少超时前的探测次数
net.ipv4.tcp_keepalive_probes=5
# 优化网络设备接收队列
net.core.netdev_max_backlog=3000
net.core.somaxconn= 32768

然后调整 ulimit

vi /etc/security/limits.conf

# End of file 在尾部增加
* soft nofile 65535
* hard nofile 65535

执行 sysctl -p 使其生效。

二、压测客户端配置

如果是压测机器,也需要单独调优。建议优先使用 Linux 进行压测,Windows 在端口、句柄和网络行为上限制更多。

vi /etc/sysctl.conf

主要是增加timewait的最大数和端口的范围(也是解决Non HTTP response code: java.net.NoRouteToHostException的问题)

net.ipv4.tcp_tw_reuse = 1
#TIME_WAIT连接的最大数,这里压测的时候可以调大
net.ipv4.tcp_max_tw_buckets = 5000
#这里主要是开放从1024-65535之间的端口当做请求连接端口。默认值为32768 61000
net.ipv4.ip_local_port_range = 10240 65535

执行 sysctl -p 使其生效。

三、应用服务器

Tomcat 默认线程数通常较小,大流量场景下很容易成为瓶颈,需要按实际并发量和机器资源进行调优。

server:
  tomcat:
    threads:
      max: 2000
    max-connections: 10000

四、MySQL

MySQL 默认连接数通常偏小,可以先查看当前配置,再根据应用连接池上限进行调整。

#查看当前连接数
show variables like '%max_connections%';
#设置连接数,注意这里只能临时生效,重启以后就会失效,如果需要永久生效需要修改配置文件的max_connections参数
set GLOBAL max_connections = 5000;

应用服务器侧也要同步调整连接池参数。

spring:
  datasource:
    name: druidDataSource
    type: com.alibaba.druid.pool.DruidDataSource
    druid:
      #连接池支持的最大连接数。
      max-active: 10000
      #初始化连接数目
      initial-size: 10
      #连接池中连接用完时,新的请求等待时间(毫秒),-1表示无限等待,直到超时
      max-wait: 30000
      #这里需要与初始化连接数匹配,否则可能会有问题
      min-idle: 10

五、Redis

Redis 单机默认 maxclients 通常已经能够覆盖不少场景,但在高并发压测或热点业务下,仍然建议结合连接池参数一起评估。

Redis 服务器侧:

#查看连接数
CONFIG GET maxclients
#查看当前的连接数
info clients
#设置连接数
CONFIG SET maxclients 50000

应用服务器侧:

spring
  redis:
    timeout: 20000
    lettuce:
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 50000
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: -1
        # 连接池中的最大空闲连接
        max-idle: 1000
        # 连接池中的最小空闲连接
        min-idle: 50