前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP(二)

TCP(二)

作者头像
在周末
发布2019-08-26 17:54:23
4170
发布2019-08-26 17:54:23
举报
文章被收录于专栏:在周末的专栏在周末的专栏

TCP半连接和全连接问题

TCP握手过程详解

如上图所示,关键部分:syns queue(半连接队列)和accept queue(全连接队列)

正常情况下的处理过程如下:

1)当server端收到client发送的SYN后,将连接相关信息放在syns queue中,并回复SYN+ACK;

2)当server端收到client发送的ACK后,将连接相关信息从syns queue中取出并放在accept queue中。

异常情况:

步骤2)中如果accept queue满了,则根据tcp_abort_on_overflow指定的策略执行

  如果tcp_abort_on_overflow为0,server丢弃client发送的ack,并且在一段时间后再次发送syn+ack给client(即重新走握手的第二步),如果cilent的超时时间比较短,就会出现异常;重试次数由net.ipv4.tcp_synack_retries指定(centos默认5次);

  如果tcp_abort_on_overflow为1,server将发送一个reset给client,表示要废掉这次握手过程和连接。此时client应该会出现connection reset by peer异常。

怎么查看队列是否满?

netstat -s

  该命令查看每个协议的统计数据

netstat -s | egrep "listen"

  如果看到:XXXX times the listen queue of a socket overflowed 并且XXXX 值在不断增加,就说明有全连接队列偶尔满了。

ss -lnt | grep port

State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 50 :::9188 :::*

其中Send-Q为监听9188端口的全连接队列最大为50,Recv-Q表示全连接队列中和等待进入全连接的数量。

全连接队列的大小取决于:min(backlog, somaxconn) . backlog是在socket创建的时候传入的(Java Socket默认为50),somaxconn是一个os级别的系统参数

半连接队列的大小取决于:max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog)。 不同版本的os会有些差异.

CLOSE-WAIT问题

什么情况下会出现CLOSE-WAIT状态

  在被动关闭连接时,已经收到对方发来的FIN(并发送了ACK),但还没有发送自己的FIN时,处于CLOSE_WAIT状态。

正常情况下该状态持续的时间应该很短,出现大量close_wait的现象,主要原因是某种情况下对方关闭了socket链接,但是我方忙与读或者写,没有关闭连接。

产生该问题的例子:https://blog.csdn.net/yu616568/article/details/44677985

  首先,我这边的大部分请求都需要查询数据库,我的数据库连接池设置的最大连接数是100,所以每一个请求创建了一个连接,等到100个请求就把连接池占满了,但是处理servlet的那个线程并没有释放这个连接,于是接下来的请求再去创建数据库连接的时候就会一直阻塞在那里,这里我所用的是DBCP作为连接池的,它的实现好像是使用apache的objectPool来实现的,如果没有可用的连接对象会导致线程等待,好了,servlet由于得不到数据库连接而阻塞了,这个客户端的请求就一直等待,客户端使用httpclient设置了5s的请求超时时间,那么超时之后就会抛出异常,关闭连接,关闭连接导致客户端发送了FIN报文,我这边的TCP/IP返回了ACK报文,但是由于处理请求的线程还处于阻塞的状态,所以当前的连接状态时CLOSE_WAIT。

解决方法 基本的思想就是要检测出对方已经关闭的socket,然后关闭它

1.代码需要判断socket,一旦read返回0,断开连接,read返回负,检查一下errno,如果不是AGAIN,也断开连接。(注:在UNP 7.5节的图7.6中,可以看到使用select能够检测出对方发送了FIN,再根据这条规则就可以处理CLOSE_WAIT的连接) 2.给每一个socket设置一个时间戳last_update,每接收或者是发送成功数据,就用当前时间更新这个时间戳。定期检查所有的时间戳,如果时间戳与当前时间差值超过一定的阈值,就关闭这个socket。 3.使用一个Heart-Beat线程,定期向socket发送指定格式的心跳数据包,如果接收到对方的RST报文,说明对方已经关闭了socket,那么我们也关闭这个socket。 4.设置SO_KEEPALIVE选项,并修改内核参数

TCP协议在带宽利用率、性能方面的优化

delay ack

Nagle算法

参考资料

服务器TIME_WAIT和CLOSE_WAIT详解和解决办法

CLOSE_WAIT状态的原因与解决方法

关于TCP 半连接队列和全连接队列

就是要你懂 TCP | 最经典的TCP性能问题

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-06-22 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
数据库
云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档