我们开发了一个基于Netty(3.5.11)的IM服务器,它使用我们的自定义协议。
以下是处理程序添加到管道的顺序。
objChannelPipeline.addLast("nettyLoggingHandler", objFrameworkLoggingHandler);
objChannelPipeline.addLast("ipFilter", objCustomIPFilterHandler);
objChannelPipeline.addLast("idleHandler", objIdleStateHandler);
objChannelPipeline.addLast("loggingHandler", objLoggingHandler);
objChannelPipeline.addLast("frameDecoder",objDelimiterBasedFrameDecoder);
objChannelPipeline.addLast("messageDecoder", new CustomProtocolDecoderHandler());
objChannelPipeline.addLast("groupOrder", executionHandler);
objChannelPipeline.addLast("ProtocolMultiplexer", objRegistrationHandler);
在我们从客户端获得的注册消息中找到协议后,“ProtocolMultiPlexer”处理程序被替换为合适的“ProtocolHandler”。
ipFilterHandler查看MYSQL数据库中的一个表,该表包含列入黑名单的IP,并决定是否要处理来自远程IP的连接。
问题:每隔几天后,服务器就会停止处理任何消息。我们可以通过执行负载测试并终止与mysql服务器的所有连接来重新创建此问题。当所有MYSQL进程被杀死时,除了boss线程之外的所有netty线程似乎都挂起了。服务器正在接受连接请求,但是进一步处理没有发生的消息。当我们发现我们没有添加MYSQL“connectTimeout”和“socketTimeout”值时,我们认为问题已经解决了。 添加这些值之后我们再次尝试通过在加载时杀死所有MYSQL进程来重复我们的测试,我们没有发现任何线程进入挂起状态。
在生产中使用上述更改部署服务器之后,我们遇到了类似的错误,但这次,即使老板线程与所有其他“Netty”线程一起进入挂起状态。唯一正在运行的线程是来自我们的DBPool(http://www.snaq.net/java/DBPool/)的更干净的线程。没有Netty线程记录任何内容,所有线程似乎都挂起了。我无法获得线程转储。 任何帮助都很明显
谢谢