2

我尝试在 Netty 下对WebSocketServer进行压力测试,并将其与Tornado中的 hello demo 进行比较。

两者都接收和响应“hello world html”,我通过Siege进行压力测试。它们在完全相同的环境下运行。

我们预计原生 java 应该比 Tornado/Python 更快。然而,结果是:Tornado/Python在 no 方面比 Netty快大约 2 倍。每秒处理的请求数。

谁能解释为什么原生 Java 更慢?测试是否正确?

谢谢

JAVA:交易速度:657.89 交易/秒 Python:交易速度:1435.41 交易/秒

JAVA WebSocket服务器

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);
    }
}

Tornado 下的 Python

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