赞
踩
主动方: 发送fin进入fin_wait1,收到fin的ack进入fin_wait2,发送fin时接收缓冲区还有数据 - 应用层不读数据你就close?发reset告知对端你出问题了
默认:linger关闭,close调用立即返回(发出发送缓冲区未发出数据和fin后)
linger开启,linger时间为0: close立即返回,丢弃发送缓冲区未发出数据,发reset,自己立即关闭连接
linger开启,linger时间大于0: close等待fin的ack或超时到来,发送缓冲区未发出数据会发的,若close是超时返回会发reset
注意:若发送缓冲区有数据-末尾数据加fin状态,否则单独放置fin,close/write/内核定时器都会尝试发送数据,但尝试可能受各种原因(拥塞窗口)失败
发送缓存区有数据未发?一般很少,可能小包批量发微微延迟,或者受拥塞控制
接收缓存区有数据未ack?一般很少,可能批量或混在发送包里微微延迟
被动方:收到fin-很快会回ack,进入close_wait(等待应用层调用close),此时应用层可读可写,但终归会读到fin/eof,
读到后应该主动调用close,进入last_ack且等待ack后进入closed, 注意长期处于close_wait一般是应用层写的不好(没有去读,读到eof也不close)
主动方不会长期fin_wait2:收到fin进入time_wait+2msl后自动closed 或 tmo+2msl后自动closed
read只要有数据立即返回,write需缓冲区能完全放下数据才返回(特例:当write正阻塞等待时对面关闭了socket,则write则会立即将剩余缓冲区填满并返回所写的字节数)
进程异常终止(OS代发fin)/进程调用close(close同时关闭发送和接收), tcp层不能收数据(会回应reset)
进程调用shutdown(选择关闭发送+不关闭接收-依然发fin),tcp和应用层还能读取数据
reset发出端和接收端都会立即释放连接,状态置为closed
对收到reset的socket调用write会收到sigpipe信号-默认终止进程/不少程序会捕捉这个信号,比如抛异常connection reset by peer等,调用read也会报错
一端退出另一端能否感知:
https://blog.csdn.net/mxt51220/article/details/126705935
https://segmentfault.com/q/1010000040681423/a-1020000040681501
https://blog.csdn.net/weixin_28841265/article/details/114338114
客户端退出mysql服务端的感知和处理:
User thread 处于read process write循环中
read:wait_timeout/tcp层关闭(tcp keepalive/连接关闭)
write: tcp层关闭/超时重传 注意write只要发送缓冲区空间足够即可返回,超时重传带来的问题反而只能在read中发现,具体可见https://blog.csdn.net/hellozhxy/article/details/128792609
process: 不受连接影响
失败处理: 回滚事务+释放事务关联的锁,释放资源如release_lock
liquibase应用退出lock释放优化:
get_lock 多条changelog release_lock release_lock和事务无关
事务 select for update 多条changelog 事务提交 单独select for update自成事务-锁自动释放,故需配合事务使用
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。