`
zhaohaolin
  • 浏览: 1025473 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Netty NIO 框架性能压测 – 长链接【转】

 
阅读更多
压测准备
  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<Integer, Channel> channel = new HashMap<Integer, Channel>();
 
	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

结论:

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

相关推荐

    IO_deep_learning_notes.zip

    184 C10K问题及NIO精讲和IO模型性能压测 地址 185 网络编程之多路复用器及Epoll精讲 地址 187 网络编程java API 实战多路复用器开发 地址 189 全手写急速理解Netty模型及IO模型应用实战 地址 191 Netty之IO模型...

    Dubbo服务以及压测脚本开发

    Dubbo 在此之上提供了高效的序列化、网络通信库 Netty 和异步 I/O 模型 (BIO、NIO、AIO) 的选择,以优化性能。 **4. Dubbo框架 (2.7 版本)** Dubbo 2.7 版本增强了服务治理和运维能力,例如节点角色的定义、调用...

    Java高级架构必备知识点

    **7.20 NIO技术之-Netty** - **NIO基本概念及BIO、AIO的对比分析**:理解NIO、BIO和AIO之间的区别。 - **Netty实现IM聊天系统**:基于Netty开发即时通讯系统。 **7.21 分布式缓存技术-Redis** - **Redis的安装及...

    麦芽糊精检验表格(食品企业原辅料质量验收记录表).docx

    麦芽糊精检验表格(食品企业原辅料质量验收记录表).docx

    塑料原型制作服务市场报告:全球前13强生产商排名及市场份额.docx

    塑料原型制作服务市场报告:全球前13强生产商排名及市场份额.docx

    C++数据结构与STL容器总结

    C++数据结构与STL容器总结

    谷氨酸钠(味精)检验表格(食品企业原辅料质量验收记录表).docx

    谷氨酸钠(味精)检验表格(食品企业原辅料质量验收记录表).docx

    小程序/虚拟资源变现知识付费小程序/激励广告流量主

    已更新微信登录获取用户头像失败功能,增加登录更新账号信息功能。 主要功能 会员系统,用户登录/注册 购买记录 收藏记录 基本设置 后台控制 导航颜色 字体颜色 标题等设置 流量主广告开关 小程序广告显示隐藏 广告主审核过审核 资源管理 后台可以添加5种类型资源 灵活设置 激励广告解锁资源 vip专享资源 免费资源 积分购买资源 阅读全文资源 公告 会员公告系统 VIP系统 用户可以开通VIP 查看vip专属资源 签到 签到互动二奖励 分类 资源分类 友情连接 跳转小程序 盈利能力:激励视频广告+插屏广告+视频广告+横幅广告+格子广告 =收益神器

    [继电保护仿真]-三段式距离保护 基于matlab simulink仿真 支持三段式电流保护、三段式距离保护、零序电流保护、欠压保护、振荡闭锁、差动保护、变压器差动保护、变压器后备保护、母线保护、

    [继电保护仿真]--三段式距离保护 基于matlab simulink仿真 支持三段式电流保护、三段式距离保护、零序电流保护、欠压保护、振荡闭锁、差动保护、变压器差动保护、变压器后备保护、母线保护、自动重合闸、分布式电源自适应保护等仿真定制 ,继电保护仿真; 三段式距离保护; MATLAB Simulink仿真; 多种保护类型仿真定制,Matlab Simulink三段式距离保护仿真定制

    基于Flask的pythonweb开发的外卖平台毕设

    内含数据库 源码 流程图 效果图,绝对物超所值

    薄板动力学相空间非传统Hamilton变分原理及辛算法的研究与应用(可复现,有问题请联系博主)

    内容概要:本文主要讨论了将弹性薄板动力分析从传统的Lagrange体系转换到Hamilton体系的必要性和优势。通过引入非传统Hamilton变分原理,建立了薄板动力学在相空间中的正则方程及对应的辛算法——辛空间有限元-时间子域法。这种方法不仅可以提高计算精度与效率,而且克服了以往非辛算法中存在的诸多缺陷。此外,文章提供了具体的数学模型、边界和初始条件推导以及算例验证。 适用人群:适用于固体力学领域研究人员、机械工程专业的学生和技术人员,特别是关注弹性薄板振动特性分析的专业人士。 使用场景及目标:本方法适用于弹性薄板结构在不同边界条件下的动态响应分析。旨在为相关工程问题提供更高精确度的解决方案。 其他说明:该研究展示了新型算法相比于传统方法在稳定性和准确性方面的优越性。通过对两个特定实例的数据对比进一步证实了辛算法的有效性和可行性。

    基于时变参数字典与精细化二次选择的正交匹配追踪算法在轴承故障诊断中的应用(可复现,有问题请联系博主)

    内容概要:本文提出了一种基于时变参数字典和细化二次选择机制的正交匹配追踪(TPRSS-OMP)算法,用于滚动轴承的早期故障检测。传统的相关滤波方法对噪声敏感,固定参数原子难以适应时间变化的影响特征,而本文提出的改进方法克服了这些问题。首先通过分段时域相关滤波与K-means聚类确定拉普拉斯小波字典的时间变化参数范围,在求解稀疏系数过程中引入新的优化后的次级选择原则——考虑信号重建前后信封频谱峰度的变化,从而提高算法对背景噪音干扰下的故障冲击特征提取能力。实验结果表明,新算法能有效重构故障信号并精准提取故障脉冲特征,适用于实际工况下的滚动轴承监测任务。 适合人群:具有一定机械工程与振动信号处理基础知识的研究人员、研究生、工程师。 使用场景及目标:①工业设备中滚动轴承及其他旋转设备的早期故障预警系统构建;②从强背景噪声中精确提取故障冲击特征。 其他说明:论文提供仿真及真实数据验证,展示了改进后的正交匹配追踪方法相比现有技术在准确性方面的优越表现,特别强调对于复杂操作环境下的鲁棒性能提升。文中还讨论了未来需要解决的问题如K-means聚类方法可能受到大幅波动的影响以及复合故障情况下的扩展性研

    醪糟检验表格(食品企业原辅料质量验收记录表).docx

    醪糟检验表格(食品企业原辅料质量验收记录表).docx

    SBLC买断基本信息.docx

    SBLC买断基本信息.docx

    罗汉果检验表格(食品香辛料质量验收记录表)检验表格(食品香辛料质量验收记录表).docx

    罗汉果检验表格(食品香辛料质量验收记录表)检验表格(食品香辛料质量验收记录表).docx

    MySQL 的.ibd文件恢复数据

    100%能恢复数据,亲测亲调试优化了代码 工具概述 我们有一个用Go语言编写的工具,能够读取.ibd文件并将其转换为可执行的SQL语句,从而实现数据恢复。该工具的主要功 解析.ibd文件:读取并解析.ibd文件中的数据结构。 生成SQL脚本:将解析到的数据转换为SQL插入语句。 恢复数据:通过执行生成的SQL脚本,将数据重新导入数据库 https://blog.csdn.net/qq_24396737/article/details/146182892?spm=1001.2014.3001.5501

    船舶与海洋工程技术-带顶滚轮的船用通用导缆器标准规范(ISO 13733:2020)

    内容概要:本国际标准 (ISO 13733:2020) 详细规定了安装在船舶上以引导系泊绳从船内到外板的带有顶部滚轮的船用通用导缆器的标准和技术要求。具体涵盖四种类型的导缆器分类、额定尺寸、尺寸参数、制造材料、结构设计、制造与检测要求以及标记要求等内容,并明确了安全工作载荷(SWL)的定义和要求,还提供了有限元法(FEM)用于评估强度的分析条件。 适用人群:适用于从事船舶工程、海上技术设备制造和相关标准规范实施的专业技术人员和监管人员。 使用场景及目标:本标准用于指导船舶装备制造商和工程师进行正确的导缆器设计、选型、生产及其安装施工,并保障在各种实际操作条件下能可靠传递系泊负荷。 其他说明:标准修订了多项内容,增加了技术指南并调整了关键部件的设计尺寸,提高了产品的安全性。此外,对于涉及专利权的技术细节,请参照ISO官网的相关信息获取进一步帮助。

    2025年汽车租赁业务系统应该具备的功能

    本文为抛砖引玉:简单描述,如需根据自身业务详细设计,请随时联系

    基于51单片机的测量仪(电压,电平,频率) 1104-基于51单片机的测量仪(电压,电平,频率)原理图、流程图、物料清单、仿真图、源代码 功能介绍: 基于单片机的简易测量仪(测量电压、TTL电平01

    基于51单片机的测量仪(电压,电平,频率) 1104-基于51单片机的测量仪(电压,电平,频率)原理图、流程图、物料清单、仿真图、源代码 功能介绍: 基于单片机的简易测量仪(测量电压、TTL电平01,频率等) 设计一个简易的测量设备,用两支表笔(1个是GND,一个是输入信号)测可用于数字电路实验及测试中 功能要求如下: (1)测量直流信号的电压,电压范围0~5V; (2)测量信号的TTL电平,给出高低电平测量结果;(3)测量数字信号的频率,给出测量结果; (4)用LCD显示结果,使用按键切测量功能(5)显示学号及姓名的拼音字母 有哪些资料: 1、仿真工程文件 2、源代码工程文件 3、原理图工程文件 4、流程图 5、功能介绍 6、元件清单 ,基于51单片机的测量仪;电压测量;电平测量;频率测量;原理图;流程图;物料清单;仿真图;LCD显示;按键切换功能;学号姓名显示。,基于51单片机多功能测量仪:电压、电平、频率测量及显示系统

    基于YOLOv9的智慧渔业捕捞检测系统(Python源码+数据集) 智慧渔业捕捞一共355张,类别为:'fish' ,基于YOLOv9; 智慧渔业捕捞检测系统; Python源码; 数据集; 鱼('

    基于YOLOv9的智慧渔业捕捞检测系统(Python源码+数据集) 智慧渔业捕捞一共355张,类别为:'fish' ,基于YOLOv9; 智慧渔业捕捞检测系统; Python源码; 数据集; 鱼('fish'); 355张图片,基于YOLOv9的渔业智慧检测系统(Python+数据集)

Global site tag (gtag.js) - Google Analytics