NewLife.Net——网络压测单机2266万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/nnhy/NewLife.Net.Tests

一、测试结果

二、服务端修改

我们对前一篇文章的例程稍微调整一下:

 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 = 1;
    Intervals = new[] { 1, 5 };
}

三、增加客户端压测项目

新建控制台项目Benchmark,并从nuget引用NewLife.Core

入口函数需要分析参数:

static void Main(String[] args)
{
    XTrace.UseConsole();

    try
    {
        var cfg = new Config();

        // 分解参数
        if (args != null && args.Length > 0) 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 = 0;
    for (var i = 0; i < cfg.Thread; i++)
    {
        var tsk = Task.Factory.StartNew(() =>
        {
            try
            {
                var client = uri.CreateRemote();
                client.Open();
                for (var k = 0; 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#大数据!

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏林德熙的博客

VisualStduio 打断点调试和不打断点调试有什么区别 随机数

最近小伙伴告诉我,他的代码在打断点的时候,运行到断点,之后就可以运行。如果没有断点,他的代码就无法运行,经过了一段时间的研究才发现,原来打断点和不打断点是有一些...

21320
来自专栏小特工作室

解决微信公众平台IP白名单

微信公众平台,作为自媒体的旗舰级产品,越来越多的人已经投入它的怀抱。正如它的广告词所说:再小的个体,也有品牌 好吧,闲话不多说,今天要说的是它的IP白名单机制。...

1.3K60
来自专栏架构师之路

1分钟实现“延迟消息”功能

一、缘起 很多时候,业务有“在一段时间之后,完成一个工作任务”的需求。 例如:滴滴打车订单完成后,如果用户一直不评价,48小时后会将自动评价为5星。 一般来说怎...

56360
来自专栏云计算

使用Akka HTTP构建微服务:CDC方法

原文地址:https://dzone.com/articles/building-microservices-with-akka-http-a-cdc-appr...

40650
来自专栏阿炬.NET

FSLIB.NETWORK 简易使用指南

39960
来自专栏跟着阿笨一起玩NET

asp.net采用OLEDB方式导入Excel数据时提示:未在本地计算机上注册"Microsoft.Jet.OLEDB.4.0" 提供程序"

 笔者在项目中做做了一个从Excel表格中导入数据的模块、大体上asp.net项目中导入Excel大体分成三类:

82610
来自专栏跟着阿笨一起玩NET

DataTable.AcceptChanges & DataAdapter.Update

The AcceptChanges method makes rows status to Unchanged, then the DataAdapter.Up...

7610
来自专栏更流畅、简洁的软件开发方式

【自然框架】之数据访问 —— 再小的类库也需要设计。

  以前也写过几篇关于数据访问的,这里是最新的总结。麻雀虽小五脏俱全,数据访问也许不起眼,但是也要好好的设计一翻。从2004年开始用自己的数据访问,一直到现在,...

26690
来自专栏智能大石头

NewLife.Net——网络压测单机1.88亿tps

21840
来自专栏张善友的专栏

使用OData协议查询Windows日志

OData开放数据协议是微软针对Google的GData推出的,旨在推广Web程序数据库格式标准化的开放数据协议,微软将 OData 定义为基于 HTTP、A...

24690

扫码关注云+社区

领取腾讯云代金券