2

Netty でWebSocketServerのストレス テストを行い、 Tornadoの hello デモと比較してみます。

どちらも「hello world html」を受信して​​応答し、Siegeによるストレス テストを行います。それらはまったく同じ環境で実行されます。

ネイティブ Java は Tornado/Python よりも高速である必要があります。ただし、結果は次のとおりです。Tornado/Python は、No に関して Nettyよりも約2 倍高速です。1 秒あたりに処理されるリクエストの数。

ネイティブ Java が遅い理由を説明できる人はいますか? テストは正しいですか?

ありがとう

JAVA : トランザクション レート: 657.89 トランス/秒 Python : トランザクション レート: 1435.41 トランス/秒

JAVA WebSocketServer

public class WebSocketServer {

private final int port;

public WebSocketServer(int port) {
    this.port = port;
}

public void run() {
    // Configure the server.
    ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
            Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));

    // Set up the event pipeline factory.
    bootstrap.setPipelineFactory(new WebSocketServerPipelineFactory());

    // Bind and start to accept incoming connections.
    bootstrap.bind(new InetSocketAddress(port));

    System.out.println("Web socket server started at port " + port + '.');
    System.out.println("Open your browser and navigate to http://localhost:" + port + '/');
}

public static void main(String[] args) {
    int port;
    if (args.length > 0) {
        port = Integer.parseInt(args[0]);
    } else {
        port = 8888;
    }
    new WebSocketServer(port).run();
}

}

Java メッセージ ハンドラ

@Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
    Object msg = e.getMessage();
    if (msg instanceof HttpRequest) {
        handleHttpRequest(ctx, (HttpRequest) msg);
    } else if (msg instanceof WebSocketFrame) {
        handleWebSocketFrame(ctx, (WebSocketFrame) msg);
    }
}
private void handleHttpRequest(ChannelHandlerContext ctx, HttpRequest req) throws Exception {
    HttpResponse res = new DefaultHttpResponse(HTTP_1_1, OK);
    // ChannelBuffer content = WebSocketServerIndexPage.getContent(getWebSocketLocation(req));
    ChannelBuffer content = ChannelBuffers.copiedBuffer( "<html><body>hello!</body></html>", CharsetUtil.US_ASCII);


    res.setHeader(CONTENT_TYPE, "text/html; charset=UTF-8");
    setContentLength(res, content.readableBytes());

    res.setContent(content);
    sendHttpResponse(ctx, req, res);
    return;

}

private void handleWebSocketFrame(ChannelHandlerContext ctx, WebSocketFrame frame) {

    // Check for closing frame
    if (frame instanceof CloseWebSocketFrame) {
        handshaker.close(ctx.getChannel(), (CloseWebSocketFrame) frame);
        return;
    } else if (frame instanceof PingWebSocketFrame) {
        ctx.getChannel().write(new PongWebSocketFrame(frame.getBinaryData()));
        return;
    } else if (!(frame instanceof TextWebSocketFrame)) {
        throw new UnsupportedOperationException(String.format("%s frame types not supported", frame.getClass()
                .getName()));
    }

    // Send the uppercase string back.
    String request = ((TextWebSocketFrame) frame).getText();
    if (logger.isDebugEnabled()) {
        logger.debug(String.format("Channel %s received %s", ctx.getChannel().getId(), request));
    }
    ctx.getChannel().write(new TextWebSocketFrame(request.toUpperCase()));
}

private static void sendHttpResponse(ChannelHandlerContext ctx, HttpRequest req, HttpResponse res) {
    // Generate an error page if response status code is not OK (200).
    if (res.getStatus().getCode() != 200) {
        res.setContent(ChannelBuffers.copiedBuffer(res.getStatus().toString(), CharsetUtil.UTF_8));
        setContentLength(res, res.getContent().readableBytes());
    }

    // Send the response and close the connection if necessary.
    ChannelFuture f = ctx.getChannel().write(res);
    if (!isKeepAlive(req) || res.getStatus().getCode() != 200) {
        f.addListener(ChannelFutureListener.CLOSE);
    }
}

トルネード下のパイソン

define("port", default=8888, help="run on the given port", type=int)


class MainHandler(tornado.web.RequestHandler):
def get(self):
    self.write("Hello, world")


def main():
    tornado.options.parse_command_line()
    application = tornado.web.Application([
        (r"/", MainHandler),
    ])
    http_server = tornado.httpserver.HTTPServer(application)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()


if __name__ == "__main__":
    main()
4

0 に答える 0