网络配置参数和调优的一些总结

内核配置

先来了解几个关于网络的内核配置。

目录

以 CentOS 7 为例,目录 /proc/sys/ 存放着内核相关配置,其中网络相关的主要集中在 /proc/sys/net/core//proc/sys/net/ipv4//proc/sys/net/ipv6/ 几个目录下。在这几个目录下,不同参数名称对应一个文件,修改文件值可以调整对应参数。

同时,想要修改 /proc/sys/ 下参数也可以通过修改 /etc/sysctl.conf 配置文件达到目的。如:想要修改 /proc/sys/net/ipv4/tcp_max_syn_backlog1024,可以添加一行 net.ipv4.tcp_max_syn_backlog = 1024

主要参数说明

一般需要调优的参数
  • somaxconn 完成连接队列上线。应用完成连接队列大小计算方式:

    1
    min(backlog, somaxconn)

    backlog 为打开 socket 时候的传入值,完成连接队列大小取决于该参数系统配置的最小值

  • tcp_max_syn_backlog tcp 半连接队列上限。应用半连接队列大小计算方式:

    1
    2
    table_entries = min(min(somaxconn,backlog),tcp_max_syn_backlog)
    roundup_pow_of_two(table_entries + 1) # 大于 table_entries + 1 的最小 2 的 n 次幂

    somaxconntcp_max_syn_backlog 同时影响半连接队列的大小。所以对于一般应用程序需要在开启 Socket 时候指定 backlog,还需要提前对系统进行调优。

    • 默认情况下 somaxconn == tcp_max_syn_backlog == 128 需要配置提高,不然可能导致应用配置无效。
    • 举例来说 redis、nginx 使用的 backlog 为 511。在系统配置满足的情况下,半连接队列为 512,完成连接队列为 511
  • tcp_abort_on_overflow 控制完成连接队列满时,收到客户端 ACK 时的处理方案。默认为 0,会忽略该次 ACK,导致向客户端重发 ACK+SYN,期望客户端再次发送 ACK 时候完成连接队列有空闲。设置为 1 会直接发送 RST 给客户端。

由 TCP 全连接队列和半连接队列导致问题的典型案例可以参看阿里这一次问题复盘


  • tcp_timestamps 连接需要额外使用 10 个字节来发送对方和回复的时间戳,用来辅助判断 TCP 包顺序判断。以下两个选项需要双方都开启 tcp_timestamp 才能正常生效
  • tcp_tw_reuse 一般针对客户端方生效(比如压测发起机),是否允许将处于 TIME_WAIT 状态 socket 用于开启新的连接。如果禁用需要等待 2 个 MSL
  • tcp_tw_recycle 系统缓存不同 IP 请求的最新 timestamp,如果来自同一主机的 SYN 请求时间小于缓存时间会被丢弃,如果大于则复用 TIME_WAIT 连接。但是由于大部分网络请求都经过 NAT,所以容易产生错误错误的过滤。一般不会开启。
其他参数
  • tcp_syncookies 控制是否在连接 ESTABLISHED 阶段才进行资源分配,默认 1。
    • 1 连接队列满时生效
    • 0 不生效,始终在收到 SYN 时分配资源
    • 2 始终生效
  • tcp_fastopen 应用程序作为服务端是否支持 TCP FastOpen
Socket 选项
  • SO_REUSEADDR 允许应用程序绑定同一端口
  • SO_LINGER 默认为禁用,此时 close() 方法会直接返回,同时将 buffer 中内容交给操作系统发出并执行四次挥手;设置开启时需要指定时间,close() 方法会进行等待内容的全部发出并进行四次挥手,直到超时时间,如果超过时间阈值时将直接发送 RST 直接中断连接不再进行数据发送和四次挥手

服务器配置

默认情况下 Java 程序给出的 SererSocket 默认 backlog 为 100,系统的 somaxconn 为 128,这对于一些访问量高的程序来说可能并不够。一般来说,首先会把服务器的调高如 1024(因为无论是 ng、redis 还是一些 web 服务 128 都挺小的)。同时如果使用 tomcat 还需要注意一下几个配置:

  • maxThreads 工作线程池最大数,默认 200
  • maxConnections 最多连接的 Socket 数量。BIO 默认 200,NIO 默认 10000,APR 默认 8192
  • disableKeepAlivePercentage 需要主动关闭长连接的阈值
  • acceptCount 对应 socket 的 backlog 数值,通过 netstat/ss 观察到有丢弃的连接时需要调整 accept 队列容量

作为一些及时性要求高的应用或者还需要在 TCP 连接建立时候关闭 delay ack 的优化,因为默认的情况下为了提高传输效率会开启 Nagle 算法(将短时间内的多个 ack 合并成一个包,类型响应合并)

参考

码路加油
显示评论