netty和tomcat的hello world性能比较

小弟有点菜, 测试不科学的地方敬请指教。

环境:

       16G内存,  8核双线程CPU,   cenos6,   jmeter,  netty5,   tomcat6, JDK1.7-64

1    netty的源码:example下的hello world

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;

public class HttpHelloWorldServer {

	private final int port;

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

	public void run() throws Exception {
		// Configure the server.
		EventLoopGroup bossGroup = new NioEventLoopGroup(1);
		EventLoopGroup workerGroup = new NioEventLoopGroup(50);
		try {
			ServerBootstrap b = new ServerBootstrap();
			b.option(ChannelOption.SO_BACKLOG, 1024);
			b.group(bossGroup, workerGroup)
					.channel(NioServerSocketChannel.class)
					.childHandler(new HttpHelloWorldServerInitializer());

			Channel ch = b.bind(port).sync().channel();
			System.out.println(" connection is ok");
			ch.closeFuture().sync();
		} finally {
			bossGroup.shutdownGracefully();
			workerGroup.shutdownGracefully();
		}
	}

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

HttpHelloWorldServerHandler:

import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;

import static io.netty.handler.codec.http.HttpHeaders.Names.*;
import static io.netty.handler.codec.http.HttpHeaders.*;
import static io.netty.handler.codec.http.HttpResponseStatus.*;
import static io.netty.handler.codec.http.HttpVersion.*;

public class HttpHelloWorldServerHandler extends ChannelHandlerAdapter {
    private static final byte[] CONTENT = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd' };

    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        ctx.flush();
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        if (msg instanceof HttpRequest) {
            HttpRequest req = (HttpRequest) msg;

            if (is100ContinueExpected(req)) {
                ctx.write(new DefaultFullHttpResponse(HTTP_1_1, CONTINUE));
            }
            boolean keepAlive = isKeepAlive(req);
            FullHttpResponse response = new DefaultFullHttpResponse(HTTP_1_1, OK, Unpooled.wrappedBuffer(CONTENT));
            response.headers().set(CONTENT_TYPE, "text/plain");
            response.headers().set(CONTENT_LENGTH, response.content().readableBytes());

            if (!keepAlive) {
                ctx.write(response).addListener(ChannelFutureListener.CLOSE);
            } else {
                response.headers().set(CONNECTION, Values.KEEP_ALIVE);
                ctx.write(response);
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        cause.printStackTrace();
        ctx.close();
    }
}

  HttpHelloWorldServerInitializer:

import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.http.HttpServerCodec;

public class HttpHelloWorldServerInitializer extends ChannelInitializer<SocketChannel> {
    @Override
    public void initChannel(SocketChannel ch) throws Exception {
        ChannelPipeline p = ch.pipeline();

        // Uncomment the following line if you want HTTPS
        //SSLEngine engine = SecureChatSslContextFactory.getServerContext().createSSLEngine();
        //engine.setUseClientMode(false);
        //p.addLast("ssl", new SslHandler(engine));

        p.addLast("codec", new HttpServerCodec());
        p.addLast("handler", new HttpHelloWorldServerHandler());
    }
}

2    tomcat的代码, 就一个sevlet

package testTomcatHttp;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		doPost(req, resp);
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		// TODO Auto-generated method stub
		PrintWriter printWriter = resp.getWriter();
		printWriter.println("<h1>Hello World!</h1>");
	}
}

  web.xml

<servlet>  
    <servlet-name>hello</servlet-name>  
    <servlet-class>testTomcatHttp.TestServlet</servlet-class>  
  </servlet>     
  <servlet-mapping>  
    <servlet-name>hello</servlet-name>  
    <url-pattern>/hello</url-pattern>  
  </servlet-mapping>


测试备注:

1)    由于tomcat6中, 有个bug, acceptor参数设置无效,只能是1, 所以我们只改变maxThreads的值;

2)   tomcat和netty的jvm参数配置为:  -server -Xms2048m -Xmx3098m -Xloggc:/root/nettyhttp/gc.log

3)   jMeter循环次数都是1000次,sleep 1ms

测试用例:

(1)   netty :  acceptor=1,   I/O Threads=50,   jMeter的用户线程数分别为100和50

(2)  tomcat nio:  acceptor=1,   maxThreads=50,   jMeter的用户线程数分别为100和50

(3)  tomcat bio:  acceptor=1,   maxThreads=50,   jMeter的用户线程数分别为100和50

备注: 不稳定,第一次测试500多, 第二次700多,   且刚开始的Throughput很高, 但是越后越慢, 且开始error

(4)  在tomcat bio模式下, 把maxThreads=16   netty I/OThreads默认, 在本机上也是16,

测试的结果,  tomcat只有300多, 且有报错,   而netty的测试结果800上下,且没有报错。


所以, 根据测试结果可以推断出,  

  a    netty+http在性能上和可靠性和还是不错的, 且可以nginx搭配使用。

  b     tomcat, nio模式还可以, 但是bio模式,测试结果不怎么好。

   且, 

 netty + http 定制不用受web容器的限制, IO线程对于执行时间比较长的task, 可以异步交给现场池, 猜测tomcat的nio模式中,  actiom-server中也可以这样做。但是tomcat, 别人都封装好了, 不会出现大问题。

具体使用哪个, 根据场景进行选择。 


欢迎指教!

你可能感兴趣的:(netty和tomcat的hello world性能比较)