NettyNIO框架性能压测之如何实现长链接
                                            这篇文章将为大家详细讲解有关Netty NIO框架性能压测之如何实现长链接,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

成都创新互联公司,为您提供网站建设、成都网站制作、网站营销推广、网站开发设计,对服务服务器租用等多个行业拥有丰富的网站建设及推广经验。成都创新互联公司网站建设公司成立于2013年,提供专业网站制作报价服务,我们深知市场的竞争激烈,认真对待每位客户,为客户提供赏心悦目的作品。 与客户共同发展进步,是我们永远的责任!
压测准备
- 需要将ulimit -n 改大,否则nio链接开不大。 
- 准备4台机器(1台netty服务器,3台压测机) 
- 使用apache的ab做压测工具 
开始干活
压测代码:
package org.dueam.sample.netty;
package org.dueam.sample.netty;
 
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.Executors;
 
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.buffer.ChannelBuffer;
import org.jboss.netty.buffer.DynamicChannelBuffer;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelStateEvent;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.channel.ChannelHandler.Sharable;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
 
public class ChatServer {
 
	public static void main(String[] args) throws Exception {
		if(args.length <1){
			args = new String[]{"9876","true"};
		}
		ChannelFactory factory = new NioServerSocketChannelFactory(Executors
				.newCachedThreadPool(), Executors.newCachedThreadPool());
 
		ServerBootstrap bootstrap = new ServerBootstrap(factory);
 
		ChatServerHandler handler = new ChatServerHandler();
		ChannelPipeline pipeline = bootstrap.getPipeline();
		pipeline.addLast("chat", handler);
 
		bootstrap.setOption("child.tcpNoDelay", true);
		bootstrap.setOption("child.keepAlive", true);
		int port = Integer.valueOf(args[0]);
		bootstrap.bind(new InetSocketAddress(port));
 
		boolean fillChat = "true".equals(args[1]);
		if (fillChat) {
			ChannelManagerThread cmt = new ChannelManagerThread();
			cmt.start();
		}
 
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		while (true) {
			String command = br.readLine();
			if ("dump".equals(command)) {
				System.out.println("当前活着的数量:" + channel.size());
			} else if ("help".equals(command)) {
				System.out.println("命令列表:");
				System.out.println("dump:打印当前情况");
				System.out.println("help:帮助文档");
			}
		}
 
	}
	final static Random random = new Random();
	static int max = 0;
	static class ChannelManagerThread extends Thread {
		@Override
		public void run() {
			while (true) {
				try {
					if(max < channel.size()){
						max = channel.size() ;
						System.out.println("live:"+channel.size());
					}
 
					for (Channel s : channel.values()) {
						if (random.nextInt(100)>70) {
						ChannelBuffer cb = new DynamicChannelBuffer(256);
						cb.writeBytes("Hey!有人来找你了!".getBytes());
						s.write(cb);
						}
					}
					sleep(500);
				} catch (InterruptedException e) {
 
				}
			}
		}
	}
 
	final static Map channel = new HashMap();
 
	static void log(String message) {
		System.out.println(message);
	}
 
	@Sharable
	static class ChatServerHandler extends SimpleChannelHandler {
		@Override
		public void channelConnected(ChannelHandlerContext ctx,
				ChannelStateEvent e) {
			Channel ch = e.getChannel();
			ChannelBuffer cb = new DynamicChannelBuffer(256);
			cb.writeBytes("Hell!你来了啊!".getBytes());
			ch.write(cb);
			channel.put(e.getChannel().getId(), e.getChannel());
		}
 
 
		@Override
		public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) {
		}
 
		@Override
		public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) {
			e.getCause().printStackTrace();
			channel.remove(e.getChannel().getId());
			log("remove channel by exception! id:" + e.getChannel().getId());
 
			e.getChannel().close();
		}
 
		@Override
		public void channelDisconnected(ChannelHandlerContext ctx,
				ChannelStateEvent e) throws Exception {
			channel.remove(e.getChannel().getId());
			log("remove channel by exception! id:" + e.getChannel().getId());
 
		}
	}
}  压测方式:
#加大超时和并发量,并使用keep-alive的方式保持住端口 ./ab -n 20000 -c 20000 -k -t 999999999 -r http://192.168.216.30:9876/
压测结果
内存损耗:
[root@cap216030 ~]# free -k -t -s 10 -- 原始内存 total used free shared buffers cached Mem: 4149076 189828 3959248 0 13196 95484 -/+ buffers/cache: 81148 4067928 Swap: 2096472 208 2096264 Total: 6245548 190036 6055512 -- 执行 chat server之后 total used free shared buffers cached Mem: 4149076 207236 3941840 0 13216 96244 -/+ buffers/cache: 97776 4051300 Swap: 2096472 208 2096264 Total: 6245548 207444 6038104 -- 59471 个nio连接之后 total used free shared buffers cached Mem: 4149076 474244 3674832 0 13328 96132 -/+ buffers/cache: 364784 3784292 Swap: 2096472 208 2096264 Total: 6245548 474452 5771096
结论:
- Netty nio 可以轻松将链接开到6W,每个线程大概损坏5k左右的系统内存 
后续压测方案
- 编写Java客户端做内容实时双向推送 
- 使用100台机器每台机器起1000个线程来模拟客户端进行压测 
关于“Netty NIO框架性能压测之如何实现长链接”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。
分享标题:NettyNIO框架性能压测之如何实现长链接
文章来源:http://www.scyingshan.cn/article/ijgpes.html

 建站
建站
 咨询
咨询 售后
售后
 建站咨询
建站咨询 
 