首页 > 编程知识 正文

java time类,javawaitnotify原理

时间:2023-05-04 01:55:22 阅读:60225 作者:3256

问题的原因是6电芯# s; y; ~7 w3 T8 Y3 k# W! W4 G

8 b ) k7 S- J# I

在此期间,我们调查了nacos,使用它作为dubbo的注册中心,而不是zookeeper,并使用了nacos的1.1.4版。 此外,还使用了nacos同步。 nacos提供的迁移工具允许您将常见注册中心服务与nacos同步。 这个不好用。 至少不是生产水平的工具。 但是,这与本文无关,我们将编写一篇文章,介绍此同步工具的优缺点,以及在生产水平上需要进行哪些改造。 开始测试的时候,总是服务奇怪地离线,找不到原因。 随后,在调查过程中,nacos发布了1.2.0-beta.0版,因此我们前往github查看了1.2.0-beat.0版的发行说明。 一个个修复的bugfix去review,重要的都merge放到调查版上,其中一个bugfix引起了我的注意。

: D$ d# u# ~4 F' G% n9 {; `2 v

; g: f2 X8 W! K

nacos Java客户端使用rest的http接口请求。 在这个bugfix上说

t'{}T8G; 当Kdubbo使用nacos注册中心时,dubbo的使用者端会建立大量TIME_WAIT状态的连接,占用大量端口,并为每个请求/心跳创建新连接,没有共享连接。 在javadoc看来,问题可能出在使用HttpURLConnection上。 每次请求时调用disconnect并关闭了连接。 4 Y$ x/i3 I. N1 g. q6? v

nacosSync服务器(本质上是去nacos客户端)检查连接状态)不在现场。 这是后来模拟的)。

* f; *w.y(O2L ),}1 Z

9 k* b3 `0 M! F/W% ]

1 ^: O0 p' ~$ Z* A然后查看了错误日志

2 G1 Q-? 7 hy Java.net.connect exception : can ' tassignrequestedaddress (connect failed ),这个错误造成了严重的问题,在服务经常下滑的欢呼声高涨的蓝天下8 Kt1 R; J4 j7 Z8 w! {

问题处理分析2 T0 M: o r ) V9 C: U

4 J7 n6 H5 x4 O0 o4 Z5 Z# Q# J; o将此issue的代码集成到调查版中,重新打包并重新启动nacosSync,仍然会减少TIME_WAIT的数量,经过几天的测试,nacos服务也不会无缘无故脱机。 问题解决起来很简单,为什么会发生这种事呢? 修复代码2 H/n' `# k; Y4 s

! lm! C6 A,u; Jj

8 x; L% s1 F- B' a Q

在Java Doc上是这么说的! t/[/z5 d; I' `1 x- a/s

eachttpurlconnectioninstanceisusedtomakeasinglerequestbuttheunderlyingnetworkconnectiontothehttpservermaybetransparentlyshareresharesharer ingtheclose (methodsontheinputstreamoroutputstreamofanhttpurlconnectionafterarequestmayfreeenetworkresourcesasssociatedwiththithithithisthisthisthisthid sharedpersistentconnection.callingthedisconnect (methodmayclosetheunderlyingsocketifapersistentconnectionionisotherwiseidleateattte 接下来介绍tcp建立连接的3次握手和断开连接的4次手。 以下内容主要来自聪明的信封《计算机网络》 (第7版)和对网上文章的理解。

6 [% z/M3 C5 O# B% @/}tcp次握手' z/d* L3 q' U. z7 o

$?u ) Rn' n. z d

如图所示,tcp建立连接的三次握手过程如下:

* W% v6 D R,P[ o f,G6 t2 z8 a4 T' kY4 J1 Q,b

>(1)开始时A处于关闭,B处于LISTEN状态,A发起建立连接的请求,发送SYN=1的报文段,初始序列号seq=x,A进入SYN-SENT状态6 T4 o; D/ y" ]6 I0 |9 |

(2)B收到请求报文后,同意建立连接,发送SYN=1,ACK=1的报文段,确认序列号为ack=x+1,同时B的初始序列号为seq=y,B进入SYN-RCVD状态( G$ C, ^0 D( w. O/ F

(3)当A收到B的确认后,也需要向B给出确认,ACK=1,seq=x+1,ack=y+1,此后A、B进入ESTABLISHED状态4 |! T- F, M+ q; Z$ M. k, ^然而tcp协议更需要考虑的是异常情况9 t! X. C* Z* r/ ?/ L# R- d* {

( @$ X! b3 A6 e" s0 m) n

(异常A)如果(1)中A发送报文时发生丢包导致B未收到,则A会重试,重试超时后,会进入CLOSED状态;7 w7 s% H9 d. z" g2 H  w/ B

(异常B)如果(2)收到A的请求,但未回复或者或者回复报文丢失,对A来说就是(异常A),如果B回复的报文丢失,即A收不到确认报文,也不会发生(3),此时B也会重试,超时后关闭这个连接;3 D4 [( ~5 u% i6 e- |

(异常C)A最后一个确认包丢失了,此时A已经进入ESTABLISHED状态,可以发送数据,B还是SYN-RCVD状态,此时如果B先收到A的数据包,则也会进入ESTABLISHED状态;如果A不发送最后一个确认包,也不发送数据,此时B处于“半连接”状态,会在重试几次(2)之后关闭连接,这就是“SYN FLOOD 攻击”。

2 L' e( o2 ]; O5 gtcp四次挥手

K& N: s3 s2 o0 m" N2 c$ U6 ]$ O0 f, R% c  |! N2 p* U

8 H. y' g' `; F) Z0 w6 Q* r. W2 m; w9 q% f

(1)开始A、B都处于ESTABLISHED状态,A主动关闭,发送FIN=1报文,seq=u,A进入FIN-WAIT-1状态;

* G3 X7 X) Z% E5 ~. a! W

(2)B收到关闭信号后,回复ACK=1,seq=v,ack=u+1,B进入CLOSE-WAIT状态,此时B还可以向A发送数据,A收到B的回复后进入FIN-WAIT-2状态;

" r; _  a$ ]- a, w5 X! E& G, q

(3)等B数据发送完毕后,向A发送可以关闭信号,FIN=1,ACK=1,seq=w,ack=u+1,B进入LAST-ACK状态;

1 E' ]: R6 }4 @6 A

(4)A收到B的关闭信号后回复确认,ACK=1,seq=u+1,ack=w+1,A进入TIME-WAIT状态,等待2MSL(即120秒)后进入CLOSED状态,B收到A的确认后进入CLOSED状态。

$ ^, c- Y& G, H) ^8 l; T异常情况:2 t0 M. @' b$ S( j

4 ~, E4 ~5 C5 Q

(异常A)A发起关闭信号进入FIN-WAIT-1,若B未回复,则会一直重试直到超时,超时后A直接关闭连接;

1 _4 E( g* h5 G4 z

(异常B)B回复A后进入CLOSE-WAIT状态,但没有发送下一个FIN报文,则B一直处于CLOSE-WAIT状态;/ [  c" |& D& j3 B1 c& z  y6 t8 ^6 ]4 {

(异常C)A收到B的ACK后进入FIN-WAIT-2状态,等待B的关闭,此时仍然可接收B的数据;理论上FIN-WAIT-2在未收到B的关闭请求前都是保持这个状态,但实际的实现却是有一个超时时间,linux默认是180秒,超时后直接关闭这个连接;

& F7 R- Q$ S# E. Q, B4 @

(异常D)B发送关闭连接报文FIN后进入LAST-ACK状态,但未收到回复,B会重复发送关闭请求,直到超时,超时后关闭该连接。

: F% ]1 D; L* T- [& C4 b1 j9 S' L  m由tcp的三次握手与四次挥手能得出如下结论:* g7 U; R9 Q9 r2 }) R

- N8 V. G( , @1 n# y

tcp之所以需要四次挥手是因为tcp连接是全双工,前两次挥手保证了A到B的关闭,后两次保证了B到A的关闭;! C- y: _/ L7 i  S

在客户端设置 TIME_WAIT 是为了保证最后一个ACK能大概率送达B,如果不等待2MSL直接关闭连接,同时ACK也丢失,那么B再重发的关闭请求就无法处理,B大概率会停留在LAST-ACK状态;

) q& @0 @  {. O7 w3 y

在没有攻击的情况下,容易出问题的是CLOSE-WAIT与TIME-WAIT状态;CLOSE-WAIT是服务端没有关闭连接,通常是代码中忘了关闭连接;TIME-WAIT出现则通常在客户端,客户端在短时间内发起了太多的连接,可以复用连接来解决该问题。; I8 k. L/ L* f3 I+ + f# H

如果出现其他中间状态较多的情况,可按上面的图进行分析,考虑是否存在攻击。

/ N4 ?+ x" R( T总结

3 j. O, K: i1 `5 Wd5 L3 P9 o3 C4 h1 r

7 t& @. `; e0 u) K/ c

在处理请求的客户端时需要注意使用短链接会可能会造成TIME_WAIT过多的情况;$ O4 `. B7 l1 Z, x0 M

在写代码的时候要注意可能会导致的异常情况,不使用的资源(包括但不限于连接)需要及时释放;

5 G, t, M) l8 U7 j( v, S: [; P

对于开源产品的使用需要多看github上的issue,尽量提前预知可能的问题,在下一个版本发布时,需要关注修复的bug以及推出的新功能。

) P% ]! N3 w, U0 C更多nacos相关文章推荐2 o$ Y* ]3 M1 Q0 h! W

; e/ l/ w3 u6 j; R$ d/ m* _

nacos的一致性协议distro介绍

0 [  v; U, c  r  n% |+ }+ }

: m8 B! v6 u6 Z/ SJava吧 收集整理 java论坛 www.java8.com

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