2017-08-16 21 views
0

次のような状況があります。My Netty Serverは、クライアントからのデータを驚異的な速さで取得します。私はクライアントがその速度のために多少のプッシュメカニズムを使用していると思います。私は正確にPUSH - POPメカニズムが何であるか分かりませんが、クライアントが非常に高速でデータを送信するためのメカニズムを使用していると感じています。私の要件は、私は単純なTCP Nettyサーバークライアントであり、ArrayBlockingQueueを使用して実装されたBlockingQueueに追加されます。 Nettyがイベントベースであるため、データを受け入れてキューに格納するのにかかる時間はいくらか増えます。クライアント側でNettyサーバーが実行されていないという例外が発生しています。しかし、単一のデータを受け入れてキューに格納する時間はますます増えています。どうすればこれを防ぐことができますか?この状況で最速のキューがありますか?別のスレッドがキューからデータを取り出して処理するとき、私はBlockingQueueを使用して名前を付けます。だから、私は同期化されたキューが必要です。どのようにしてサーバーのパフォーマンスを向上させることができますか、または非常に高速にデータを挿入する方法はありますか?気にするのは待ち時間だけです。レイテンシは可能な限り低くする必要があります。JavaでNetty Serverのパフォーマンスを向上させる

マイServerコード:

public class Server implements Runnable { 
private final int port; 

static String message; 
Channel channel; 
ChannelFuture channelFuture; 
int rcvBuf, sndBuf, lowWaterMark, highWaterMark; 

public Server(int port) { 
    this.port = port; 
    rcvBuf = 2048; 
    sndBuf = 2048; 
    lowWaterMark = 1024; 
    highWaterMark = 2048; 
} 

@Override 
public void run() { 
    try { 
     startServer(); 

    } catch (Exception ex) { 
     System.err.println("Error in Server : "+ex); 
     Logger.error(ex.getMessage()); 
    } 
} 

public void startServer() { 
    // System.out.println("8888 Server started"); 
    EventLoopGroup group = new NioEventLoopGroup(); 
    try { 
     ServerBootstrap b = new ServerBootstrap(); 
     b.group(group) 
     .channel(NioServerSocketChannel.class) 
     .localAddress(new InetSocketAddress(port)) 
     .childOption(ChannelOption.SO_RCVBUF, rcvBuf * 2048) 
     .childOption(ChannelOption.SO_SNDBUF, sndBuf * 2048) 
     .childOption(ChannelOption.WRITE_BUFFER_WATER_MARK, new WriteBufferWaterMark(lowWaterMark * 2048, highWaterMark * 2048)) 
     .childOption(ChannelOption.TCP_NODELAY, true) 

      .childHandler(new ChannelInitializer<SocketChannel>() { 

        @Override 
        public void initChannel(SocketChannel ch) throws Exception { 
         channel = ch; 
         System.err.println("OMS connected : " + ch.localAddress()); 
         ch.pipeline().addLast(new ReceiveFromOMSDecoder()); 
        } 
       }); 
     channelFuture = b.bind(port).sync(); 
     this.channel = channelFuture.channel(); 
     channelFuture.channel().closeFuture().sync(); 

    } catch (InterruptedException ex) { 
     System.err.println("Exception raised in SendToOMS class"+ex); 
    } finally { 
     group.shutdownGracefully(); 
    } 
} 

}

マイServerHandlerコード:

@Sharable 
public class ReceiveFromOMSDecoder extends MessageToMessageDecoder<ByteBuf> { 


    private Charset charset; 
    public ReceiveFromOMSDecoder() { 
     this(Charset.defaultCharset()); 
    } 

    /** 
    * Creates a new instance with the specified character set. 
    */ 
    public ReceiveFromOMSDecoder(Charset charset) { 
     if (charset == null) { 
      throw new NullPointerException("charset"); 
     } 
     this.charset = charset; 
    } 

    @Override 
    protected void decode(ChannelHandlerContext ctx, ByteBuf msg, List<Object> out) throws Exception { 

     String buffer = msg.toString(charset); 
     if(buffer!=null){ 
     Server.sq.insertStringIntoSendingQueue(buffer); //inserting into queue 
     } 
     else{ 
      Logger.error("Null string received"+buffer); 
     } 
    } 
     @Override 
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) { 
     // Logger.error(cause.getMessage()); 
     System.err.println(cause); 
    } 
} 
+0

複数の問題があると思われるため、この質問を「あまりにも広い」と締めくくっています。コンテキストから抜け出す問題の1つは、クライアントまたはサーバー側で例外がスローされ、もう1つの問題はパフォーマンスの問題です。パフォーマンスの問題は、それ自体も大きく、多くの原因があります。大量のデータを受信すると予想される場合は、すべてのプロトコルデータを文字列として残すとすぐに問題が発生し、すべてのパケットをサーバークラスに直接渡すと、スレッドの競合を見るときにオーバーヘッドが発生します – Ferrybig

答えて

1

三短時間セックス:あなたが送信しているよう

  1. が見えません応答。あなたはおそらくすべきです。
  2. IOスレッドをブロックしないでください。 EventExecutorGroupを使用して、着信ペイロードの処理をディスパッチします。すなわちChannelPipeline.addLast(EventExecutorGroup group, String name, ChannelHandler handler)のようなものです。
  3. 一般的にブロックしないでください。 ArrayBlockingQueueを捨てて、JCToolsやその他の実装を見て、非ブロッキングアナログを見つけてください。
+0

ありがとうNicholas。現在、ArrayBlockingQueueではなくConcurrentLinkedQueueを使用しています。 JCToolsでサンプルのサンプルを見つけることができませんでした。私はそれを使用することに非常に混乱しています。私は図書館を通り、SPSCのキューが私のデザインのものであることを知りました。しかし、私はそれを使う方法を知らない。図書館や資料の使用例をいくつか教えてください。 –

+0

hema;私はJCToolsに別の質問をします。 – Nicholas

関連する問題