博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Netty NIO 框架性能压测 – 长链接
阅读量:7015 次
发布时间:2019-06-28

本文共 4973 字,大约阅读时间需要 16 分钟。

hot3.png

压测准备
  1. 需要将ulimit -n 改大,否则nio链接开不大。
  2. 准备4台机器(1台netty服务器,3台压测机)
  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     cachedMem:       4149076     189828    3959248          0      13196      95484-/+ buffers/cache:      81148    4067928Swap:      2096472        208    2096264Total:     6245548     190036    6055512 -- 执行 chat server之后             total       used       free     shared    buffers     cachedMem:       4149076     207236    3941840          0      13216      96244-/+ buffers/cache:      97776    4051300Swap:      2096472        208    2096264Total:     6245548     207444    6038104 -- 59471 个nio连接之后             total       used       free     shared    buffers     cachedMem:       4149076     474244    3674832          0      13328      96132-/+ buffers/cache:     364784    3784292Swap:      2096472        208    2096264Total:     6245548     474452    5771096

结论:

  1. Netty nio 可以轻松将链接开到6W,每个线程大概损坏5k左右的系统内存
后续压测方案
  1. 编写Java客户端做内容实时双向推送
  2. 使用100台机器每台机器起1000个线程来模拟客户端进行压测

原文转自 

转载于:https://my.oschina.net/tantexian/blog/715962

你可能感兴趣的文章
Azure China (3) 使用Visual Studio 2013证书发布Cloud Service至Azure China
查看>>
xmapp 404设置
查看>>
SQL Server中, DateTime (日期)型操作的 SQL语法
查看>>
iisweb服务器完美解决方案
查看>>
请教SQL Server登录失败的问题
查看>>
对象和流
查看>>
简单的兼容的login页面
查看>>
jquery之超简单的div显示和隐藏特效demo
查看>>
Oracle:PL/SQL 中如何使用Array
查看>>
[js - 算法可视化] 汉诺塔(Hanoi)演示程序
查看>>
Note:JSON
查看>>
分享.NET 3.0的书籍下载(持续更新中)
查看>>
几道有意思的逻辑分析题
查看>>
apache svn下新建一个项目
查看>>
高效 JavaScript 单元测试(转)
查看>>
[Windows Azure] What is a cloud service?
查看>>
使用C#的泛型队列Queue实现生产消费模式
查看>>
深入理解Tornado——一个异步web服务器
查看>>
软件架构师应该知道的97件事
查看>>
VMware、Citrix和Microsoft虚拟化技术详解与应用实践
查看>>