日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

在ASP.NET Core微服务架构下使用数据库切分和扩展, 并用JMeter进行负载测试

發布時間:2023/12/4 asp.net 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在ASP.NET Core微服务架构下使用数据库切分和扩展, 并用JMeter进行负载测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

原文鏈接:https://itnext.io/how-to-scale-an-asp-net-core-microservice-and-sharded-database-load-test-with-jmeter-1a8c7292e7e3

現在,您將擴展應用程序并運行多個微服務和數據庫的容器實例。您將使用Docker Compose和HAProxy負載均衡器:?

然后運行JMeter負載測試,以查看應用程序在使用不同數量的實例時如何伸縮。最后,您還將發布和接收來自RabbitMQ的消息。

1.運行多個數據庫和微服務實例

將微服務容器化

使用上一篇文章中的代碼和環境作為基礎。

將Visual Studio解決方案資源管理器中的文件“Dockerfile”重命名為“dockerfile”(第一個字符小寫)。然后右鍵單擊Docker文件并選擇“創建Docker鏡像”。這也會將鏡像推送到docker。

在Docker中運行應用程序

創建docker-compose.yml文件:

version:?'2' services:webservice:image:?'postservice:latest'???cpus:?0.5scale:?4environment:-?PostDbConnectionStrings__Shard0=server=database0;?port=3306;?database=post;?user=root;?password=pw;?Persist?Security?Info=False;?Connect?Timeout=300??????-?PostDbConnectionStrings__Shard1=server=database1;?port=3306;?database=post;?user=root;?password=pw;?Persist?Security?Info=False;?Connect?Timeout=300???#??-?PostDbConnectionStrings__Shard2=server=database2;?port=3306;?database=post;?user=root;?password=pw;?Persist?Security?Info=False;?Connect?Timeout=300???loadbalancer:image:?dockercloud/haproxylinks:-?webservicevolumes:-?/var/run/docker.sock:/var/run/docker.sockports:-?5001:80database0:image:?'mysql:5.6'cpus:?0.5ports:-?3312:3306environment:-?MYSQL_ROOT_PASSWORD=pwdatabase1:image:?'mysql:5.6'cpus:?0.5ports:-?3313:3306environment:-?MYSQL_ROOT_PASSWORD=pwdatabase2:image:?'mysql:5.6'cpus:?0.5ports:-?3314:3306environment:-?MYSQL_ROOT_PASSWORD=pw????

docker文件配置3個數據庫容器和4個Post服務實例。目前,Post服務實例只使用了2個數據庫。稍后可以刪除注釋以使用第三個數據庫。HAProxy負載均衡器公開端口5001上的Post服務容器。

每個容器有0.5cpu的限制,以幫助在本地機器上進行實際的負載測試。在我的12核筆記本上,仍然有未使用的資源,因此添加更多的服務和數據庫實例可以帶來好處。

啟動應用程序

C:\dev>docker-compose?up?-d

初始化數據庫

打開瀏覽器訪問http://localhost:5001/swagger/index.html

初始化至少有100個用戶和10個類別的數據庫。

您可以創建更多的用戶和類別,但由于CPU的限制,這需要一些時間。

2.縮放應用程序并使用JMeter進行負載測試

創建JMeter測試計劃

安裝并打開JMeter。

創建測試計劃和線程組:?

32個線程是一個很好的開始。在線程的每個循環上,它添加一個帖子并讀取10個帖子。

添加HTTP請求以創建帖子:?

  • Servername: localhost

  • Port: 5001

  • HTTP-Request: POST

  • Path: /api/Posts

  • Body Data:

{"title":?"MyTitle","content":?"MyContent","userId":?${__Random(1,100)},"categoryId":?"Category${__Random(1,10)}" }

它為隨機用戶(ID 1–100)和類別(1–10)創建一個帖子。

向請求添加內容類型application/json HTTP頭:?

隨機閱讀10篇文章:

  • Servername: localhost

  • Port: 5001

  • HTTP-Request: GET

  • Path: /api/Posts

  • Send Parameters with the Request:

NAME?|?VALUE?|?CONTENT-TYPE category?|?Category${__Random(1,10)}?|?text/plain count?|?10?|?text/plain

運行測試

在測試運行時查看摘要報告:?

等待一段時間,直到平均值(響應時間)和吞吐量穩定。

修改測試參數

停止JMeter中的測試。

您可以更改測試計劃中的線程。將它們提升到64或128個線程。或者將線程數減少到16甚至1。

在編輯docker-compose.yml之前關閉應用程序:

C:\dev>docker-compose?down

您可以通過“scale”屬性更改Post服務實例的數量。更改數據庫數的“environment”屬性(添加/刪除注釋):

更改后啟動應用程序:

C:\dev>docker-compose?up?-d

數據庫服務器運行需要一段時間。并記住初始化數據庫:?

3.試驗結果示例

在我的電腦上,兩個Post服務與一個數據庫的比率會產生很好的效果。我可以將它擴展到六個服務和三個數據庫,直到我的硬件達到極限。平均時間保持在500ms以下。增加高于64的線程會產生錯誤。

結果取決于我的環境和CPU限制。它們在你的機器上是不同的。

每秒吞吐量與實例數成比例:?

在CPU受限的容器中,每秒305個請求,每天大約有2500萬個請求。這將允許100萬用戶每天寫10篇帖子和閱讀帖子。當然,現實生活中的應用程序會更復雜,但我希望示例能夠顯示基本的思想。

4.微服務間通信和復制用戶更改

Post服務通過Rabbitmq消息從User微服務接收對用戶的更改:?

你也可以用JMeter來模擬。

創建RabbitMQ容器

發出以下命令(在控制臺窗口中)以啟動具有管理UI的RabbitMQ容器

C:\dev>docker?run?-d??-p?15672:15672?-p?5672:5672?-e?RABBITMQ_DEFAULT_USER=test?-e?RABBITMQ_DEFAULT_PASS=test?--hostname?my-rabbit?--name?some-rabbit?rabbitmq:3-management

該命令將“test”配置為用戶和密碼,而不是默認的Guest賬戶。Guest僅限于localhost,但在docker中,容器位于不同的主機上。

修改后微服務

在Visual Studio中安裝RabbitMQ.Client NuGet包。

添加IntegrationEventListenerService類:

using?Microsoft.Extensions.Hosting; using?Newtonsoft.Json.Linq; using?PostService.Data; using?PostService.Entities; using?RabbitMQ.Client; using?RabbitMQ.Client.Events; using?System; using?System.Collections.Generic; using?System.Text; using?System.Threading; using?System.Threading.Tasks;namespace?PostService {public?class?IntegrationEventListenerService?:?BackgroundService{private?async?Task?ListenForIntegrationEvents(CancellationToken?stoppingToken){try{ConnectionFactory?factory?=?new?ConnectionFactory{UserName?=?"test",Password?=?"test"};var?endpoints?=?new?System.Collections.Generic.List<AmqpTcpEndpoint>?{new?AmqpTcpEndpoint("host.docker.internal"),new?AmqpTcpEndpoint("localhost")};var?connection?=?factory.CreateConnection(endpoints);var?channel?=?connection.CreateModel();var?consumer?=?new?EventingBasicConsumer(channel);var?arguments?=?new?Dictionary<String,?object>{{?"x-single-active-consumer",?true?}};channel.QueueDeclare("user.postservicesingleactiveconsumer",?false,?false,?false,?arguments);channel.ExchangeDeclare("userloadtest",?"fanout");channel.QueueBind("user.postservicesingleactiveconsumer",?"userloadtest",?"");consumer.Received?+=?(model,?ea)?=>{var?body?=?ea.Body.ToArray();var?message?=?Encoding.UTF8.GetString(body);Console.WriteLine("IntegrationEvent?{0}",?message);var?data?=?JObject.Parse(message);var?type?=?ea.RoutingKey;var?user?=?new?User(){ID?=?data["id"].Value<int>(),Name?=?data["name"].Value<string>(),Version?=?data["version"].Value<int>()};if?(type?==?"user.add"){_dataAccess.AddUser(user);}else?if?(type?==?"user.update"){_dataAccess.UpdateUser(user);}channel.BasicAck(ea.DeliveryTag,?false);};channel.BasicConsume(queue:?"user.postservicesingleactiveconsumer",autoAck:?false,consumer:?consumer);try{await?Task.Delay(Timeout.Infinite,?stoppingToken);}catch?(OperationCanceledException){Console.WriteLine("Shutting?down.");}}catch?(Exception?e){Console.WriteLine(e.ToString());}}private?readonly?DataAccess?_dataAccess;public?IntegrationEventListenerService(DataAccess?dataAccess){_dataAccess?=?dataAccess;}protected?override?async?Task?ExecuteAsync(CancellationToken?stoppingToken){while?(!stoppingToken.IsCancellationRequested){await?ListenForIntegrationEvents(stoppingToken);}}} }

后臺服務使用“test”帳戶訪問RabbitMQ和host.docker.internal以及localhost作為主機。這允許從容器和Visual Studio調試器內部進行連接。

單個活動的消費者保證只有一個Post-service實例接收消息。

如果活動的實例崩潰,那么下一個實例將接管。稍后可以通過停止docker中當前接收的實例來嘗試。

如果exchange和管道尚不存在,則代碼將創建它們。它使用手動確認。

修改Startup.cs以運行IntegrationEventListenerService:

public?void?ConfigureServices(IServiceCollection?services){services.AddControllers();services.AddSwaggerGen(c?=>{c.SwaggerDoc("v1",?new?OpenApiInfo?{?Title?=?"PostService",?Version?=?"v1"?});});services.AddSingleton<DataAccess>();services.AddSingleton<IntegrationEventListenerService>();services.AddHostedService<IntegrationEventListenerService>(provider?=>?provider.GetService<IntegrationEventListenerService>());}

在Docker中運行已更改的微服務

關閉docker中的應用程序:

C:\dev>docker-compose?down

編譯Post服務,將其容器化并發布到docker。

更改后啟動應用程序:

C:\dev>docker-compose?up?-d

數據庫服務器運行需要一段時間。并記住初始化數據庫:?

修改JMeter測試

在JMeter測試計劃中,添加一個只有一個線程的線程組:?

添加計時器:

恒定計時器將測試限制為每秒一條消息。每秒一條消息非常常見。即使半年內有100萬用戶注冊,每分鐘也只有4個新用戶。

添加HTTP請求以將消息發布到RabbitMQ:?

  • Servername: localhost

  • Port: 15672

  • HTTP-Request: POST

  • Path: /api/exchanges/%2F/userloadtest/publish

  • Body Data:

{"properties":{},"routing_key":"user.update","payload":"{id:1,name:\"NewName${__counter(TRUE,)}\",version:${__counter(TRUE,)}}","payload_encoding":"string" }

用戶實體有一個version字段來處理無序消息。為了保持測試的簡單性,它只更新單個用戶并增加version字段的值。性能影響應該保持不變。

將Content-Type和對RabbitMQ的授權添加到HTTP頭。?

Content-Type?|?application/json Authorization?|?Basic?dGVzdDp0ZXN0

*“dGVzdDp0ZXN0”是base64編碼的用戶和密碼“test”。

運行測試

吞吐量應該與前面的測試類似。

您還可以通過查看控制臺輸出來識別docker中的活動的RabbitMQ消費者。您可以停止容器,則另一個實例將接管消息處理。

5.最后的想法和展望

您創建了一個微服務架構并實現了應用層數據庫分片。然后用多個容器實例擴展應用程序并對其進行負載測試。您還用RabbitMQ處理了用戶更改事件。

這只是一個示例應用程序。您必須調整代碼才能在生產環境中使用它。

下一步是什么?要獲取帖子最多的前10個類別的數據,需要查詢多個數據庫實例。這可能會導致延遲和性能下降。Redis可以是查詢聚合數據的解決方案。我將在下一篇文章中展示它。

歡迎關注我的個人公眾號”My IO“

總結

以上是生活随笔為你收集整理的在ASP.NET Core微服务架构下使用数据库切分和扩展, 并用JMeter进行负载测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。