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