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

歡迎訪問 生活随笔!

生活随笔

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

asp.net

在ASP.NET Core微服务架构下使用数据库切分和扩展

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

原文鏈接:https://itnext.io/how-to-use-database-sharding-and-scale-an-asp-net-core-microservice-architecture-22c24916590f

微服務的一大優點是,它們可以獨立擴展。本文展示了擴展一個微服務及其數據庫的好處和挑戰

您將創建一個示例應用程序并手動實現應用程序層分片。它展示了如何根據用例和數據模型選擇分片Key。這有助于將相同的原理應用到具有集成擴展(如MongoDB等)的DBMS上。

1.用例和數據模型

示例應用程序由一個User和Post微服務組成。它們通過消息交流:?

User微服務處理添加和修改用戶。Post微服務處理查看和添加帖子。因為與Post微服務的交互要多得多,所以,當應用程序的負載增加時,Post微服務將成為第一個需要擴展的微服務。

作者的名字是PostService綁定上下文的一部分,因此也是Post微服務的一部分。在User微服務中添加和修改作者。User微服務在添加新用戶或更改用戶名時發送事件。

PostService的邏輯數據模型

用戶可以分類寫文章。他們還可以按類別閱讀帖子,包括作者姓名。最新的帖子在上面。分類是固定的,很少改變。

基于這些用例,我決定按類別劃分數據庫分片:

2.實現微服務

創建解決方案并添加名為“PostService”的ASP.NET Core 5 Web API項目。禁用HTTPS并激活OpenAPI支持。

安裝以下NuGet軟件包:

  • Microsoft.EntityFrameworkCore.Tools

  • MySql.EntityFrameworkCore

  • Newtonsoft.Json

創建實體

Post實體的索引可以加快檢索某個類別中最新的帖子:

using?Microsoft.EntityFrameworkCore; using?System.ComponentModel.DataAnnotations;namespace?PostService.Entities {[Index(nameof(PostId),?nameof(CategoryId))]public?class?Post{public?int?PostId?{?get;?set;?}public?string?Title?{?get;?set;?}public?string?Content?{?get;?set;?}public?int?UserId?{?get;?set;?}public?User?User?{?get;?set;?}[Required]public?string?CategoryId?{?get;?set;?}public?Category?Category?{?get;?set;?}} }

User實體中的版本稍后將幫助處理無序消息:

namespace?PostService.Entities {public?class?User{public?int?ID?{?get;?set;?}public?string?Name?{?get;?set;?}public?int?Version?{?get;?set;?}} }namespace?PostService.Entities {public?class?Category{public?string?CategoryId?{?get;?set;?}} }

創建PostServiceContext

using?Microsoft.EntityFrameworkCore;namespace?PostService.Data {public?class?PostServiceContext?:?DbContext{private?readonly?string?_connectionString;public?PostServiceContext(string?connectionString){_connectionString?=?connectionString;}protected?override?void?OnConfiguring(DbContextOptionsBuilder?optionsBuilder){optionsBuilder.UseMySQL(_connectionString);}public?DbSet<PostService.Entities.Post>?Post?{?get;?set;?}public?DbSet<PostService.Entities.User>?User?{?get;?set;?}public?DbSet<PostService.Entities.Category>?Category?{?get;?set;?}} }

在appsettings.Development.json中添加連接字符串(在調試期間將使用兩個分片)

{"Logging":?{"LogLevel":?{"Default":?"Information","Microsoft":?"Warning","Microsoft.Hosting.Lifetime":?"Information"}},"PostDbConnectionStrings":?{"Shard0":?"server=localhost;?port=3310;?database=post;?user=root;?password=pw;?Persist?Security?Info=False;?Connect?Timeout=300","Shard1":?"server=localhost;?port=3311;?database=post;?user=root;?password=pw;?Persist?Security?Info=False;?Connect?Timeout=300"????} }

添加DataAccess代碼

GetConnectionString(string category)計算CategoryId的哈希值。哈希的第一部分將配置的分片數(連接字符串)取模,從而確定給定類別的分片。

InitDatabase刪除并重新創建所有分片中的所有表,并插入虛擬用戶和類別。

其他方法用于創建和加載帖子。

using?Microsoft.AspNetCore.Mvc; using?Microsoft.EntityFrameworkCore; using?Microsoft.Extensions.Configuration; using?PostService.Entities; using?System; using?System.Collections.Generic; using?System.Linq; using?System.Security.Cryptography; using?System.Text; using?System.Threading.Tasks;namespace?PostService.Data {public?class?DataAccess{private?readonly?List<string>?_connectionStrings?=?new?List<string>();public?DataAccess(IConfiguration?configuration){var?connectionStrings?=?configuration.GetSection("PostDbConnectionStrings");foreach(var?connectionString?in?connectionStrings.GetChildren()){Console.WriteLine("ConnectionString:?"?+?connectionString.Value);_connectionStrings.Add(connectionString.Value);}}public?async?Task<ActionResult<IEnumerable<Post>>>?ReadLatestPosts(string?category,?int?count){using?var?dbContext?=?new?PostServiceContext(GetConnectionString(category));return?await?dbContext.Post.OrderByDescending(p?=>?p.PostId).Take(count).Include(x?=>?x.User).Where(p?=>?p.CategoryId?==?category).ToListAsync();}public?async?Task<int>?CreatePost(Post?post){using?var?dbContext?=?new?PostServiceContext(GetConnectionString(post.CategoryId));dbContext.Post.Add(post);return?await?dbContext.SaveChangesAsync();}public?void?InitDatabase(int?countUsers,?int?countCategories){foreach?(var?connectionString?in?_connectionStrings){using?var?dbContext?=?new?PostServiceContext(connectionString);dbContext.Database.EnsureDeleted();dbContext.Database.EnsureCreated();for?(int?i?=?1;?i?<=?countUsers;?i++){dbContext.User.Add(new?User?{?Name?=?"User"?+?i,?Version?=?1?});dbContext.SaveChanges();}for?(int?i?=?1;?i?<=?countCategories;?i++){dbContext.Category.Add(new?Category?{?CategoryId?=?"Category"?+?i?});dbContext.SaveChanges();}}}private?string?GetConnectionString(string?category){using?var?md5?=?MD5.Create();var?hash?=?md5.ComputeHash(Encoding.ASCII.GetBytes(category));var?x?=?BitConverter.ToUInt16(hash,?0)?%?_connectionStrings.Count;return??_connectionStrings[x];}} }

在Startup.cs中將DataAccess注冊為單例

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

創建PostController

它使用DataAccess類

using?Microsoft.AspNetCore.Mvc; using?PostService.Data; using?PostService.Entities; using?System.Collections.Generic; using?System.Threading.Tasks;namespace?PostService.Controllers {[Route("api/[controller]")][ApiController]public?class?PostsController?:?ControllerBase{private?readonly?DataAccess?_dataAccess;public?PostsController(DataAccess?dataAccess){_dataAccess?=?dataAccess;}[HttpGet]public?async?Task<ActionResult<IEnumerable<Post>>>?GetLatestPosts(string?category,?int?count){return?await?_dataAccess.ReadLatestPosts(category,?count);}[HttpPost]public?async?Task<ActionResult<Post>>?PostPost(Post?post){await?_dataAccess.CreatePost(post);return?NoContent();}[HttpGet("InitDatabase")]public?void?InitDatabase([FromQuery]?int?countUsers,?[FromQuery]?int?countCategories){_dataAccess.InitDatabase(countUsers,?countCategories);}} }

3. 用PostService訪問數據庫

安裝Docker Desktop。

創建兩個MySql容器

C:\dev>docker?run?-p?3310:3306?--name=mysql1?-e?MYSQL_ROOT_PASSWORD=pw?-d?mysql:5.6 C:\dev>docker?run?-p?3311:3306?--name=mysql2?-e?MYSQL_ROOT_PASSWORD=pw?-d?mysql:5.6

在Visual Studio中啟動Post服務。瀏覽器在打開http://localhost:5001/swagger/index.html

使用swagger UI與服務交互:

初始化包含100個用戶和10個類別的數據庫:?

在“Category1”下增加一個帖子:

{"title":?"MyTitle","content":?"MyContent","userId":?1,"categoryId":?"Category1" }

閱讀“Category1”中排名前10位的帖子:

連接到數據庫容器并驗證哪個數據庫包含新的帖子

C:\dev>docker?container?exec?-it?mysql1?/bin/sh

使用密碼“pw”登錄MySql并讀取帖子:?

第二個實例不包含任何帖子:

C:\dev>docker?container?exec?-it?mysql2?/bin/sh

4.最后的想法和展望

您創建了一個可工作的應用程序,實現了應用程序層分片,并使用了分片Key的概念。

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

在第二部分中,您將縮放并運行微服務和數據庫的多個容器實例。您將使用docker compose和負載平衡器。然后,您將運行JMeter負載測試,以查看應用程序在使用不同數量的實例時是如何伸縮的。最后,您將通過RabbitMQ模擬來自用戶微服務的用戶事件。

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

總結

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

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