前言
作为工作多年的老司机,我主导过 3 次微服务重构,见过太多团队掉进微服务陷阱:拆分时春风得意,运维时步履维艰。
某电商平台从单体拆分为 120 个微服务后,故障率飙升 300%,排障时间从 10 分钟恶化到 3 小时。
这篇文章跟大家一起聊聊微服务中的 10 个最常见的问题,希望对你会有所帮助。
1.错误的拆分问题
典型场景:按代码包名拆分服务
后果:
订单查询需调用 4 个服务
接口延迟从 50ms→350ms
链路追踪日志爆炸式增长
正确方案:基于业务能力拆分
拆分原则:
单一职责(一个服务解决一类问题)
团队自治(2 Pizza Team 可独立交付)
数据自治(服务独占数据库)
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) // 降级类
public interface StockClient {
@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、分层构建:
2、并行构建:
// 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.团队协作问题
现实困境:
10.1 统一技术公约
RESTful 接口规范
错误码全局定义
日志格式标准
健康检查端点/actuator/health
10.2 基础设施共享
总结
由此可见,微服务如果用不好问题还是挺多的,需要有丰富的实战经验,才能把微服务项目真正的做好。
微服务的三层防御体系:
微服务的十条军规:
服务粒度按业务能力而非代码量
跨服务事务用最终一致性替代强一致
必须配置熔断超时阈值
配置中心统一管理所有环境参数
全链路追踪 ID 穿透所有服务
每个服务独占数据库
接口版本兼容至少 2 个迭代
建立分层构建流水线
核心指标监控覆盖率 100%
制定跨团队技术公约
微服务的本质不是技术升级,而是组织关系的重构。
文章转载自:苏三说技术
原文链接:https://www.cnblogs.com/12lisu/p/18997181
体验地址:http://www.jnpfsoft.com/?from=001YH
评论