网络性能debug参数整理( 三 )

能够有效防范SYN Flood攻击的手段之一就是SYN Cookie 。SYN Cookie原理由D. J. Bernstain和 Eric Schenk发明 。SYN Cookie是对TCP服务器端的三次握手协议作一些修改,专门用来防范CentOS SYN Flood攻击的一种手段,它的原理是, 在TCP服务器收到TCP SYN包并返回TCP SYN+ACK包时,不分配一个专门的数据区,而是根据这个SYN包计算出一个cookie值 。在收到TCP ACK包时,TCP服务器在根据那个cookie值检查这个TCP ACK包的合法性 。如果合法,再分配专门的数据区进行处理未来的TCP连接
  [root@centos8 ~]# sysctl -a | grep backlognet.core.netdev_max_backlog = 1000#该参数决定了,网络设备接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目 。将数据包放入 CPU 的 backlog 的时候需要看队列内当前积压的数据包有多少,超过 net.core.netdev_max_backlog 后要丢弃数据
 net.ipv4.tcp_max_syn_backlog = 256#表示SYN队列长度,默认1024,改成8192,可以容纳更多等待连接的网络连接数 。
 

  • 其他参数设置
net.core.netdev_max_backlog = 400000#该参数决定了,网络设备接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目 。
net.core.optmem_max = 10000000#该参数指定了每个套接字所允许的最大缓冲区的大小
#指定了接收套接字缓冲区大小的缺省值(以字节为单位) 。
对收消息过程来说,Socket 占用内存量就是 Receive Queue、Prequeue、Backlog、Out of order 队列内排队的 sk_buff 占用内存总数 。当数据被拉取到 User Space 后,就不再占用 Socket 的内存 。这里有几个需要注意的,一个是发送过程和接收过程共用分配的 Socket 内存总量 sk_forward_alloc 。对收消息过程来说,Receive Queue、Prequeue、Backlog、Out of order 共同占用的内存量不能超过 sk->sk_rcvbuf 。如果用户进程处理消息较慢,大量消息在 Receive Queue、Prequeue、Backlog 内排队,则 Out of order 队列的大小会受到限制,而 Out of order 队列大小会影响 TCP Receive Window 的大小,从而在用户进程处理消息慢的时候能通过减小 Receive Window 让对端减慢发消息速度 。一般来说 Socket 的 sk_rcvbuf 受到如下两个配置的控制:
sysctl -w net.core.rmem_max=8388608sysctl -w net.core.rmem_default=8388608  net.core.somaxconn = 100000#Linux kernel参数,表示socket监听的backlog(监听队列)上限
net.core.wmem_default = 11059200#定义默认的发送窗口大小;对于更大的 BDP 来说,这个大小也应该更大 。
net.core.wmem_max = 11059200#定义发送窗口的最大大小;对于更大的 BDP 来说,这个大小也应该更大 。
net.ipv4.conf.all.rp_filter = 1net.ipv4.conf.default.rp_filter = 1#严谨模式 1 (推荐)
#松散模式 0
net.ipv4.tcp_congestion_control = reno cubic#默认推荐设置是 htcp
net.ipv4.tcp_window_scaling = 0#关闭tcp_window_scaling
#启用 RFC 1323 定义的 window scaling;要支持超过 64KB 的窗口,必须启用该值 。
 net.ipv4.tcp_ecn = 0#把TCP的直接拥塞通告(tcp_ecn)关掉
net.ipv4.tcp_sack = 1#关闭tcp_sack
#启用有选择的应答(Selective Acknowledgment),
#这可以通过有选择地应答乱序接收到的报文来提高性能(这样可以让发送者只发送丢失的报文段);
#(对于广域网通信来说)这个选项应该启用,但是这会增加对 CPU 的占用 。
net.ipv4.tcp_max_tw_buckets = 10000#表示系统同时保持TIME_WAIT套接字的最大数量
net.ipv4.tcp_keepalive_probes = 3#如果对方不予应答,探测包的发送次数
net.ipv4.tcp_keepalive_intvl = 15#keepalive探测包的发送间隔
 
对于 TCP 连接来说稍微特别一些,除了 sk_rcvbuf 的限制之外,TCP 还有自己的一套 Socket 接收 Buffer 的限制机制,能根据系统当前所有 TCP 连接占用的总内存量判断系统压力级别,来决定是否能为某个 Socket 继续分配接收 Buffer 。这里要区分清楚的是 sk_rcvbuf 是 Socket 接收 buffer 分配的上限,而 Socket 当前实际分配的接收 buffer 大小是 sk_rmem_alloc 记录 。连接每次收到一个 sk_buff 放入 Socket 队列之后,就会增加 sk_rmem_alloc 并减少 sk_forward_alloc 的值,sk_forward_alloc 不够的时候就需要向系统申请配额 。如果系统上只有一个连接,那 Socket 分配的接收 Buffer 没有达到 sk_rcvbuf 之前,系统可能都会允许给这个连接继续分配接收 buffer 。但是如果系统上有几百万连接,占用了大量的内存,每个连接都分为 sk_rcvbuf 这么多接收 Buffer 的话系统可能会支撑不住,所以 TCP 的接收 Buffer 的限制机制就是在 Socket 的接收 Buffer 还未到达 sk_rcvbuf 之前就根据当前系统负载情况,在负载特别大的时候拒绝 Socket 扩大接收 buffer 的申请 。


推荐阅读