高并发下别再这样写 Service!

54 阅读3分钟

沉默是金,总会发光

大家好,我是沉默

想象一下——
凌晨 3 点,手机被警报震醒:

  1. 订单服务响应时间飙升到 5 秒

  2. 数据库 CPU 100% 拉满

  3. 一堆秒杀用户疯狂点 F5,客服群已经被骂爆

你颤抖着打开代码,结果映入眼帘的是一个 5000 行的“ Service”

  • if-else 嵌套 10 层
  • try-catch 嵌套 5 层
  • 新人看一眼就崩溃

此时此刻,你终于体会到:

线上崩溃,90% 都是“屎山类”在作妖。

**-**01-

一个“ Service”如何拖垮系统?

以秒杀下单为例,本来逻辑很清晰:

  1. 检查库存
  2. 校验用户
  3. 扣减库存
  4. 生成订单
  5. 发送通知

但“ Service”的写法是这样的

@Servicepublic class OrderService {    // 5000行代码的上帝类...    public Result createOrder(OrderDTO dto) {        // 200行库存校验        if(itemStock <= 0) {...}        if(activityTimeExpired) {...}        if(userBlacklisted) {...}        // 300行优惠券逻辑        if(couponType == 1) {...}        else if(couponType == 2) {...}        // 400行订单创建        try {            // 嵌套5层try-catch        } catch (Exception e) {            return Result.fail("系统繁忙");        }    }}

致命问题:

  • 单点故障:任何修改都可能引爆全局

  • 性能瓶颈:同步阻塞,没法抗高并发

  • 维护地狱:一个 bug 修 1 天,线上炸 3 次

- 02-

如何让 Service 变轻?

1 战略分层:DDD 重构后的目录结构

src├── application  # 应用服务(流程编排)│   ├── OrderAppService.java├── domain       # 领域层│   ├── model    # 聚合根/实体│   ├── service  # 领域服务│   ├── event    # 领域事件├── infrastructure # 基础设施│   ├── repository # 仓储实现

流程图:对比重构前后的调用方式

图片

2 关键代码

应用服务层:只管“编排”

@Service@RequiredArgsConstructorpublic class OrderAppService {    private final InventoryService inventoryService;    private final CouponService couponService;    private final OrderDomainService domainService;    private final EventPublisher publisher;    @Transactional    public OrderResult createOrder(OrderCmd cmd) {        inventoryService.preDeduct(cmd.getSkuId(), cmd.getQuantity());        CouponDiscount discount = couponService.calculate(cmd.getCouponId());        Order order = domainService.createOrder(cmd.getUserId(), cmd.getItems(), discount);        publisher.publish(new OrderCreatedEvent(order));        return OrderResult.success(order);    }}

每个类只做一件事,清晰到新人一眼就懂。

- 03-

如何避免再次爆炸?

1 库存扣减方案

方案实现方式优缺点
悲观锁 (for update)行级锁安全,但高并发性能差
乐观锁 (CAS)version 字段控制高并发性能好,但要重试
Redis 扣减原子 Lua 脚本性能极高,但一致性要兜底

推荐方案:乐观锁 + 限流熔断 + MQ 补偿

2 异步事件削峰填谷

@Componentpublic class OrderCreatedHandler {    @EventListener    @Async("orderExecutor")    public void handle(OrderCreatedEvent event) {        emailService.sendConfirm(event.getOrder());        analyticsService.logOrder(event);    }}

线程池隔离 + 可降级处理,让非核心逻辑别拖垮主流程。

-****04-****总结场景决策树:图片

重构收益:

  • TPS 从 200 → 5000+
  • 可用性 99.99%
  • 新人一天就能看懂业务逻辑

**
**

避坑指南:

  • 不要把所有逻辑堆在 Service

  • 不要用异常当业务逻辑

  • 一定要用领域事件解耦

  • 一定要为关键流程加补偿机制

凌晨 3 点的报警,只有一次就够了。

写好 Service,不仅是代码优雅,更是 团队生死的分水岭

如果你还在写“屎山类”,赶紧转发,让你的团队少掉几次通宵急救!

**-****05-**粉丝福利

我这里创建一个程序员成长&副业交流群, 


 和一群志同道合的小伙伴,一起聚焦自身发展, 

可以聊:


技术成长与职业规划,分享路线图、面试经验和效率工具, 




探讨多种副业变现路径,从写作课程到私活接单, 




主题活动、打卡挑战和项目组队,让志同道合的伙伴互帮互助、共同进步。 




如果你对这个特别的群,感兴趣的, 
可以加一下, 微信通过后会拉你入群, 
 但是任何人在群里打任何广告,都会被我T掉。