CodeBenchmark之壓力測試詳解

CodeBenchmark是一款高性能可視化的併發測試組件,通過組件可以對任意邏輯代碼或服務進行併發測試;組件最終通過可視化的方式來顯示測試結果,在測試結果中可以看到具體的併發情況和處理延時的分佈。組件不僅可以對單個邏輯或服務進行併發測試,還可以同時對多個邏輯代碼用例進行不同併發分組壓測,最終顯示它們之間的性能差異和不同併發下的最優結果。接下來介紹如何使用這一組件對邏輯代碼或服務進行併發測試。

構建測試項目

可以通過vsvscode構建一個控制檯項目然後引用組件(引用最新版本的BeetleX.CodeBenchmark)

Install-Package BeetleX.CodeBenchmark -Version 1.0.8

實現一個HTTP壓測

引用組件後就可以編寫具體的測試用例,測試用例編寫必須符合組件測試要求,所以需要實現一個接口來編寫測試代碼,接口描述如下:

    public interface IExample:IDisposable
    {
        void Initialize(Benchmark benchmark);
        Task Execute();
    }

HTTP壓測邏輯代碼

    [System.ComponentModel.Category("TCP")]
    class HttpGet : IExample
    {
        public void Dispose()
        {          
        }

        public async Task Execute()
        {
            var result = await _httpHandler.json();
        }

        public void Initialize(Benchmark benchmark)
        {
            if(_httpApi==null)
            {
                _httpApi = new BeetleX.Http.Clients.HttpClusterApi();
                _httpApi.DefaultNode.Add("http://192.168.2.19:8080");
                _httpHandler = _httpApi.Create<IHttpHandler>();
            }
        }

        static BeetleX.Http.Clients.HttpClusterApi _httpApi;

        static IHttpHandler _httpHandler;

        [BeetleX.Http.Clients.FormUrlFormater]
        public interface IHttpHandler
        {
            // http://host/json
            Task<string> json();
        }
    }

在併發實例初始化的時候創建一個請求http請求對象,HttpClusterApi是一個線程安全對象所以只需要靜態化構建一個即可;組件會針對第一個併發來構建一個實例。

啓動壓測

當測試用例寫好後就需要進行測試,通過以下簡單代碼即可以打開測試管理

            Benchmark benchmark = new Benchmark();
            benchmark.Register(typeof(Program).Assembly);
            benchmark.Start();//在本地打開管理服務,服務端口默信是9090
            if(Environment.OSVersion.Platform== PlatformID.Win32NT)
                benchmark.OpenWeb();

代碼中做了一下判斷,如果當前系統是windows則自動打開瀏覽器訪問服務(由於服務是基於vue實現,會存在一些舊瀏覽器兼容問題,建議使用新版瀏覽器)。

管理和測試

當服務打開後就可以通過瀏覽器管理測試用例,具體界面如下:

在管理界面中你只需要選擇測試用例和添加併發測試即可以進行壓測,以下是開啓10個併發並運行10秒的測試情況:

運行後能看到併發完成的數量和平均的RPS,點擊測試的用例還能看到延時分佈,可以知道大部分處理分佈在那個時間區域。

不同併發對比

很多時候需要對一個服務進行不同併發的測試,這樣可以觀察服務在那個併發量下的最併發處理能力;組件支持對同時添加多個測試併發組並進行測試和結果對比。

在這個硬件和測試場景之下,顯然是8併發的測力測試結果最高

通這個測試就可以針對服務情況來規劃併發控制設計。接下來換個環境試下同樣的測試

通過工具可以很快就能測出不同環境下最優的併發處理效果

多邏輯併發能性能對比

組件也支持多用例壓測對比,只需要在測試的時候選擇多個測試用例即可。接下來簡單地測試一下不同json組件序列化的性能對比。 測試分別有Newtonsoft.Json,Utf8Json,SwifterJsonspanJson.相應代碼如下:

  • Newtonsoft.Json

    [System.ComponentModel.Category("Serializer-Stream")]
      class Newtonsoft_Stream : CodeBenchmark.IExample
      {
          public void Dispose()
          {
    
          }
          public Task Execute()
          {
              memoryStream.Position = 0;
              var users = User.List(10);
              jsonSerializer.Serialize(jsonTextWriter, users);
              jsonTextWriter.Flush();
    
              return Task.CompletedTask;
          }
    
          private System.IO.MemoryStream memoryStream;
    
          private System.IO.StreamWriter streamWriter;
    
          private Newtonsoft.Json.JsonSerializer jsonSerializer;
    
          private Newtonsoft.Json.JsonTextWriter jsonTextWriter;
    
          public void Initialize(Benchmark benchmark)
          {
              memoryStream = new System.IO.MemoryStream();
              jsonSerializer = new Newtonsoft.Json.JsonSerializer();
              streamWriter = new StreamWriter(memoryStream);
              jsonTextWriter = new Newtonsoft.Json.JsonTextWriter(streamWriter);
          }
      }
  • Utf8Json

    [System.ComponentModel.Category("Serializer-Stream")]
      class Utf8Json_Stream : CodeBenchmark.IExample
      {
          public void Dispose()
          {
          }
    
          public async Task Execute()
          {
              MemoryStream.Position = 0;
              var users = User.List(10);
              await Utf8Json.JsonSerializer.SerializeAsync<List<User>>(MemoryStream, users);
              TextWriter.Flush();
          }
    
          private System.IO.MemoryStream MemoryStream = new System.IO.MemoryStream();
    
          private System.IO.TextWriter TextWriter;
    
          public void Initialize(Benchmark benchmark)
          {
              TextWriter = new System.IO.StreamWriter(MemoryStream, Encoding.UTF8);
          }
      }
  • SwifterJson

    [System.ComponentModel.Category("Serializer-Stream")]
      class Swifter_Stream : CodeBenchmark.IExample
      {
          public void Dispose()
          {
          }
          public async Task Execute()
          {
              MemoryStream.Position = 0;
              var users = User.List(10);
              await Swifter.Json.JsonFormatter.SerializeObjectAsync<List<User>>(users, TextWriter);
              TextWriter.Flush();
          }
    
          private System.IO.MemoryStream MemoryStream = new System.IO.MemoryStream();
    
          private System.IO.TextWriter TextWriter;
    
          public void Initialize(Benchmark benchmark)
          {
              TextWriter = new System.IO.StreamWriter(MemoryStream, Encoding.UTF8);
          }
      }
  • SpanJson

     [System.ComponentModel.Category("Serializer-Stream")]
      class Span_Stream : CodeBenchmark.IExample
      {
          public void Dispose()
          {
    
          }
    
          public async Task Execute()
          {
              var users = User.List(10);
              MemoryStream.Position = 0;
              await SpanJson.JsonSerializer.NonGeneric.Utf8.SerializeAsync(users, MemoryStream);
          }
    
          private System.IO.MemoryStream MemoryStream = new System.IO.MemoryStream();
    
          public void Initialize(Benchmark benchmark)
          {
    
          }
      }

接下來對這幾個邏輯進行2,4,8,16和32的併發壓測(注意:在這裏提醒一下,如果是壓測內存運算數據的情況併發數最好不要超過CPU的邏輯核數,否則會導致組件計數Timer可能沒機會觸發或觸發延時)

 

 

到這裏CodeBenchmark的使用就講解完成,如果有興趣可以關注https://github.com/IKende/CodeBenchmarkDoc

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