文档章节

tomcat、netty以及nodejs的helloworld性能对比

longrmlife
 longrmlife
发布于 2013/04/05 16:39
字数 528
阅读 18861
收藏 21

最近闲来无事,对tomcat、netty以及nodejs的性能对比比较有兴趣,于是自行测试了一下。

测试环境:

测试工具:Apache JMeter2.9

测试代码:

  1. tomcat下的jsp:
    <%@page language="java" contentType="text/html; charset=GBK" %>
    <%@page import = "java.util.Date" %>
    
    <html>
    <body>
      hello world!
      <%= new Date() %>
    </body>
    </html>
  2. netty下的server:
    package com.hannah.netty;
    import java.net.InetSocketAddress;
    import java.util.concurrent.Executors;
    
    import org.jboss.netty.bootstrap.ServerBootstrap;
    import org.jboss.netty.channel.ChannelPipeline;
    import org.jboss.netty.channel.ChannelPipelineFactory;
    import org.jboss.netty.channel.Channels;
    import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
    import org.jboss.netty.handler.codec.http.HttpRequestDecoder;
    import org.jboss.netty.handler.codec.http.HttpResponseEncoder;
    
    public class AdminServer {
    	public static void main(String[] args) {
    		start(8080);
    	}
    
    	public static void start(int port) {
    		// 配置服务器-使用java线程池作为解释线程
    		ServerBootstrap bootstrap = new ServerBootstrap(new NioServerSocketChannelFactory(
    				Executors.newCachedThreadPool(), Executors.newCachedThreadPool()));
    		// 设置 pipeline factory.
    		bootstrap.setPipelineFactory(new ServerPipelineFactory());
    		// 绑定端口
    		bootstrap.bind(new InetSocketAddress(port));
    		System.out.println("admin start on " + port);
    	}
    
    	private static class ServerPipelineFactory implements ChannelPipelineFactory {
    		public ChannelPipeline getPipeline() throws Exception {
    			// Create a default pipeline implementation.
    			ChannelPipeline pipeline = Channels.pipeline();
    			pipeline.addLast("decoder", new HttpRequestDecoder());
    			pipeline.addLast("encoder", new HttpResponseEncoder());
    			// http处理handler
    			pipeline.addLast("handler", new AdminServerHandler());
    			return pipeline;
    		}
    	}
    }
    package com.hannah.thirdparty.netty;
    
    import java.util.Date;
    
    import org.jboss.netty.buffer.ChannelBuffer;
    import org.jboss.netty.buffer.ChannelBuffers;
    import org.jboss.netty.buffer.DynamicChannelBuffer;
    import org.jboss.netty.channel.Channel;
    import org.jboss.netty.channel.ChannelFutureListener;
    import org.jboss.netty.channel.ChannelHandlerContext;
    import org.jboss.netty.channel.ExceptionEvent;
    import org.jboss.netty.channel.MessageEvent;
    import org.jboss.netty.channel.SimpleChannelUpstreamHandler;
    import org.jboss.netty.handler.codec.frame.TooLongFrameException;
    import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
    import org.jboss.netty.handler.codec.http.HttpHeaders.Names;
    import org.jboss.netty.handler.codec.http.HttpRequest;
    import org.jboss.netty.handler.codec.http.HttpResponse;
    import org.jboss.netty.handler.codec.http.HttpResponseStatus;
    import org.jboss.netty.handler.codec.http.HttpVersion;
    import org.jboss.netty.util.CharsetUtil;
    
    public class AdminServerHandler extends SimpleChannelUpstreamHandler {
    
    	@Override
    	public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
    //		HttpRequest request = (HttpRequest) e.getMessage();
    //		String uri = request.getUri();
    //		System.out.println("uri:" + uri);
    		HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
    		ChannelBuffer buffer = new DynamicChannelBuffer(2048);
    		buffer.writeBytes(("Hello World!\t" + new Date()).getBytes("UTF-8"));
    		response.setContent(buffer);
    		response.setHeader("Content-Type", "text/html; charset=UTF-8");
    		response.setHeader("Content-Length", response.getContent().writerIndex());
    		Channel ch = e.getChannel();
    		// Write the initial line and the header.
    		ch.write(response);
    		ch.disconnect();
    		ch.close();
    	}
    
    	@Override
    	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
    		Channel ch = e.getChannel();
    		Throwable cause = e.getCause();
    		if (cause instanceof TooLongFrameException) {
    			sendError(ctx, HttpResponseStatus.BAD_REQUEST);
    			return;
    		}
    		cause.printStackTrace();
    		if (ch.isConnected()) {
    			sendError(ctx, HttpResponseStatus.INTERNAL_SERVER_ERROR);
    		}
    	}
    
    	private void sendError(ChannelHandlerContext ctx, HttpResponseStatus status) {
    		HttpResponse response = new DefaultHttpResponse(HttpVersion.HTTP_1_1, status);
    		response.setHeader(Names.CONTENT_TYPE, "text/plain; charset=UTF-8");
    		response.setContent(ChannelBuffers.copiedBuffer("Failure: " + status.toString() + "\r\n", CharsetUtil.UTF_8));
    
    		// Close the connection as soon as the error message is sent.
    		ctx.getChannel().write(response).addListener(ChannelFutureListener.CLOSE);
    	}
    }
  3. nodejs下的example.js:
    // var url = require('url');
    var http = require('http');
    http.createServer(function (req, res) {
      // var pathname = url.parse(req.url).pathname;
      res.writeHead(200, {'Content-Type': 'text/plain'});
      res.end('Hello World!\t' + new Date());
    }).listen(1337, '127.0.0.1');
    console.log('Server running at http://127.0.0.1:1337/');


测试结果:

  1. 线程数:100;循环次数:100;
  2. 线程数:1000;循环次数:10;
  3. 线程数:1000;循环次数:100;

结果分析:整体上来看,并发小的时候,区别不大;当并发逐渐加大时,tomcat首先承受不住,nodejs和netty性能大致相当(netty性能略低点);最后一次请求的时候,tomcat报OutOfMemory的错误了!

© 著作权归作者所有

longrmlife
粉丝 0
博文 2
码字总数 1079
作品 0
东城
私信 提问
加载中

评论(20)

Percy-Dreams
Percy-Dreams
应用环境不同,首先社区有人说tomcat支持arp模式,这个理论性能比nio更高。其次,tomcat通常连接、断开,connection虽然有连接池,但是大都是web环境的。netty更倾向于长链接。
卖萌的程序猿
卖萌的程序猿
挖个坟,netty的windows和linux环境的性能差别很大,除了编码复杂以外,netty秒杀tomcat,node勉强可以和netty一战了
X
Xy丶
你的cpu是几核的?
我用4核4g配置测得 helloword程序
netty: 13810.39/sec
node: 5101.64/sec
多核情况下node好像完败吧。
我想如果node利用了多核加上nginx负载均衡应该性能又会超过 netty。。。
Xsank
Xsank
测xsocket与netty tcp性能用什么?
一条大河波浪宽
一条大河波浪宽
幸好看了下面的评论,楼主应该修改一下文章啊
longrmlife
longrmlife 博主

引用来自“sunxiaopang6245”的评论

你好,能否告知你是怎么通过jmeter进行nodejs测试的
启动nodejs服务,然后用jmeter去请求哦
sunxiaopang6245
sunxiaopang6245
你好,能否告知你是怎么通过jmeter进行nodejs测试的
niweicumt
niweicumt
楼主测试tomcat是bio还是nio的?如果是bio跟nio的netty和异步的nodejs比较实在是胜之不武35
小长
这个测试很有用啊,就是没测试tomcat的nio或者是aio的性能
小报童
小报童
tomcat没有做什么优化,实在是太局限了
三大角度 PK ,Go 语言和 Node.js 谁胜谁负?

Node.js 与 Go 语言一直是互联网大战中的主战场,虽说按照普通的各项指标对比,那么这场战争可能在很长时间内都难分胜负,但我们还是决定尝试对这二者做一些研究,并力求做出更准确的判断。 ...

王练
2018/07/01
12.4K
47
三大角度PK,Go语言和Node.js谁胜谁负?

Node.js与Go语言一直是互联网大战中的主战场,虽说按照普通的各项指标对比,那么这场战争可能在很长时间内都难分胜负,但我们还是决定尝试对这二者做一些研究,并力求做出更准确的判断。 我们...

程序师
2018/06/30
0
0
编写Node.js原生扩展

原文出处:https://www.cloudkick.com/blog/2010/aug/23/writing-nodejs-native-extensions/ 译文出处:http://www.grati.org/?p=413 Node.js是一个强大的平台,理想状态下一切都都可以用jav...

红薯
2011/04/18
2.4K
1
helloword测试 netty vs nodejs

ab -n 10000 -c 1024 netty比nodejs高出30%的性能

yak
2012/06/21
2.8K
4
关于 node.js 语言的讨论

本文是从 Node on nails! 这篇文章翻译而来。 在开始叙述这篇文章之前,我要非常清楚和明确的声明:“我并不是在鼓励你放弃NodeJS或转向Java”。 我一直参与在这种争论中。在我的编程界的朋友...

红薯
2011/11/02
2.1K
14

没有更多内容

加载失败,请刷新页面

加载更多

Xss过滤器(Java)

问题 最近旧的系统,遇到Xss安全问题。这个系统采用用的是spring mvc的maven工程。 解决 maven依赖配置 <properties><easapi.version>2.2.0.0</easapi.version></properties><dependenci......

亚林瓜子
27分钟前
2
0
Navicat 快捷键

操作 结果 ctrl+q 打开查询窗口 ctrl+/ 注释sql语句 ctrl+shift +/ 解除注释 ctrl+r 运行查询窗口的sql语句 ctrl+shift+r 只运行选中的sql语句 F6 打开一个mysql命令行窗口 ctrl+l 删除一行 ...

低至一折起
今天
7
0
Set 和 Map

Set 1:基本概念 类数组对象, 内部元素唯一 let set = new Set([1, 2, 3, 2, 1]); console.log(set); // Set(3){ 1, 2, 3 } [...set]; // [1, 2, 3] 接收数组或迭代器对象 ...

凌兮洛
今天
1
0
PyTorch入门笔记一

张量 引入pytorch,生成一个随机的5x3张量 >>> from __future__ import print_function>>> import torch>>> x = torch.rand(5, 3)>>> print(x)tensor([[0.5555, 0.7301, 0.5655],......

仪山湖
今天
5
0
OSChina 周二乱弹 —— 开发语言和语言开发的能一样么

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @花间小酌:#今日歌曲推荐# 分享The Score的单曲《Revolution》 《Revolution》- The Score 手机党少年们想听歌,请使劲儿戳(这里) @批判派...

小小编辑
今天
2.8K
19

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部