eShopOnContainers 知多少[4]:Catalog microservice
引言
Catalog microservice(目錄微服務(wù))維護(hù)著所有產(chǎn)品信息,包括庫(kù)存、價(jià)格。所以該微服務(wù)的核心業(yè)務(wù)為:
產(chǎn)品信息的維護(hù)
庫(kù)存的更新
價(jià)格的維護(hù)
架構(gòu)模式
如上圖所示,本微服務(wù)采用簡(jiǎn)單的數(shù)據(jù)驅(qū)動(dòng)的CRUD微服務(wù)架構(gòu),來(lái)執(zhí)行產(chǎn)品信息的創(chuàng)建、讀取、更新和刪除(CRUD)操作。 這種類(lèi)型的服務(wù)在單個(gè) ASP.NET Core Web API 項(xiàng)目中即可實(shí)現(xiàn)所有功能,該項(xiàng)目包括數(shù)據(jù)模型類(lèi)、業(yè)務(wù)邏輯類(lèi)及其數(shù)據(jù)訪(fǎng)問(wèn)類(lèi)。其項(xiàng)目結(jié)構(gòu)如下:
核心技術(shù)選型:
ASP.NET Core Web API
Entity Framework Core
SQL Server
Swashbuckle(可選)
Autofac
Eventbus
Polly
實(shí)體建模
該微服務(wù)的核心領(lǐng)域?qū)嶓w是商品,其類(lèi)圖如下:
對(duì)于實(shí)體這一塊,有兩個(gè)小知識(shí)點(diǎn)需要說(shuō)明一下:
1. 進(jìn)行數(shù)據(jù)庫(kù)字段映射時(shí),主鍵都使用了?ForSqlServerUseSequenceHiLo指定使用?HI-LO高低位序列進(jìn)行主鍵生成。
2. 在進(jìn)行種子數(shù)據(jù)的預(yù)置時(shí),使用了?Polly開(kāi)啟了Retry機(jī)制。
private Policy CreatePolicy( ILogger<CatalogContextSeed> logger, string prefix,int retries = 3)
{
? ?return Policy.Handle<SqlException>().
? ? ? ?WaitAndRetryAsync(
? ? ? ? ? ?retryCount: retries,
? ? ? ? ? ?sleepDurationProvider: retry => TimeSpan.FromSeconds(5),
? ? ? ? ? ?onRetry: (exception, timeSpan, retry, ctx) =>
? ? ? ? ? ?{
? ? ? ? ? ? ? ?logger.LogTrace($"[{prefix}] Exception {exception.GetType().Name} with message ${exception.Message} detected on attempt {retry} of {retries}");
? ? ? ? ? ?}
? ? ? ?);
}
public async Task SeedAsync(CatalogContext context,IHostingEnvironment env,IOptions<CatalogSettings> settings,ILogger<CatalogContextSeed> logger)
{
? ?var policy = CreatePolicy(logger, nameof(CatalogContextSeed));
? ?await policy.ExecuteAsync(async () =>
? ?{
? ? ? ?//...
? ?}); ? ? ?
}
3. 使用NoTracking提升查詢(xún)速度 在?CatalogController的構(gòu)造方法中,明確指定以下代碼來(lái)進(jìn)行查詢(xún)優(yōu)化,這一點(diǎn)也是我們值得學(xué)習(xí)的地方。
((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
數(shù)據(jù)庫(kù)表結(jié)構(gòu)
你肯定會(huì)好奇為什么會(huì)多了一張 IntegrationEventLog表,這里先按住不表。
最后
如果eShopOnContainers采用的是單體式應(yīng)用架構(gòu)而非微服務(wù)架構(gòu),那么以上業(yè)務(wù)邏輯的實(shí)現(xiàn)并不復(fù)雜,使用簡(jiǎn)單的CRUD再輔以ACID事務(wù)就能很好的完成業(yè)務(wù)需求。本文的介紹也就可以到此為止了。
然而將其抽取出來(lái)成為獨(dú)立的基礎(chǔ)微服務(wù),那么我們要考慮的問(wèn)題就多了。比如:
修改產(chǎn)品價(jià)格時(shí),需要同步更新購(gòu)物車(chē)中保存的產(chǎn)品信息的價(jià)格。
下訂單時(shí),需要驗(yàn)證當(dāng)前商品庫(kù)存是否充足,進(jìn)行鎖庫(kù)搶占,以避免庫(kù)存不足導(dǎo)致的訂單無(wú)效。
而這一切我們都不能再享受單體應(yīng)用中直接使用ACID事務(wù)的便利了。因?yàn)樵谖⒎?wù)應(yīng)用里,產(chǎn)品表和購(gòu)物籃表被各自的微服務(wù)所占有。任何微服務(wù)不應(yīng)該在自己的事務(wù)中包含其他微服務(wù)的表或存儲(chǔ),即使是直接查詢(xún)也是不可以的。目錄微服務(wù)不能直接更新購(gòu)物籃表,因?yàn)橘?gòu)物籃表被購(gòu)物籃微服務(wù)占有。要更新購(gòu)物籃微服務(wù),產(chǎn)品微服務(wù)應(yīng)該使用基于異步通信,如集成事件(消息和基于事件的通信)來(lái)實(shí)現(xiàn)最終一致性。
那下一節(jié)我們就來(lái)詳細(xì)闡述eShopOnContainers是如何通過(guò)事件機(jī)制完成最終一致性的。
總結(jié)
以上是生活随笔為你收集整理的eShopOnContainers 知多少[4]:Catalog microservice的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Docker最全教程——从理论到实战(二
- 下一篇: OrchardCore 如何实现模块化(