TCP backlog的解读

TCP backlog参数

介绍

  • 在实际生产环境中使用netty的过程中,遇到了一个奇怪的坑,就是backlog参数,明明设置得很大了,但是还是不生效,使得server在TCP连接数上来的时候,就会发送ECONNREFUSED给client以示拒绝。
  • 这触及到我的知识盲区,因此我决定加以探索并且记录、分享。我从底层、应用层两个层面进行分析,并最终定位到了这个问题,且加以解决。

底层

backlog参数主要用于底层方法int listen(int sockfd, int backlog), 在解释backlog参数之前,我们先了解下tcp在内核的请求过程,其实就是tcp的三次握手:

img

  • 握手过程:
    • client发送SYN到server,将状态修改为SYN_SEND,如果server收到请求,则将状态修改为SYN_RCVD,并把该请求放到syns queue队列中。
    • server回复SYN+ACK给client,如果client收到请求,则将状态修改为ESTABLISHED,并发送ACK给server。
    • server收到ACK,将状态修改为ESTABLISHED,并把该请求从syns queue中放到accept queue。

因此,在系统内核中,会维护两个队列,syns queueaccept queue

syns queue

用于保存半连接状态的请求,其大小通过/proc/sys/net/ipv4/tcp_max_syn_backlog指定,一般默认值是1024,这个参数涉及到一著名的TCP SYN FLOOD恶意DOS攻击方式就是建立大量的半连接状态的请求,然后丢弃,导致syns queue不能保存其它正常的请求,从而攻击你的系统。

accept queue

用于保存全连接状态的请求,其大小通过/proc/sys/net/core/somaxconn指定,在使用listen函数时,内核会根据传入的backlog参数与系统参数somaxconn,取二者的较小值。如果accpet queue队列满了,server将发送一个ECONNREFUSED错误信息Connection refused到client。

应用层

查看netty中的实现代码:

SOMAXCONN = AccessController.doPrivileged(new PrivilegedAction<Integer>() {
   
    @Override
    public Integer run() 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值