2017-01-15 7 views
-1

ネットワークサーバーにNetty 3.10.5-finalを使用しています。サーバーには約100台のクライアントが同時に存在します。 サーバが "遅れ"し始め、パケットの送信を停止しますが、着信接続を引き続き受け入れます。Netty 3.10.5-final "lags"

public class ClientListener { 
/** 
* NIO server that processes requests between login and game servers. 
*/ 
protected NettyServer gameServerListener; 
/** 
* Client packets executor. 
*/ 
protected final Executor packetsExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2); 
ExecutorService bossExec = new OrderedMemoryAwareThreadPoolExecutor(1, 400000000, 2000000000, 60, TimeUnit.SECONDS); 
ExecutorService ioExec = new OrderedMemoryAwareThreadPoolExecutor(4 , 400000000, 2000000000, 60, TimeUnit.SECONDS); 

private String serverName; 
private String bindIp; 
private int port; 

public ClientListener(String serverName, String bindIp, int port) { 
    this.serverName = serverName; 
    this.bindIp = bindIp; 
    this.port = port; 
} 

public void start() { 
    gameServerListener = new NettyServer(serverName, bindIp, port); 
    gameServerListener.setChannelFactory(new NioServerSocketChannelFactory(bossExec, ioExec)); 
    gameServerListener.setPipelineFactory(new ClientPipeline(packetsExecutor)); 
    gameServerListener.setOption("child.bufferFactory", new HeapChannelBufferFactory(ByteOrder.LITTLE_ENDIAN)); 
    gameServerListener.setOption("tcpNoDelay", true); 
    gameServerListener.setOption("child.tcpNoDelay", true); 
    gameServerListener.setOption("child.keepAlive", true); 
    gameServerListener.setOption("readWriteFair", true); 
    gameServerListener.startServer(); 
} 

NettyServerクラスはServerBootstrapのための単純なラッパーです: これは私が、サーバーを起動するために使用しているコードです。

最初に、IO Executerがイベント/メモリ制限に達した可能性があり、制限を0に置き換えました。これはまったく制限がないことを意味します。これは問題を解決しません。 それから、私はクライアント・パケット用に異なるエグゼキュータを使用しようとしましたが、それはあまり役に立ちません。 私のチャンネルの実装はSimpleChannelHandlerを拡張しており、内部には同期がないので、このバージョンも捨てました。 私はこれ以外に "遅れ"を引き起こす可能性のあるアイデアは持っていません。

+0

プロファイラを接続し、IOスレッドがブロックされていないことを確認しましたか? –

+0

@NormanMaurerはい、添付のプロファイラです。これで、私はChannelHandlerのmessageReceivedメソッドでデータベース操作を呼び出すことができたことが分かりました。データベースが長いクエリを実行していたとき、これはIOスレッドをブロックする可能性があります。今のところ、すべてがうまくいくように見え、プロファイリングを続ける。 – NewJ

答えて

1

解決策が見つかりました。

問題は、私がChannelHandlerのchannelDisconnectedメソッドでデータベース操作を呼び出していたためでした。データベースが長いクエリを実行していたとき、これはIOスレッドをブロックし、ネットワークの開始が遅くなる可能性があります。

私のケースでは、私はIOスレッドの外ですべてのデータベース操作を除外し、それが助けになりました。