Q: 网络编程中listen()函数backlog的理解?
A:根据实际经验, 在大量并发连接的服务器上, 这个参数必须设置得比较大, 如1024或者10240或者更大, 否则客户端会频繁收到connection refused的错误. 有时候, 我们情愿客户端排队等待几秒钟, 而不是让客户端立即报一个连接失败的错误. 所以, 大部分情况下backlog参数要设置得比较大, 而不是使用默认的.
RE:嗯,我的说法不严谨,通常情况下不用设置,如果是在高并发的服务器上那么需要设置(具体到达什么样的临界连接量时会出问题,我没有测试过,老兄你有相关的测试吗?分享一下如何),但只设置listen中的backlog用处是不大的。因为backlog不能大于系统预定义的SOMAXCONN,如果backlog比SOMAXCONN将被重置为SOMAXCONN,这个值默认为了128,你说的这种情况应该同修改net.core.somaxconn并把backlog设置为SOMAXCONN。
A:是的, 要同时修改 net.core.somaxconn, 我们一般改为数十万. 根据经验, 我们有一类纯内存操作的服务器是单进程单线程IO多路复用模式的, 因为每一次内存操作都很快, 所以即使是单线程的server也能达到数万qps.但服务器的并发很高, 每秒会有1000+连接, 都是短连接. 所以, 如果偶尔有一两个请求比较慢, 如达到100ms时, 就会堆积至少100个连接等待accept. 这时, 如果backlog太小, 就会有很多客户端连接失败. 但因为是突发的慢请求, 而且机率很小, 所以不希望客户端连接失败, 而是排队等待, 所以要把backlog设置很大.
Q:总算明白了tcp/ip协议listen函数中backlog参数的含义。
RE:linux的实现是不一样的,在Linux下,backlog指定的是complete queue的大小,而incomplete queue的大小可以由系统管理员在 /proc/sys/net/ipv4/tcp_max_syn_backlog下进行统一配置。
你可以看一看这篇文章。http://veithen.github.io/2014/01/01/how-tcp-backlog-works-in-linux.html