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#大數據!

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章