Netty源码阅读系列-重要参数backlog

973 阅读3分钟

「我正在参与掘金会员专属活动-源码共读第一期,点击参与

一、Netty中backlog参数的含义

Netty的channel配置中有一个NioChannelOption.SO_BACKLOG选项,这个参数值会在底层传递给Net.listen函数。

image.png 想搞清楚这参数的含义,可以参考一下linux手册中的解释

image.png

"The backlog argument defines the maximum length to which the queue of pending connections for sockfd may grow."

backlog参数代表了tcp全连接队列的长度。当tcp连接三次握手成功后,状态为ESTAB且该连接并没有被应用程序的accept()函数取走时,该连接就被放置在全连接队列中。

全连接队列容量不足时,新的ESTAB状态连接无处安放,就会造成连接失败。所以说该参数对程序并发性的影响还是很大的。

该参数不仅在应用程序中可以配置, 在内核参数中也有对应的配置。

在linux中相关的内核参数是net.core.somaxconn

image.png

二、实践中的注意事项

Netty程序backlog参数与内核参数不一致时会发生什么?

值得注意的是backlog的值在内核参数与程序参数不一致时会取两者的较小值。min(backlog, somaxconn)

Netty中backlog的默认值是什么?

通过追踪Netty源码,可以看到在linux环境下Netty的backlog默认值和"/proc/sys/net/core/somaxconn"中的配置是一致的。

image.png

image.png

image.png

如何验证backlog配置是否生效?

程序启动后监听了某个端口, 如何能看到该监听的全连接队列长度呢?

在linux环境中可以使用ss命令。

ss命令的第三列参数Send-Q就代表了accept queue的长度。

image.png

三、实测

针对backlog参数的配置做以下测试,验证对该参数的理解是否正确。

case内核参数Netty backlog参数预期aceetp queue大小
case1: Netty不设置backlog参数666不设置666
case2: Netty backlog参数大于内核参数128511128
case3: Netty backlog参数小于内核参数1024511511

case1

修改内核参数somaxconn为666

image.png

不设置Netty backlog参数

image.png

启动程序后ss -antl结果 (Netty程序监听端口为7777)

image.png

case2

修改内核参数somaxconn为128

image.png

设置Netty backlog参数为511

image.png 启动程序后ss -antl结果 (Netty程序监听端口为7777)

image.png

case3

修改内核参数somaxconn为1024

image.png

设置Netty backlog参数为511

image.png

启动程序后ss -antl结果 (Netty程序监听端口为7777)

image.png

测试结论

这三个case的测试结果都符合预期, 验证了以下结论(在linux环境下)

  1. accept queue长度取程序backlog参数和内核参数somaxconn的较小值。

  2. Netty中backlog的默认值和内核参数一致。

四、总结

backlog是个很重要的参数。

设置过小: accept queue达到容量上限后, 后续的连接无法成功建立, 会成为程序的并发瓶颈。

设置过大: 在处理性能不足时大量的连接积压会造成客户端超时,且连接积压时消耗更多的系统资源(例如内存)。

那如何设置backlog参数还是要根据程序的性能测试、QPS等综合考量, 实际应用中对该accept queue的状态保持关注适时调整。

使用时要注意仅仅在程序中配置backlog是不行的, 要关注内核参数(linux环境中是net.core.somaxconn),当两者不一致时最终实际生效的是两者较小的值。