3

我们开发了一个基于 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 进程都被终止时,除了老板线程之外的所有 netty 线程似乎都被挂起。服务器正在接受连接请求,但在未发生的情况下进一步处理消息。当我们发现我们没有添加 MYSQL 的“connectTimeout”和“socketTimeout”值时,我们认为问题已经解决了。添加这些值后,我们再次尝试通过杀死负载下的所有 MYSQL 进程来重复我们的测试,我们没有发现任何线程进入挂起状态。

在生产中使用上述更改部署服务器后,我们遇到了类似的错误,但这一次,甚至老板线程以及所有其他“Netty”线程都进入了挂起状态。唯一工作的线程是来自我们 DBPool ( http://www.snaq.net/java/DBPool/ ) 的更干净的线程。没有 Netty 线程正在记录任何内容,并且所有线程似乎都被挂起。我无法获得线程转储。任何帮助都是可观的

谢谢

4

1 回答 1

1

Netty 处理程序不应该执行长阻塞操作,例如从数据库读取。按照http://netty.io/4.0/guide/#faq.4中的建议,从单独的线程中执行此操作

于 2013-07-02T16:15:39.300 回答