前言

作为工作多年的老司机,我主导过3次微服务重构,见过太多团队掉进微服务陷阱:拆分时春风得意,运维时步履维艰

某电商平台从单体拆分为120个微服务后,故障率飙升300%,排障时间从10分钟恶化到3小时。

这篇文章跟大家一起聊聊微服务中的10个最常见的问题,希望对你会有所帮助。

1.错误的拆分问题

典型场景:按代码包名拆分服务

图片

 

后果

  • • 订单查询需调用4个服务

  • • 接口延迟从50ms→350ms

  • • 链路追踪日志爆炸式增长

正确方案:基于业务能力拆分

图片

 

拆分原则

  1. 1. 单一职责(一个服务解决一类问题)

  2. 2. 团队自治(2 Pizza Team可独立交付)

  3. 3. 数据自治(服务独占数据库)

2.分布式事务问题

错误示范:跨服务数据库操作

@Transactional // 本地事务失效!  
public void createOrder(OrderDTO dto) {  
    // 1.订单服务写库  
    orderService.save(dto);  
    
    // 2.调用库存服务  
    stockFeignClient.deduct(dto.getSkuId());  
}  

后果:订单创建成功但库存未扣减 → 超卖事故

解决方案:Saga模式 + 可靠事件

图片

 

代码实现

@SagaStart  
public void createOrder(OrderDTO dto) {  
    Saga.with("freezeStock", () -> stockClient.freeze(dto))  
        .with("saveOrder", () -> orderService.save(dto))  
        .compensate("saveOrder", () -> orderService.delete(dto.getId()))  
        .compensate("freezeStock", () -> stockClient.unfreeze(dto))  
        .execute();  
}  

3.连环雪崩问题

场景复现:服务A → 服务B → 服务C,C超时导致全链路崩溃

图片

 

防御方案:熔断+降级+超时

@FeignClient(name = "stock-service",  
  configuration = FeignConfig.class,  
  fallback = StockFallback.class) // 降级类  
publicinterfaceStockClient {  
    @GetMapping("/deduct")
    @TimeLimiter(fallbackMethod = "defaultResult")// 超时控制  
    CompletableFuture<Boolean> deduct(@RequestParam String skuId);  
}  

// 熔断配置  
circuitBreaker:  
  failureRateThreshold: 50
  waitDurationInOpenState: 10s  
  slidingWindowSize: 20  

4.配置管理混乱问题

反模式:配置文件散落各服务

├── user-service  
│   ├── application-dev.yml  
│   ├── application-prod.yml  
├── order-service  
│   ├── application-dev.yml  
│   └── application-prod.yml  

后果

  • • 修改日志级别需重新部署10个服务

  • • 生产环境误用dev配置

正确方案:统一配置中心

图片

 

关键配置

spring:  
cloud:
    nacos:
      config:
        server-addr:192.168.1.10:8848
        file-extension:yaml
        shared-configs:
          -data-id:common.yaml# 公共配置   

5.日志追踪碎片化问题

问题现象

[user-service] 用户查询成功 userId=100  
[order-service] 订单创建失败 userId=100  
[payment-service] 支付超时 userId=100 

痛苦:跨3个日志系统拼凑调用链

解决方案:Sleuth+Zipkin全链路追踪

图片

 

日志格式

2023-08-20 14:30 [user-service,7a3b,9f2c] INFO 用户查询  
2023-08-20 14:30 [order-service,7a3b,d8e1] ERROR 订单创建失败  

其中:

  • • 7a3b:全局Trace ID

  • • 9f2c/d8e1:各服务ID

6.数据库拆分问题

错误操作:服务共用数据库

图片

 

后果

  • • 订单表锁阻塞用户注册

  • • 无法独立扩缩容

正确设计:数据库垂直拆分

图片

 

分库分表策略

// 用户ID取模分片  
public String determineDatabase(Long userId) {  
    int dbIndex = userId % 4;  
    return "user_db_" + dbIndex;  
}  

7.接口兼容性问题

血案:订单服务升级v2接口,未通知支付服务

图片

 

解决方案:三版本策略

/v1/createOrder (旧版)  
/v2/createOrder (新版)  
/v3/createOrder (预发布) 

Spring Cloud灰度发布

spring:  
cloud:
    gateway:
      routes:
        -id:order_v2
          uri:lb://order-service
          predicates:
            -Header=version,v2
          filters:
            -StripPrefix=1  

8.持续集成问题

典型问题:120个服务独立构建 → 流水线拥堵

图片

 

优化方案

  1. 1. 分层构建

图片

 

  1. 1. 并行构建

// Jenkinsfile并行配置  
stage('Parallel Build') {  
  parallel {  
      stage('Service A') { steps { sh './build-serviceA.sh' } }  
      stage('Service B') { steps { sh './build-serviceB.sh' } }  
  }  
}  

9.监控缺失问题

惨痛教训

  • • 磁盘写满8小时无人察觉

  • • 数据库连接池耗尽导致全站崩溃

监控体系黄金四件套

图片

 

关键告警规则

rules:  
-alert:HighErrorRate
    expr:sum(rate(http_server_requests_errors_total[5m]))>0.5
    for:2m
-alert:DBConnectionExhausted
    expr:db_connections_active>db_connections_max*0.9
    for:1m  

10.团队协作问题

现实困境

团队

技术栈

部署方式

用户组

Java+MySQL

K8s

订单组

Go+Postgres

VM

支付组

Node+Mongo

Serverless

解决方案

10.1统一技术公约
  1. 1. RESTful接口规范

  2. 2. 错误码全局定义

  3. 3. 日志格式标准

  4. 4. 健康检查端点/actuator/health

10.2基础设施共享

图片

 

总结

由此可见,微服务如果用不好问题还是挺多的,需要有丰富的实战经验,才能把微服务项目真正的做好。

微服务的三层防御体系

图片

 

微服务的十条军规

  1. 1. 服务粒度按业务能力而非代码量

  2. 2. 跨服务事务用最终一致性替代强一致

  3. 3. 必须配置熔断超时阈值

  4. 4. 配置中心统一管理所有环境参数

  5. 5. 全链路追踪ID穿透所有服务

  6. 6. 每个服务独占数据库

  7. 7. 接口版本兼容至少2个迭代

  8. 8. 建立分层构建流水线

  9. 9. 核心指标监控覆盖率100%

  10. 10. 制定跨团队技术公约

微服务的本质不是技术升级,而是组织关系的重构。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐