记录一次TCP ZeroWindow问题

243 阅读1分钟

环境介绍

  • java项目maven打包
  • netty版本:4.1.77
  • docker部署运行
  • 服务器系统:centos7

应用架构

简单.png

业务应用与netty-server

两者之间用http进行通信

netty-server与netty-client

两者之间用tcp进行通信

问题

抓包发现,netty-server会发送TCT ZeroWindow 给netty-client,最终导致netty-client会掉线(netty-server(80.80.84.11),netty-client(24.46.28.25))

微信截图_20240202094343.png

解决

TCP ZeroWindow 出现的原因

netty-server 处理数据的能力跟不上netty-client发送数据的速度,导致滑动窗口(win)=0,从而就会发送 TCP ZeroWindow 给netty-client 让其暂时不要发送数据,等滑动窗口(win)>0时,再发送数据

排查思路

  1. netty-server 服务器性能不行,加资源(我这是测试阶段,只接了一个netty-client,所以不会是服务器性能不行)
  2. netty-server 处理数据慢,长时间没释放资源,导致滑动窗口(win)=0

定位问题

netty-server只负责通信部分,并不负责业务处理,所以当netty-server收到netty-client发送的数据后,会调用【应用程序】的http接口,把数据发送给【应用程序】,如果这个http处理速度慢,就会导致netty-server资源不释放,从而导致滑动窗口(win)=0

问题代码

@Component
@Slf4j
public class TaskHandler extends ResponseHandler {
    
    @Autowired
    private IDataFeign dataFeign;
    
    @Override
    public Nettyresponse doWork(ReceiveMessage message, ChannelHandlerContext ctx) {
        log.inf("数据接收完成;{}", message);
        
        // 调用【应用程序】http接口(主要问题就在这里,这里应该采用异步调用)
        dataFeign.taskControl(message);
        
        return new NettyResponse();
    }
}