NewLife.Net——网络压测单机1.88亿tps
NewLife.Net压力测试,峰值4.2Gbps,50万pps,消息大小24字节,消息处理速度2266万tps!
共集合20台高配ECS参与测试,主服务器带宽6Gbps、100万pps,16核心64G内存。另外19台共模拟400个用户连接,13*16+6*32=400,每用户发送2000万个消息,服务端收到后原样返回。
tps意义非常重大,就是告诉所有人,.Net下普普通通的Socket封装,甚至没有使用MSDN的Pool,就能得到非常不错的性能!
*感谢楼下提醒,错误计算了速度,算法如下:
每秒流量 = 4.2G / 8 = 537.6M (进出都是4.2Gbps)
包头消耗 = 50万 * 40 = 19M (50万包,ip+tcp头40字节)
处理速度 = (537.6M - 19M) / 24 = 22,657,979 = 2266万
另外每个nc客户端均有速度计算,102万~200万tps之间,共19客户端,与上吻合
由于我的疏忽,只是简单拿4.2G除以24得到1.88亿,也没有汇总各客户端数据,给出了错误数据,非常抱歉!
(有考虑tcp包头,因报文很短必然粘包,按MTU=1500算误差2.7%,所以直接没有算进去)
有些同学比较着急,觉得前面两篇有点小儿科,群友就说,上数字吧!
我们在2017.4.1做了一个极限并发测试,奔着单机100万并发,实际上只得到了84.5万,这次补一个吞吐量的压力测试好了。
老规矩,先上代码:https://github.com/NewLifeX/NewLife.Net
一、测试结果
二、服务端修改
我们对前一篇文章的例程稍微调整一下:
class MyNetSession : NetSession<MyNetServer>
{
/// <summary>客户端连接</summary>
public override void Start()
{
base.Start(); // 欢迎语
var str = String.Format("Welcome to visit {1}! [{0}]\r\n", Remote, Environment.MachineName);
Send(str);
} /// <summary>收到客户端数据</summary>
/// <param name="e"></param>
protected override void OnReceive(ReceivedEventArgs e)
{
//WriteLog("收到:{0}", e.Packet.ToStr()); // 把收到的数据发回去
Send(e.Packet);
}
}
把显示收到数据的那一行给注释了,否则这一行就能玩死千万级测试,更别说亿万级了。
服务主函数的线程数也要从2改为1,关闭第二个向所有客户端定时群发时间的任务。
public MyService()
{
ServiceName = "EchoAgent";
DisplayName = "回声服务";
Description = "这是NewLife.Net的一个回声服务示例!"; // 准备两个工作线程,分别负责输出日志和向客户端发送时间
//ThreadCount = 2;
ThreadCount = ;
Intervals = new[] { , };
}
三、增加客户端压测项目
新建控制台项目Benchmark,并从nuget引用NewLife.Core
入口函数需要分析参数:
static void Main(String[] args)
{
XTrace.UseConsole(); try
{
var cfg = new Config(); // 分解参数
if (args != null && args.Length > ) cfg.Parse(args); // 显示帮助菜单或执行
if (cfg.Address.IsNullOrEmpty())
ShowHelp();
else
Work(cfg);
}
catch (Exception ex)
{
XTrace.WriteException(ex.GetTrue());
} //Console.WriteLine("OK!");
//Console.ReadKey();
}
主函数就是开一定数量的LongTask,然后等待
static void Work(Config cfg)
{
var uri = new NetUri(cfg.Address);
if (cfg.Content.IsNullOrEmpty()) cfg.Content = "学无先后达者为师";
var pk = new Packet(cfg.Content.GetBytes()); Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("NewLife.NC v{0}", AssemblyX.Entry.Version); Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("目标:{0}", uri);
Console.WriteLine("请求:{0:n0}", cfg.Times);
Console.WriteLine("并发:{0:n0}", cfg.Thread);
Console.WriteLine("并发:[{0:n0}] {1}", pk.Count, cfg.Content);
Console.ResetColor();
Console.WriteLine(); var sw = Stopwatch.StartNew(); // 多线程
var ts = new List<Task>();
var total = ;
for (var i = ; i < cfg.Thread; i++)
{
var tsk = Task.Factory.StartNew(() =>
{
try
{
var client = uri.CreateRemote();
client.Open();
for (var k = ; k < cfg.Times; k++)
{
client.Send(pk);
Interlocked.Increment(ref total);
}
}
catch { }
}, TaskCreationOptions.LongRunning);
ts.Add(tsk);
}
Task.WaitAll(ts.ToArray()); sw.Stop(); Console.WriteLine("完成:{0:n0}", total); var ms = sw.Elapsed.TotalMilliseconds;
Console.WriteLine("速度:{0:n0}tps", total * 1000L / ms);
}
四、上线测试
从阿里云分批租用最高配置的竞价实例20台。统一选择华东2(上海)的D区,因为代码压测只能使用内网,公网达不到这个速度。
整个华东2D最高配就是大数据网络增强型,仅剩的7台都拿下,其中一台作为服务端跑EchoAgent,另外再补13台8核的机器,共19台跑nc(Benchmark)。
在8核心机器上(13台),测试命令:
nc -n 20000000 -c 16 tcp://172.19.227.198:1234
在16核心机器上(6台),测试命令
nc -n 20000000 -c 32 tcp://172.19.227.198:1234
五、结论
人有多大胆,地有多大产!
虽然这次的EchoTest只是简单把数据包发回来,没有挂载复杂业务,但是说明了网络库不是瓶颈,只要硬件性能跟得上,它要多强有多强!
e.Packet的设计,实际上实现了ZeroCopy,同时大大减轻了GC负担,后面会有专门文章提到。
网络库NewLife.Net支持.Net Core 2.0,但XAgent不支持,毕竟它是Windows服务。
这次测试在 .Net Framework v4.6.1 上进行。
网络系列文章,是为了一步步介绍X组件网络库 NewLife.Net的设计理念,从2005年开始,活了13年,不管是成功还是失败,都积累了很多的经验。
我是大石头,打1999年起,19年老码农。目前在物流行业从事数据分析架构工作,日常工作都是亿万数据的读写使用。欢迎大家一起C#大数据!
NewLife.Net——网络压测单机1.88亿tps的更多相关文章
- Jmeter之http性能测试实战 非GUI模式压测 NON-GUI模式 结果解析TPS——干货(十一)
性能测试计划 性能测试用例 录制脚本 性能测试结果 性能测试报告 性能测试监控报告 准备工作 从脚本已录制成功之后开始进行压测 安装Jmeter拓展插件 查看 Transactions per Sec ...
- 压测中的QPS与TPS区别
原文来自:https://www.cnblogs.com/fkkk/p/11957566.html QPS(每秒查询率)=并发数/平均响应时间 TPS(每秒处理事务数)=请求数/时间(秒) TPS的过 ...
- RocketMQ性能压测分析(转载)
一 机器部署 1.1 机器组成 1台nameserver 1台broker 异步刷盘 2台producer 2台consumer 1.2 硬件配置 CPU 两颗x86_64cpu,每颗 ...
- RocketMQ性能压测分析(转)
原创文章,转载请注明出处:http://jameswxx.iteye.com/blog/2093785 一 机器部署 1.1 机器组成 1台nameserver 1台broker 异步刷盘 2 ...
- 7. 堪比JMeter的.Net压测工具 - Crank 总结篇 - crank带来了什么
目录 堪比JMeter的.Net压测工具 - Crank 入门篇 堪比JMeter的.Net压测工具 - Crank 进阶篇 - 认识yml 堪比JMeter的.Net压测工具 - Crank 进阶篇 ...
- jmeter 压测duobbo接口,施压客户端自己把自己压死了
jmeter 压测duobbo接口,jmeter代码不合理,导致每执行一次请求,会调用一次消耗内存的实例化.导致越压越慢,请求发不出去.这个时候需要考虑修改代码了. 截图中,tps越来越少. 原来初始 ...
- 记一次压测问题定位:connection reset by peer,TCP三次握手后服务端发送RST_网络_c359719435的专栏-CSDN博客 https://blog.csdn.net/c359719435/article/details/80300433
记一次压测问题定位:connection reset by peer,TCP三次握手后服务端发送RST_网络_c359719435的专栏-CSDN博客 https://blog.csdn.net/c3 ...
- CentOS单机安装k8s并部署.NET 6程序 压测 记录
前面部分依照CentOS单机安装k8s并部署.NET 6程序来进行,内存.cpu.centos版本一致,之前222元买的三年8M 2c4g腾讯云轻量服务器,这个教程算是写的很详细的了,基本可以一致执行 ...
- Openfire 集群探究_压测情况
一.(测试时间:20151220 - 下午14:00-17:00) windows环境 第一次测试,运行中发现在eclipse环境下.4w个连接耗尽了约1G的内存. 另外:服务本来可用的,压测客户端强 ...
随机推荐
- 从JDK源码角度看线程池原理
"池"技术对我们来说是非常熟悉的一个概念,它的引入是为了在某些场景下提高系统某些关键节点性能,最典型的例子就是数据库连接池,JDBC是一种服务供应接口(SPI),具体的数据库连接实 ...
- Unity StrangeIoC HelloWorld
unity有一个叫StrangeIoC的框架插件,这里写了一个使用StrangeIoC的HelloWorld,比他自带的demo更为简单,方便理解 1.插件下载,在Asset Store直接搜索Str ...
- 版本控制之最佳实践(Git版)
现如今,应该每个开发者都在使用版本控制工具了吧.然而,如果你理解版本控制的基本规则,你便能更好地发挥它的效用.在此,我们汇总了一些最佳实践,希望你在使用Git做版本控制时能够了然于心.得心应手. 1. ...
- Cracking the Coding Interview:: 寻找有环链表的环路起始节点
给定一个有环链表,实现一个算法返回环路的开头节点. 这个问题是由经典面试题-检测链表是否存在环路演变而来.这个问题也是编程之美的判断两个链表是否相交的扩展问题. 首先回顾一下编程之美的问题. 由于如果 ...
- javascript之prototype原型属性
这个地方有点绕,仔细理解代码的意义. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" " ...
- 5、使用Libgdx设计一个简单的游戏------雨滴
(原文:http://www.libgdx.cn/topic/49/5-%E4%BD%BF%E7%94%A8libgdx%E8%AE%BE%E8%AE%A1%E4%B8%80%E4%B8%AA%E7% ...
- Linux0.11启动过程
从开机加电,到执行main函数之前的过程 好吧,这里应该是有执行3个汇编的文件,但是我不太了解.囧 从main函数,到启动OK(即可以响应用户操作了) 这个步骤做了3件事情: 创建进程0,使之具备在主 ...
- 实例分析exec函数
fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间.堆.栈等资源的副本.注意,子进程持有的是上述存储空间的"副本&quo ...
- 《java第一季之入门篇》的想法
学习java也有一段时间了,但是考虑到自己现在上课.复习.考试等耗费很多时间,感觉没有静下心来的时间去写一个长期的博客.计划今年7月1号开始写一套关于java的入门篇博客文章,入门篇计划这样--涵盖j ...
- 集群通信组件tribes之使用方法
上面已经对tribes的内部实现机制及原理进行了深入的剖析,在理解它的设计原理后看看如何使用tribes,整个使用相当简单便捷,只需要四步: ① 定义一个消息对象,由于这个消息对象是要在网络之间传递的 ...