java golang tcp socket导致线上服务器出现大量close_wait的完整示例

本文通过实例演示了Java和Golang中TCP连接导致服务器出现大量close_wait状态的原因,解释了TCP四次挥手过程,并提供了调整代码以正确关闭连接的方法。当在服务端不调用close函数时,连接将保持close_wait状态,直至系统文件描述符资源耗尽,引发'too many open files'异常。通过监控TCP连接状态并确保及时关闭连接,可以避免此类问题。
摘要由CSDN通过智能技术生成

tcp断开连接的四次挥手

先说说tcp的四次挥手,这里假定A端为主动发起关闭端,B端为被动接收关闭请求端。A把tcp的数据包中标识位FIN置为1,seq为一个随机数,发送这个包给B端,自己进入FIN_WAIT_1状态;B端收到了马上给A端回复ack(A端收到ack进入FIN_WAIT_2状态),然后自己进入CLOSE_WAIT状态。然后这个时候需要业务代码处理,把自己需要发给客户端的数据发送完,然后业务代码主动调用相应语言库函数提供的close函数,来触发关闭操作:给A端发送FIN seq的数据包,这是第三次握手。这个时候自己进入last ack状态。 A端此时收到包然后给B端口发送相应ack.A端自己此时进入time_wait状态。 B端收到ack后从last_ack就顺利进入close状态了。A端等到timewait 2msl时间后(这个时间不同的操作系统的设置不同,大约是2分钟),自动进入close状态。

如果在B端不主动调用相应自己语言的close函数,那么就会一直处于close wait状态。大量socket连接不能正常释放。直到socket服务器端打开的文件数超过系统的最大限制数,其他连接无法正常建立连接,建立连接的时候抛出too many open files异常

网上搜索的图,便于理解(侵删)

https://i-blog.csdnimg.cn/blog_migrate/8f99a43e7203eaa2b238c08c38c53d12.jpeg

linux 统计tcp连接的各种状态的连接数

这里每5秒输出一次 可以修改为自己想要的时间

 while true ;do  netstat -n | awk '/^tcp/ {++S[$NF]} END {for(a in S) print a, S[a]}' && print '-------------' ; sleep 5; done;

java版本的完整复现代码

只需要把Server.java中socket.close();这行注释掉就能观察到系统的close_wait 状态的tcp连接会一直无法释放,而打开这行注释,tcp连接即可正常关闭

Server.java

/**
 * @auther zhoudazhuang
 * @date 19-5-20 17:44
 * @description
 */

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Phaser;


public class Server {
    static class Worker implements Runnable {
        Socket socket;
        Phaser phaser;
        Worker(Socket socket,Phaser phaser){
            this.socket = soc
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值