eShopOnContainers 知多少[4]:Catalog microservice

本文深入探讨了目录微服务的设计与实现,涵盖产品信息维护、库存更新及价格管理。采用ASP.NET Core Web API与Entity Framework Core搭建CRUD微服务,通过SQL Server存储数据,利用Swashbuckle、Autofac、Eventbus和Polly增强服务功能。文章还介绍了实体建模、数据库优化及最终一致性实现策略。

引言

Catalog microservice(目录微服务)维护着所有产品信息,包括库存、价格。所以该微服务的核心业务为:

  1. 产品信息的维护

  2. 库存的更新

  3. 价格的维护

架构模式

640?wx_fmt=png

如上图所示,本微服务采用简单的数据驱动的CRUD微服务架构,来执行产品信息的创建、读取、更新和删除(CRUD)操作。 这种类型的服务在单个 ASP.NET Core Web API 项目中即可实现所有功能,该项目包括数据模型类、业务逻辑类及其数据访问类。其项目结构如下:640?wx_fmt=png

核心技术选型:

  1. ASP.NET Core Web API

  2. Entity Framework Core

  3. SQL Server

  4. Swashbuckle(可选)

  5. Autofac

  6. Eventbus

  7. Polly

实体建模

该微服务的核心领域实体是商品,其类图如下:640?wx_fmt=png

对于实体这一块,有两个小知识点需要说明一下:

1. 进行数据库字段映射时,主键都使用了 ForSqlServerUseSequenceHiLo指定使用 HI-LO高低位序列进行主键生成。

2. 在进行种子数据的预置时,使用了 Polly开启了Retry机制。


 
  1. private Policy CreatePolicy( ILogger<CatalogContextSeed> logger, string prefix,int retries = 3)

  2. {

  3.    return Policy.Handle<SqlException>().

  4.        WaitAndRetryAsync(

  5.            retryCount: retries,

  6.            sleepDurationProvider: retry => TimeSpan.FromSeconds(5),

  7.            onRetry: (exception, timeSpan, retry, ctx) =>

  8.            {

  9.                logger.LogTrace($"[{prefix}] Exception {exception.GetType().Name} with message ${exception.Message} detected on attempt {retry} of {retries}");

  10.            }

  11.        );

  12. }

  13. public async Task SeedAsync(CatalogContext context,IHostingEnvironment env,IOptions<CatalogSettings> settings,ILogger<CatalogContextSeed> logger)

  14. {

  15.    var policy = CreatePolicy(logger, nameof(CatalogContextSeed));

  16.    await policy.ExecuteAsync(async () =>

  17.    {

  18.        //...

  19.    });      

  20. }

3. 使用NoTracking提升查询速度 在 CatalogController的构造方法中,明确指定以下代码来进行查询优化,这一点也是我们值得学习的地方。


 
  1. ((DbContext)context).ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

数据库表结构

640?wx_fmt=png你肯定会好奇为什么会多了一张 IntegrationEventLog表,这里先按住不表。

最后

如果eShopOnContainers采用的是单体式应用架构而非微服务架构,那么以上业务逻辑的实现并不复杂,使用简单的CRUD再辅以ACID事务就能很好的完成业务需求。本文的介绍也就可以到此为止了。

然而将其抽取出来成为独立的基础微服务,那么我们要考虑的问题就多了。比如:

  1. 修改产品价格时,需要同步更新购物车中保存的产品信息的价格。

  2. 下订单时,需要验证当前商品库存是否充足,进行锁库抢占,以避免库存不足导致的订单无效。

而这一切我们都不能再享受单体应用中直接使用ACID事务的便利了。因为在微服务应用里,产品表和购物篮表被各自的微服务所占有。任何微服务不应该在自己的事务中包含其他微服务的表或存储,即使是直接查询也是不可以的。目录微服务不能直接更新购物篮表,因为购物篮表被购物篮微服务占有。要更新购物篮微服务,产品微服务应该使用基于异步通信,如集成事件(消息和基于事件的通信)来实现最终一致性。

那下一节我们就来详细阐述eShopOnContainers是如何通过事件机制完成最终一致性的。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值