TCP/IP的底层队列

本文深入探讨了TCP/IP的底层队列,包括建立连接时的半连接队列和全连接队列,以及接收报文时的receive、outoforder、prequeue和backlog队列。阐述了这些队列在处理并发请求、防止阻塞IO线程中的重要作用,并通过多个场景分析了接收报文的处理流程。
摘要由CSDN通过智能技术生成

                                    TCP/IP的底层队列

我自己比较了解Java语言,对Java网络编程的理解就止于Netty框架的使用。 Netty的源码贡献者Norman Maurer对于Netty网络开发有过一句建议,"Never block the event loop, reduce context-swtiching"。也就是尽量不要阻塞IO线程,也尽量减少线程切换。我们今天只关注前半句,对这句话感兴趣的同学可以看一下蚂蚁通信框架实践

为什么不能阻塞读取网络信息的IO线程呢?这里就要从经典的网络C10K开始理解,服务器如何支持并发1万请求。C10K的根源在于网络的IO模型。Linux 中网络处理都用同步阻塞的方式,也就是每个请求都分配一个进程或者线程,那么要支持1万并发,难道就要使用1万个线程处理请求嘛?这1万个线程的调度、上下文切换乃至它们占用的内存,都会成为瓶颈。解决C10K的通用办法就是使用I/O 多路复用,Netty就是这样。

Netty有负责服务端监听建立连接的线程组(mainReactor)和负责连接读写操作的IO线程组(subReactor),还可以有专门处理业务逻辑的Worker线程组(ThreadPool)。

    三者相互独立,这样有很多好处。一是有专门的线程组负责监听和处理网络连接的建立,可以防止TCP/IP的半连接队列(sync)和全连接队列(acceptable)被占满。二是IO线程组和Worker线程分开,双方并行处理网络I/O和业务逻辑,可以避免IO线程被阻塞,防止TCP/IP的接收报文的队列被占满。当然,如果业务逻辑较少,也就是IO 密集型的轻计算业务,可以将业务逻辑放在IO线程中处理,避免线程切换,这也就是Norman Maurer话的后半部分。

 TCP/IP怎么就这么多队列啊?今天我们就来细看一下TCP/IP的几个队列,包括建立连接时的半连接队列(sync),全连接队列(accept)和接收报文时的receive、outoforder、prequeue以及backlog队列。

 

建立连接时的队列

 如上图所示,这里有两个队列:syns queue(半连接队列)和accept queue(全连接队列)。三次握手中,服务端接收到客户端的SYN报文后,把相关信息放到半连接队列中,同时回复SYN+ACK给客户端。  第三步的时候服务端收到客户端的ACK,如果这时全连接队列没满,那么从半连接队列拿出相关信息放入到全连接队列中,否则按 tcp_abort_on_overflow的值来执行相关操作,直接抛弃或者过一段时间在重试。

 

接收报文时的队列

    相比于建立连接,TCP在接收报文时的处理逻辑更为复杂,相关的队列和涉及的配置参数更多。

应用程序接收TCP报文和程序所在服务器系统接收网络里发来的TCP报文是两个独立流程。二者都会操控socket实例,但是会通过锁竞争来决定某一时刻由谁来操控,由此

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

haikuotiankongdong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值