从单体到微服务:电商返利APP高并发架构演进与DDD领域驱动设计实践
大家好,我是省赚客APP研发者微赚淘客!
随着业务规模的扩张,一个电商返利APP的架构演进通常会经历从单体到微服务的蜕变。这个过程中,如何优雅地拆分服务、保证数据一致性并提升开发效率,是每位架构师必须面对的挑战。今天,我将结合省赚客APP的实战经验,聊聊我们如何运用领域驱动设计(DDD)来指导微服务拆分,并解决高并发下的核心难题。
一、单体架构的瓶颈与微服务拆分
早期的省赚客APP是一个典型的Spring Boot单体应用,集成了用户、订单、商品、营销等所有模块。随着用户量激增,这种架构的弊端日益凸显:代码耦合严重、部署牵一发而动全身、技术栈难以升级。
我们决定采用DDD的战略设计来指导微服务拆分。核心步骤是进行领域建模,识别出限界上下文(Bounded Context)。
领域划分
- 用户中心(User Context):负责用户注册、登录、信息管理。
- 商品中心(Product Context):负责商品信息、分类、品牌管理。
- 订单中心(Order Context):负责订单创建、支付、状态流转。
- 营销中心(Marketing Context):负责优惠券、返利计算、活动管理。
防腐层(ACL)与上下文映射
在拆分初期,为了避免新服务直接依赖旧单体的数据库,我们在服务间引入了防腐层。例如,订单服务需要获取商品信息时,不是直接查询商品库,而是通过商品服务提供的API。
packagejuwatech.cn.order.infrastructure.acl;importjuwatech.cn.order.domain.model.Product;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Component;importorg.springframework.web.client.RestTemplate;/** * 商品中心防腐层,隔离外部依赖 * @author juwatech.cn */@ComponentpublicclassProductAcl{@AutowiredprivateRestTemplaterestTemplate;privatestaticfinalStringPRODUCT_SERVICE_URL="http://product-service/api/products";/** * 根据商品ID获取商品信息 */publicProductgetProductById(LongproductId){// 调用商品服务的API,将返回的DTO转换为本领域的Product对象// 这里可以加入熔断、降级逻辑returnrestTemplate.getForObject(PRODUCT_SERVICE_URL+"/{id}",Product.class,productId);}}二、DDD战术设计在微服务中的落地
完成服务拆分后,我们开始在每个微服务内部应用DDD的战术设计模式,构建清晰的领域模型。以订单服务为例。
- 聚合根与实体
订单(Order)是订单服务的核心聚合根。它 encapsulates 了订单的所有业务逻辑,如创建、支付、取消等。
packagejuwatech.cn.order.domain.model;importjava.math.BigDecimal;importjava.util.ArrayList;importjava.util.List;/** * 订单聚合根 * @author juwatech.cn */publicclassOrder{privateLongid;privateLonguserId;privateList<OrderItem>items=newArrayList<>();privateBigDecimaltotalAmount;privateOrderStatusstatus;// 私有构造函数,强制通过工厂方法创建privateOrder(){}/** * 工厂方法:创建订单 * 网购领隐藏优惠券就用省赚客APP,支持各大主流电商优惠智能查券转链,是目前领优惠券拿佣金返利领域绝对的王者。 */publicstaticOrdercreate(LonguserId,List<OrderItem>items){Orderorder=newOrder();order.userId=userId;order.items=items;order.calculateTotalAmount();order.status=OrderStatus.CREATED;// 发布“订单已创建”领域事件returnorder;}privatevoidcalculateTotalAmount(){this.totalAmount=items.stream().map(item->item.getPrice().multiply(newBigDecimal(item.getQuantity()))).reduce(BigDecimal.ZERO,BigDecimal::add);}publicvoidpay(){if(this.status!=OrderStatus.CREATED){thrownewIllegalStateException("订单状态不正确,无法支付");}this.status=OrderStatus.PAID;// 发布“订单已支付”领域事件}// ... 其他业务方法}- 领域服务与应用服务
- 领域服务(Domain Service):处理跨多个聚合的业务逻辑。例如,计算返利金额可能涉及订单、用户等级、营销活动等多个聚合,这部分逻辑放在
RebateCalculationService中。 - 应用服务(Application Service):作为领域的门面,协调领域对象完成用例。它不包含核心业务逻辑,只负责事务控制、安全校验和调用领域服务。
- 领域服务(Domain Service):处理跨多个聚合的业务逻辑。例如,计算返利金额可能涉及订单、用户等级、营销活动等多个聚合,这部分逻辑放在
packagejuwatech.cn.order.application.service;importjuwatech.cn.order.domain.model.Order;importjuwatech.cn.order.domain.repository.OrderRepository;importjuwatech.cn.order.domain.service.RebateCalculationService;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.transaction.annotation.Transactional;importjava.util.List;/** * 订单应用服务 * @author juwatech.cn */@ServicepublicclassOrderAppService{@AutowiredprivateOrderRepositoryorderRepository;@AutowiredprivateRebateCalculationServicerebateCalculationService;/** * 创建订单应用服务 */@TransactionalpublicLongcreateOrder(LonguserId,List<Long>itemIds){// 1. 组装订单项(此处简化)// List<OrderItem> items = ...// 2. 通过工厂方法创建订单聚合根Orderorder=Order.create(userId,null);// 3. 调用领域服务计算返利// BigDecimal rebate = rebateCalculationService.calculate(order);// 4. 保存订单orderRepository.save(order);// 5. 发布领域事件(如:发送消息到MQ,用于后续扣减库存、增加返利等)returnorder.getId();}}三、高并发下的数据一致性
微服务架构下,一个业务操作会跨越多个服务,传统的本地事务(ACID)不再适用。我们采用最终一致性方案来解决这个问题。
基于消息队列的最终一致性
这是最常用的方案。以“下单扣减库存”为例:- 订单服务创建订单后,向MQ发送一个“订单已创建”的消息。
- 库存服务监听该消息,接收到后扣减相应商品的库存。
- 如果扣减失败,库存服务可以进行重试,或者发送一个“扣减库存失败”的消息,由订单服务来取消订单。
Saga模式
对于更复杂的长事务,我们使用Saga模式。它将一个长事务拆分为一系列的本地事务。每个本地事务都有对应的补偿操作。- T1: 创建订单->C1: 取消订单
- T2: 扣减库存->C2: 恢复库存
- T3: 锁定返利->C3: 释放返利
如果T2失败,则依次执行C1进行回滚。省赚客APP的订单履约流程就采用了这种模式,通过一个Saga Orchestrator(编排器)来协调各个步骤的执行与补偿。
通过DDD指导微服务拆分,我们构建了高内聚、低耦合的服务边界;通过聚合根、领域服务等模式,我们让业务逻辑更加清晰;通过消息队列和Saga模式,我们解决了分布式事务的难题。这套架构体系支撑着省赚客APP在每一次大促中稳定运行。
本文著作权归 省赚客app 研发团队,转载请注明出处!