我正在編寫一個基於Netty的本地HTTP服務器。當我進行壓力測試時,我受限於400個請求/秒。Netty應用程序優化
爲了優化我的服務器,我編寫了一個基於Netty的簡單服務器,它只是向客戶端發送「Hello World」,並且我使用Gatling 2啓動了一個壓力測試,並且使用此服務器,相同的結果(限於400次/秒)。
我使用Yourkit進行分析,沒有額外的GC活動,並且我的開放/關閉套接字被限制爲480個套接字/秒。
我使用MacBook Pro,有4個內核,16 GB的RAM,我使用Netty 4.1。
由於其他基準測試的結果顯示> 20 000請求/秒或更多,我很驚訝被限制在400請求/秒。我知道有硬件限制,但是對於在4核+16 GB Ram上發送「hello World」的請求數是400 req/s非常低。
非常感謝您的幫助,我不知道從哪裏開始優化我的Netty代碼。
有沒有優化Netty的具體指導方針?
這裏我的Hello World服務器的源代碼,然後我連接的處理程序:
public class TestServer {
private static final Logger logger = LogManager.getLogger("TestServer");
int nbSockets = 0 ;
EventLoopGroup pool = new NioEventLoopGroup() ;
private void init(int port) {
EventLoopGroup bossGroup = new NioEventLoopGroup(100) ;
try {
long t1 = System.currentTimeMillis() ;
ServerBootstrap b = new ServerBootstrap().group(bossGroup);
b.channel(NioServerSocketChannel.class)
.childHandler(new ChannelInitializer<SocketChannel>() {
@Override
public void initChannel(SocketChannel ch) throws Exception {
ch.pipeline().addLast("decoder", new HttpRequestDecoder(8192, 8192 * 2,
8192 * 2));
ch.pipeline().addLast("encoder", new HttpResponseEncoder());
ch.pipeline().addLast(new TestServerHandler(TestServer.this));
}
@Override
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
System.err.println("Error");
super.exceptionCaught(ctx,cause);
}
})
.option(ChannelOption.SO_BACKLOG, 100000)
.option(ChannelOption.SO_KEEPALIVE,false)
.option(ChannelOption.TCP_NODELAY,false)
.option(ChannelOption.SO_REUSEADDR,true)
.option(ChannelOption.CONNECT_TIMEOUT_MILLIS,10000)
.childOption(ChannelOption.SO_KEEPALIVE, true);
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(2);;
scheduler.scheduleAtFixedRate(new Runnable() {
@Override
public void run() {
System.err.println(nbSockets);
nbSockets = 0 ;
}
},1, 1,TimeUnit.SECONDS) ;
// Bind and start to accept incoming connections.
ChannelFuture f = b.bind(port).sync();
f.channel().closeFuture().sync();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
bossGroup.shutdownGracefully();
System.err.println("Coucou");
}
}
public static void main(String[] args) {
TestServer testServer = new TestServer() ;
testServer.init(8888);
}
}
,這裏是我的處理程序的源代碼:
public class TestServerHandler extends ChannelInboundHandlerAdapter {
private final TestServer testServer;
public TestServerHandler(TestServer testServer) {
this.testServer = testServer ;
}
@Override
public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
try {
process(ctx, msg);
} catch (Throwable e) {
e.printStackTrace();
}
}
public void process(ChannelHandlerContext ctx, Object msg) throws Exception {
ctx.channel().writeAndFlush(buildHttpResponse()).addListener(new GenericFutureListener<Future<? super Void>>() {
@Override
public void operationComplete(Future<? super Void> future) throws Exception {
ctx.channel().close() ;
testServer.nbSockets ++ ;
}
}) ;
}
public DefaultFullHttpResponse buildHttpResponse() {
String body = "hello world" ;
byte[] bytes = body.getBytes(Charset.forName("UTF-8"));
ByteBuf byteContent = Unpooled.copiedBuffer(bytes);
HttpResponseStatus httpResponseStatus =HttpResponseStatus.OK;
DefaultFullHttpResponse httpResponse = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1,
httpResponseStatus, byteContent);
return httpResponse;
}
}
我在你的代碼上本地運行apache bench:'ab -n 100000 -c 100 http:// localhost:8888 /'。它報告了超過16000個請求/秒 –
謝謝你,你是對的。我會檢查一下爲什麼我沒有和gatling一樣的結果。 – bsh
@四十二你是如何設法得到這麼高的數字的?在我的筆記本電腦(OSX)上運行這個相同的ab會導致連接在〜16.500連接後被拒絕。你的機器是什麼樣的?你是如何設置TCP堆棧的? –