Spring Boot微服务架构在高并发场景下面临分布式事务一致性、服务间通信可靠性和资源隔离等核心挑战。本文从Seata分布式事务方案、消息中间件最终一致性到服务治理策略,提供可落地的架构设计方案。
微服务拆分原则与领域驱动设计
微服务架构的第一步是服务拆分。采用领域驱动设计(DDD)的限界上下文方法,按业务能力划分服务边界。以电商系统为例,拆分为订单、库存、支付、用户、营销五个核心服务。每个服务拥有独立的数据库和部署单元,通过API Gateway统一入口。
// Spring Boot微服务基础架构
// API Gateway (Spring Cloud Gateway)
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
// gateway-service.yml
spring:
cloud:
gateway:
routes:
- id: order-service
uri: lb://order-service
predicates:
- Path=/api/orders/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
- id: inventory-service
uri: lb://inventory-service
predicates:
- Path=/api/inventory/**
- id: payment-service
uri: lb://payment-service
predicates:
- Path=/api/payments/**
- Method=GET,POST
限流配置中,replenishRate=100表示每秒允许100个请求,burstCapacity=200允许短时突发200个请求。超出限制返回429状态码,客户端实现指数退避重试。
Seata分布式事务:AT模式配置与实战
跨服务的数据一致性是微服务架构的核心难题。Seata的AT(Automatic Transaction)模式通过SQL解析和undo_log自动回滚,对业务代码侵入最小。配置流程如下:
// pom.xml
com.alibaba.cloud
spring-cloud-starter-alibaba-seata
2023.0.1.0
// application.yml
seata:
enabled: true
application-id: order-service
tx-service-group: default_tx_group
service:
vgroup-mapping:
default_tx_group: default
grouplist:
default: 127.0.0.1:8091
registry:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: seata
config:
type: nacos
nacos:
server-addr: 127.0.0.1:8848
namespace: seata
业务代码中,通过@GlobalTransactional注解开启全局事务。以订单创建流程为例,涉及订单服务创建订单、库存服务扣减库存、支付服务预扣款三个操作:
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private InventoryFeignClient inventoryClient;
@Autowired
private PaymentFeignClient paymentClient;
@GlobalTransactional(name = "create-order", rollbackFor = Exception.class)
public OrderDTO createOrder(OrderRequest request) {
// 1. 创建订单(本地事务)
Order order = new Order();
order.setUserId(request.getUserId());
order.setProductId(request.getProductId());
order.setQuantity(request.getQuantity());
order.setAmount(request.getAmount());
order.setStatus(OrderStatus.CREATED);
orderMapper.insert(order);
// 2. 扣减库存(远程调用)
Result inventoryResult = inventoryClient.deduct(
request.getProductId(), request.getQuantity()
);
if (!inventoryResult.isSuccess()) {
throw new BusinessException("库存扣减失败: " + inventoryResult.getMessage());
}
// 3. 预扣款(远程调用)
Result paymentResult = paymentClient.preDeduct(
request.getUserId(), request.getAmount(), order.getId()
);
if (!paymentResult.isSuccess()) {
throw new BusinessException("预扣款失败: " + paymentResult.getMessage());
}
return OrderDTO.fromEntity(order);
}
}
Seata AT模式在执行本地SQL前自动生成undo_log,全局事务回滚时根据undo_log逆向补偿。rollbackFor = Exception.class确保所有异常都触发回滚。需注意Seata AT模式不支持嵌套子查询和多表关联UPDATE的SQL,复杂场景需改用TCC模式。
消息中间件:RocketMQ最终一致性方案
对于实时性要求不高的场景,基于RocketMQ的事务消息实现最终一致性更高效。事务消息确保本地事务执行和消息发送的原子性:
@Service
public class OrderTransactionalProducer {
@Autowired
private TransactionMQProducer producer;
public void sendOrderMessage(OrderDTO order) throws MQClientException {
Message msg = new Message(
"ORDER_TOPIC",
"CREATE",
order.getId().toString(),
JSON.toJSONBytes(order)
);
producer.sendMessageInTransaction(msg, order.getId());
}
}
// 事务监听器
@Component
public class OrderTransactionListener implements TransactionListener {
@Autowired
private OrderMapper orderMapper;
@Override
public LocalTransactionState executeLocalTransaction(Message msg, Object arg) {
Long orderId = (Long) arg;
try {
// 执行本地事务
orderMapper.updateStatus(orderId, OrderStatus.CONFIRMED);
return LocalTransactionState.COMMIT_MESSAGE;
} catch (Exception e) {
log.error("本地事务执行失败", e);
return LocalTransactionState.ROLLBACK_MESSAGE;
}
}
@Override
public LocalTransactionState checkLocalTransaction(MessageExt msg) {
// 事务回查:检查本地事务状态
Long orderId = Long.parseLong(msg.getKeys());
Order order = orderMapper.selectById(orderId);
if (order == null) {
return LocalTransactionState.UNKNOW;
}
return order.getStatus() == OrderStatus.CONFIRMED
? LocalTransactionState.COMMIT_MESSAGE
: LocalTransactionState.ROLLBACK_MESSAGE;
}
}
RocketMQ事务消息的回查机制保证消息最终一致性。生产者执行本地事务后崩溃,Broker会定期回调checkLocalTransaction方法确认事务状态。消息消费端需实现幂等性处理,避免重复消费导致数据异常。
高并发设计:线程池与限流降级
高并发场景下,线程池配置和限流降级是保护系统的关键手段。Spring Boot中通过ThreadPoolTaskExecutor管理异步任务:
@Configuration
public class ThreadPoolConfig {
@Bean("orderExecutor")
public ThreadPoolTaskExecutor orderExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(20);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(500);
executor.setKeepAliveSeconds(60);
executor.setThreadNamePrefix("order-async-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.setWaitForTasksToCompleteOnShutdown(true);
executor.setAwaitTerminationSeconds(30);
executor.initialize();
return executor;
}
}
// Sentinel限流配置
@SentinelResource(
value = "createOrder",
blockHandler = "createOrderBlockHandler",
fallback = "createOrderFallback"
)
public OrderDTO createOrder(OrderRequest request) {
// 业务逻辑
}
public OrderDTO createOrderBlockHandler(OrderRequest req, BlockException ex) {
log.warn("订单创建被限流: userId={}", req.getUserId());
throw new ServiceException("系统繁忙,请稍后重试");
}
public OrderDTO createOrderFallback(OrderRequest req, Throwable e) {
log.error("订单创建降级: userId={}", req.getUserId(), e);
throw new ServiceException("服务暂时不可用");
}
线程池CallerRunsPolicy拒绝策略让提交线程自己执行任务,形成天然背压,防止队列积压导致OOM。Sentinel的blockHandler处理限流/熔断场景,fallback处理业务异常降级。两者配合实现多层次的系统保护。
API接口规范方面,统一返回Result包装类,包含code、message、data、traceId四个字段。traceId贯穿整个调用链路,通过MDC(Mapped Diagnostic Context)在日志中自动输出,配合SkyWalking或Zipkin实现全链路追踪。业务中台建设中,服务治理还需考虑配置中心动态推送、灰度发布和服务版本兼容性管理。
原创文章,作者:小编,如若转载,请注明出处:https://www.yunthe.com/springboot-wei-fu-wu-shi-zhan-gao-bing-fa-chang-jing-xia/