从单体到微服务:淘客返利系统的演进路径与拆分边界划分原则

从单体到微服务:淘客返利系统的演进路径与拆分边界划分原则

大家好,我是 微赚淘客系统3.0 的研发者省赚客!

微赚淘客系统1.0最初采用Spring Boot单体架构,所有功能(用户、订单、返利、通知、对账)耦合在同一个应用中。随着业务量激增,系统面临发布效率低、故障隔离差、数据库锁竞争严重等问题。我们基于领域驱动设计(DDD)思想,逐步演进为微服务架构,并确立了清晰的拆分边界与通信规范。

一、识别核心子域与限界上下文

通过事件风暴(Event Storming)梳理业务流程,我们将系统划分为以下限界上下文(Bounded Context):

  • 用户中心(User Context):注册、登录、邀请关系
  • 商品中心(Item Context):商品同步、类目管理
  • 订单中心(Order Context):订单抓取、状态跟踪
  • 返利中心(Rebate Context):规则匹配、金额计算、发放
  • 通知中心(Notify Context):微信模板、短信推送
  • 对账中心(Settlement Context):日结、月结、财务报表

每个上下文对应一个独立微服务,拥有专属数据库,禁止跨库JOIN。

二、数据库垂直拆分与数据一致性保障

原单体MySQL库被拆分为6个独立实例。以"返利发放"为例,需保证订单状态更新与返利记录写入的一致性。我们采用本地消息表 + 最终一致性方案:

java 复制代码
// 返利服务:写本地消息表
@Transactional
public void processOrderConfirmed(String orderId) {
    RebateRecord record = calculateRebate(orderId);
    rebateMapper.insert(record);

    // 写入本地消息表
    juwatech.cn.rebate.dao.MessageLogMapper.insert(
        new MessageLog("notify_user", JSON.toJSONString(record), "PENDING")
    );
}

// 后台任务:投递消息到MQ
@Scheduled(fixedDelay = 1000)
public void deliverMessages() {
    List<MessageLog> logs = messageLogMapper.selectPending(100);
    for (MessageLog log : logs) {
        try {
            juwatech.cn.mq.RabbitProducer.send("rebate.notify", log.getContent());
            messageLogMapper.markAsSent(log.getId());
        } catch (Exception e) {
            // 重试或告警
        }
    }
}

通知服务消费消息后,执行用户触达,实现跨服务最终一致。

三、API网关与服务通信

前端请求统一由Spring Cloud Gateway路由:

yaml 复制代码
# gateway.yml
spring:
  cloud:
    gateway:
      routes:
        - id: rebate-service
          uri: lb://rebate-service
          predicates:
            - Path=/api/v1/rebates/**
          filters:
            - StripPrefix=1

内部服务间调用采用Feign + Resilience4j熔断:

java 复制代码
@FeignClient(name = "order-service", fallback = OrderClientFallback.class)
public interface OrderClient {
    @GetMapping("/internal/orders/{orderId}")
    OrderDTO getOrder(@PathVariable String orderId);
}

@Component
public class OrderClientFallback implements OrderClient {
    public OrderDTO getOrder(String orderId) {
        throw new ServiceUnavailableException("Order service unavailable");
    }
}

关键链路(如返利计算)强制走gRPC以提升性能:

java 复制代码
// 在 juwatech.cn.grpc 包下定义 proto
service RebateService {
  rpc CalculateRebate (CalculateRequest) returns (CalculateResponse);
}

四、拆分边界划分原则

我们在实践中总结出以下拆分准则:

  1. 高内聚低耦合:同一业务实体的操作应归属同一服务(如返利规则与计算逻辑不得分离)
  2. 数据自治:每个服务独占数据库,通过API或事件共享数据
  3. 团队对齐:一个微服务由一个2~5人小团队全生命周期负责
  4. 变更频率一致:高频迭代模块(如返利策略)独立部署,避免牵连稳定模块(如用户体系)

例如,早期将"邀请返利"与"购物返利"混在同一模块,导致策略调整需全量回归。拆分后,juwatech.cn.rebate.invitejuwatetech.cn.rebate.shopping 各自独立演进。

五、遗留单体渐进式解耦

对于无法立即拆分的复杂模块(如老版对账),我们采用绞杀者模式(Strangler Fig Pattern)

  1. 新功能在微服务中实现
  2. 通过反向代理将新流量导向新服务
  3. 逐步迁移旧数据并下线单体接口
java 复制代码
// 单体中的适配层(临时)
@RestController
public class LegacyRebateController {
    @Autowired
    private juwatech.cn.rebate.newservice.RebateFacade newRebateFacade;

    @GetMapping("/old/rebate/calc")
    public ResponseEntity<?> calc(@RequestParam String orderId) {
        // 路由到新服务
        return newRebateFacade.calculate(orderId);
    }
}

同时,使用Apache ShardingSphere实现读写分离与分库分表,缓解单库压力。

六、可观测性与链路追踪

微服务拆分后,问题定位难度上升。我们集成SkyWalking实现全链路追踪:

java 复制代码
// 在各服务 bootstrap.yml 中配置
agent:
  service_name: ${spring.application.name}
  collector:
    backend_service: skywalking-oap:11800

关键方法添加自定义Span:

java 复制代码
@Trace
public void handleRebateTask(RebateTask task) {
    ActiveSpan.tag("order.id", task.getOrderId());
    // 业务逻辑
}

配合Prometheus+Grafana监控各服务QPS、错误率、延迟,确保拆分后稳定性不降反升。

本文著作权归 微赚淘客系统3.0 研发团队,转载请注明出处!

相关推荐
郑州光合科技余经理2 小时前
同城配送调度系统实战:JAVA微服务
java·开发语言·前端·后端·微服务·中间件·php
乾元2 小时前
绕过艺术:使用 GANs 对抗 Web 防火墙(WAF)
前端·网络·人工智能·深度学习·安全·架构
ProgrammerPulse3 小时前
K8s 运维告别 “猜谜游戏”:青云云易捷v6.0对接 K8sGPT,AI 赋能一键解锁智能诊断
云原生
勇往直前plus3 小时前
大模型开发手记(二):基于 LangChain 的 RAG 架构全面解析与落地实践
架构·langchain
想搞艺术的程序员4 小时前
架构破局 - Redis 不再做缓存!替代 MySQL 做主存储
redis·缓存·架构
星图易码4 小时前
星图云开发者平台功能详解 | 微服务管理器:异构服务零门槛无缝集成
微服务·云原生·架构
星辰_mya4 小时前
Netty
java·架构·io
●VON4 小时前
Flutter for OpenHarmony:基于 SharedPreferences 的本地化笔记应用架构与实现
笔记·学习·flutter·ui·架构·openharmony·von
heartbeat..4 小时前
Redis Cluster (Redis 集群模式)从入门到精通:架构解析、机制详解与运维排查
java·运维·redis·架构·nosql