微服务架构不是银弹,但它确实是解决大型项目复杂性的最有效手段之一。本文将带你从实践角度出发,使用 Spring Boot 3 和 Spring Cloud 2023+ 版本,完成一个微服务项目的拆分与治理。
微服务拆分的核心原则
DDD 限界上下文是微服务拆分的最佳指导:每个微服务对应一个限界上下文,有自己的领域模型。拆分的黄金法则是"高内聚、低耦合"——如果一个功能的修改总是同时改两个服务,说明它们不应该被拆分。避免微服务"死亡三角":拆分过细(300+ 个微服务但每个只有几百行代码)、拆分过粗(一个"核心服务"包含了 80% 的业务逻辑)、错误拆分(按技术层拆分:Controller 服务、Service 服务、DAO 服务)。
Spring Cloud 微服务组件全景
[网关层] Spring Cloud Gateway(路由、限流、鉴权)
[注册中心] Nacos / Consul(服务发现与配置管理)
[配置中心] Nacos Config(动态配置刷新)
[熔断降级] Resilience4j / Sentinel(断路器、限流)
[负载均衡] Spring Cloud LoadBalancer
[远程调用] OpenFeign(声明式 HTTP 客户端)
[链路追踪] Micrometer Tracing + Zipkin
[消息驱动] Spring Cloud Stream + RocketMQ/Kafka服务注册与发现:Nacos 集成
// bootstrap.yml
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: prod
group: ORDER_GROUP
config:
server-addr: localhost:8848
file-extension: yaml
shared-configs:
- data-id: common.yaml
group: DEFAULT_GROUP
refresh: trueOpenFeign 声明式远程调用
// 服务消费方 - 声明式接口
@FeignClient(name = "user-service", path = "/api/users",
fallbackFactory = UserClientFallbackFactory.class)
public interface UserClient {
@GetMapping("/{id}")
Result<User> getUser(@PathVariable("id") Long id);
}
// 使用:像调用本地方法一样调用远程服务
@RestController
public class OrderController {
@Autowired
private UserClient userClient;
@GetMapping("/api/orders/{id}")
public Result<OrderDetail> getOrder(@PathVariable Long id) {
Order order = orderService.getById(id);
Result<User> user = userClient.getUser(order.getUserId());
return Result.success(new OrderDetail(order, user.getData()));
}
}Gateway 网关:统一入口与过滤
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- AuthFilterSentinel 熔断降级
@SentinelResource(value = "getUser", blockHandler = "getUserBlockHandler")
public User getUser(Long id) {
return userMapper.selectById(id);
}
public User getUserBlockHandler(Long id, BlockException e) {
return new User(id, "降级默认用户"); // 降级兜底
}分布式事务:Seata 集成
@GlobalTransactional
public void createOrder(OrderDTO dto) {
orderService.create(dto); // 本地事务
inventoryClient.deduct(dto.getItems()); // Feign 远程调用扣减库存
accountClient.charge(dto.getUserId(), dto.getAmount()); // 远程扣款
}
// Seata 通过 TC + TM + RM 实现 AT 模式下的自动补偿总结
微服务架构的核心挑战不在技术,而在组织——分布式事务的最终一致性、服务间的数据一致性、跨服务的调试和追踪,这些问题的解决方案都在 "治理" 而不是 "代码" 层面。一个好的微服务架构应该是渐进式拆分的:先把单体写好,在业务增长需要的时候再逐步拆出服务。
评论 (0)