首页 > 编程知识 正文

java线程wait,javawaitnotify原理

时间:2023-05-03 08:26:57 阅读:60234 作者:4174

以下命令经常用于服务器的日常维护:

netstat-n|awk‘/^ TCP/{ s [ $ nf ] } end { for (ains ) print a,S[a]}

其中$NF表示最后一个字段

例如,将显示以下信息:

TIME_WAIT 814

CLOSE_WAIT 1

FIN_WAIT1 1

ESTABLISHED 634

SYN_RECV 2

LAST_ACK 1

三种常用状态是: ESTABLISHED表示正在通信,TIME_WAIT表示主动关闭,CLOSE_WAIT表示被动关闭。

更具体地说,挥手4次的交互过程如下。

客户端先发送FIN,进入FIN_WAIT1状态

服务端接收FIN,发送ACK,进入CLOSE_WAIT状态,客户端接收此ACK,进入FIN_WAIT2状态

服务端发送FIN,进入LAST_ACK状态

客户端接收FIN,发送ACK,进入TIME_WAIT状态,服务端接收ACK,进入CLOSE状态

客户端TIME_WAIT持续两倍的MSL时间,在linux体系中约为60s,转移到关闭状态

发送ACK后,可以不进入TIME_WAIT而直接设为关闭状态吗? 不,这是因为TCP协议的可靠性。 由于网络原因,ACK的发送可能会失败。 这样的话,被动方会再次重新发送FIN。 此时,如果主动侧为TIME_WAIT状态,则再次发送ACK以保证可靠性。 那么,根据这个说明,可以理解2MSL的时间长度的设定。 MSL是消息的最大生存时间,如果重发,加上一个FIN个ACK,再加上不定期的延迟时间,大致在2MSL的范围内。

如果服务器发生异常,80%的情况有以下两种:

1 .服务器维持了大量的TIME_WAIT状态

2 .服务器保持了大量的CLOSE_WAIT状态

由于linux分配给单个用户的文件句柄有限,因此如果同时保持TIME_WAIT和CLOSE_WAIT状态,则表示相应数量的通道仍然被占用,如果达到字符上限,则处理新请求

1 )服务端的时间等待太多

首先,我将介绍长连接和短连接。 HTTP1.1协议具有连接标头。 连接有两个值:关闭和保持活动。 此标头相当于在服务器端执行请求后,告知服务器端是关闭连接还是保持连接。 如果服务使用短连接,则每当客户端请求时,服务都会主动发送FIN以关闭连接。 最后进入time_wait状态。 在访问数多的web服务器中,可以考虑存在大量的TIME_WAIT状态。 允许服务快速回收TIME_WAIT资源并更改内核参数。

将/etc/sysctl.conf修改如下:

#对于新连接,内核发送的SYN连接请求数不应大于255。 默认值为5,对应于180秒左右的时间

net.ipv4.tcp_syn_retries=2

#net.ipv4.tcp_synack_retries=2

显示启用#keepalive时,TCP发送keepalive消息的频率。 默认值为2小时,更改为300秒

net.IP v4.TCP _ keepalive _ time=1200

net.ipv4.tcp_orphan_retries=3

如果本地请求关闭套接字,则此参数决定了保持双赢- 2状态的时间

net.ipv4.tcp_fin_timeout=30

#表示SYN队列的长度,默认值为1024,队列长度为8192可以增加等待连接的网络连接数。

net.IP v4.TCP _ max _ syn _ backlog=4096

#表示要打开SYN Cookies。 如果发生SYN队列溢出,可以启用和处理cookies以防止少量SYN攻击。 默认值为0,表示关闭

net.ipv4.tcp_syncookies=1

#表示打开重用。 允许将时间等待套接字重用到新的TCP连接。 默认值为0,处于关闭状态

net.ipv4.tcp_tw_reuse=1

#表示打开TCP连接的时间等待套接字的快速回收,默认值为0表示关闭

net.ipv4.tcp_tw_recycle=1

#减少超时前的探测次数

net.IP v4.TCP _ keepalive _ probes=5

#优化网络设备的接收队列

net.core.net dev _ max _ backlog=3000

更改完成后,运行/sbin/sysctl -p使参数生效。

2 ) close_wait

如果仍为CLOSE_WAIT,则在对方关闭连接后,服务器程序本身可能没有发出更多的FIN信号。 常见原因是TCP连接未调用关闭方法。 换句话说,对方的连接关闭后,程序没有检测到,或者忘记了程序需要在这个时候关闭连接,这个资源仍然被程序占用。 服务器内核参数也无法解决这种情况。 服务器对程序侵占的资源没有积极回收的权利。 在一定程度上,操作系统会使用TCP的KeepAlive功能自动清理CLOSE_WAIT连接,除非您中止程序的运行。

但实际上,由于主要是我们的程序代码有问题,通常是以下问题。

当对方调用closesocket时,你的程序

c代码

intnret=recv(s,……;

if(nret==socket_error ) )。

{

//closesocket(s;

返回假;

}很多人都忘记了那个closesocket

如果主动关闭的一方发送FIN要求被动关闭此处,被动关闭此处的TCP将立即响应一个ACK,同时向上的APP应用程序提交一个ERROR

上面的SOCKET的send或recv会导致返回SOCKET_ERROR。 通常,如果在上面返回SOCKET_ERROR后调用closesocket,则被动关闭侧的TCP会发送一个FIN,其状态将转换为LAST_ACK。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。