🛒 电商系统分布式架构实战:从单体到微服务的演进之路
文章目录
- [🛒 电商系统分布式架构实战:从单体到微服务的演进之路](#🛒 电商系统分布式架构实战:从单体到微服务的演进之路)
- [🌪️ 一、电商系统的分布式挑战](#🌪️ 一、电商系统的分布式挑战)
-
- [🔥 电商业务复杂度分析](#🔥 电商业务复杂度分析)
- [💡 分布式架构演进路径](#💡 分布式架构演进路径)
- [🏗️ 二、核心模块架构设计](#🏗️ 二、核心模块架构设计)
-
- [🌐 微服务拆分策略](#🌐 微服务拆分策略)
- [📋 服务依赖关系定义](#📋 服务依赖关系定义)
- [🔧 服务配置管理](#🔧 服务配置管理)
- [🛒 三、购物车与订单一致性保障](#🛒 三、购物车与订单一致性保障)
-
- [🎯 购物车架构设计](#🎯 购物车架构设计)
- [⚡ 订单创建幂等性保障](#⚡ 订单创建幂等性保障)
- [🔄 分布式事务解决方案](#🔄 分布式事务解决方案)
- [📦 四、库存扣减的分布式锁实战](#📦 四、库存扣减的分布式锁实战)
-
- [🔒 库存扣减的并发挑战](#🔒 库存扣减的并发挑战)
- [🛡️ Redis 分布式锁实现](#🛡️ Redis 分布式锁实现)
- [📊 库存预扣减方案](#📊 库存预扣减方案)
- [⚡ 五、秒杀高并发架构实践](#⚡ 五、秒杀高并发架构实践)
-
- [🚀 秒杀系统架构设计](#🚀 秒杀系统架构设计)
- [🛡️ 多层次防护策略](#🛡️ 多层次防护策略)
- [🔄 异步化与队列缓冲](#🔄 异步化与队列缓冲)
- [💾 数据库优化策略](#💾 数据库优化策略)
- [🎯 六、技术选型与架构总结](#🎯 六、技术选型与架构总结)
-
- [📊 技术栈全景图](#📊 技术栈全景图)
- [🏗️ 系统架构总览](#🏗️ 系统架构总览)
- [📈 性能指标与SLA](#📈 性能指标与SLA)
- [🔧 部署架构方案](#🔧 部署架构方案)
🌪️ 一、电商系统的分布式挑战
🔥 电商业务复杂度分析
典型电商业务流程图:
用户浏览 加入购物车 下单结算 库存校验 支付处理 订单完成 物流发货
电商系统核心痛点:
业务场景 | 技术挑战 | 影响范围 | 解决方案 | 推荐技术实现 |
---|---|---|---|---|
🕒 秒杀活动 | 高并发下库存竞争、超卖、缓存穿透 | 整个系统雪崩、服务不可用 | 分层限流(网关 + 业务层)、库存预热、异步削峰 | Redis 预减库存 + MQ 异步下单 + 限流组件(Guava / Sentinel) |
📦 订单创建 | 数据一致性、重复下单、超卖风险 | 库存错乱、资金损失 | 分布式事务(TCC/Saga)、幂等约束(Token 或唯一索引) | Seata + Token 防重机制 + 数据库唯一索引 |
💰 支付回调 | 第三方重复通知、网络抖动、状态不同步 | 订单状态错误、资金对账异常 | 幂等处理、状态机校验、异步补偿机制 | 幂等表 + 乐观锁 + 异步任务补偿(MQ/定时任务) |
📊 库存管理 | 并发扣减、锁竞争、实时同步 | 库存超卖或锁等待 | 分布式锁、串行化操作、延迟同步 | Redis 分布式锁(Redisson)+ 队列异步化 + 定时校准 |
🚀 营销活动 | 动态规则、高并发写操作 | 系统抖动、规则错乱 | 规则缓存化、读写隔离、灰度验证 | 本地缓存 + 配置中心(Apollo/Nacos)+ 双写一致性机制 |
💡 分布式架构演进路径
从单体到微服务的演进:
java
// 单体架构示例 - 所有功能耦合在一起
@Service
public class MonolithicEcommerceService {
public OrderResult processOrder(OrderRequest request) {
// 1. 用户验证
User user = userService.validate(request.getUserId());
// 2. 库存检查
for (OrderItem item : request.getItems()) {
Inventory inventory = inventoryService.checkStock(item);
if (inventory.getStock() < item.getQuantity()) {
throw new InsufficientStockException();
}
}
// 3. 创建订单
Order order = orderService.createOrder(request);
// 4. 扣减库存
inventoryService.deductStock(request.getItems());
// 5. 支付处理
PaymentResult payment = paymentService.process(order);
// 问题:所有操作在同一个事务中,性能瓶颈明显
return OrderResult.success(order, payment);
}
}
🏗️ 二、核心模块架构设计
🌐 微服务拆分策略
电商系统微服务架构:
API Gateway 用户服务 商品服务 购物车服务 订单服务 库存服务 支付服务 物流服务 MySQL集群 ES搜索集群 Redis集群 订单数据库 库存数据库
📋 服务依赖关系定义
Maven 多模块结构:
xml
<!-- 父POM -->
<project>
<modules>
<module>ecommerce-api</module>
<module>ecommerce-common</module>
<module>user-service</module>
<module>product-service</module>
<module>cart-service</module>
<module>order-service</module>
<module>inventory-service</module>
<module>payment-service</module>
</modules>
</project>
<!-- 订单服务依赖 -->
<dependencies>
<dependency>
<groupId>com.ecommerce</groupId>
<artifactId>ecommerce-common</artifactId>
<version>1.0.0</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
</dependencies>
🔧 服务配置管理
Nacos 配置中心配置:
yaml
# application.yml - 公共配置
spring:
application:
name: order-service
cloud:
nacos:
discovery:
server-addr: 192.168.1.100:8848
config:
server-addr: 192.168.1.100:8848
file-extension: yaml
shared-configs:
- data-id: common-config.yaml
refresh: true
- data-id: datasource-config.yaml
refresh: true
# bootstrap.yml - 环境特定配置
spring:
profiles:
active: dev
cloud:
nacos:
config:
namespace: dev
group: DEFAULT_GROUP
🛒 三、购物车与订单一致性保障
🎯 购物车架构设计
Redis 购物车数据结构:
java
@Service
public class CartService {
private final RedisTemplate<String, Object> redisTemplate;
private static final String CART_KEY_PREFIX = "cart:user:";
/**
* 添加商品到购物车
*/
public void addItem(Long userId, CartItem item) {
String key = CART_KEY_PREFIX + userId;
// 使用Hash存储购物车项
redisTemplate.opsForHash().put(key,
item.getSkuId().toString(),
serializeItem(item));
// 设置过期时间(30天)
redisTemplate.expire(key, Duration.ofDays(30));
}
/**
* 获取购物车详情
*/
public Cart getCart(Long userId) {
String key = CART_KEY_PREFIX + userId;
Map<Object, Object> items = redisTemplate.opsForHash().entries(key);
Cart cart = new Cart();
cart.setUserId(userId);
cart.setItems(deserializeItems(items));
cart.setTotalAmount(calculateTotal(items));
return cart;
}
/**
* 清空购物车(下单后)
*/
public void clearCart(Long userId) {
String key = CART_KEY_PREFIX + userId;
redisTemplate.delete(key);
}
}
// 购物车项数据结构
@Data
public class CartItem {
private Long skuId;
private String skuName;
private BigDecimal price;
private Integer quantity;
private String image;
private List<CartItemAttribute> attributes;
}
⚡ 订单创建幂等性保障
分布式订单号生成:
java
@Service
public class OrderIdGenerator {
/**
* 雪花算法生成订单ID
* 格式:时间戳(41bit) + 机器ID(10bit) + 序列号(12bit)
*/
public String generateOrderId() {
long timestamp = System.currentTimeMillis();
long machineId = getMachineId(); // 机器标识
long sequence = getSequence(); // 序列号
long orderId = ((timestamp - 1609459200000L) << 22) | (machineId << 12) | sequence;
return String.valueOf(orderId);
}
/**
* 基于数据库的唯一订单号保障
*/
@Transactional
public Order createOrderWithIdempotency(OrderRequest request, String idempotentKey) {
// 检查幂等键是否已使用
if (orderRepository.existsByIdempotentKey(idempotentKey)) {
return orderRepository.findByidempotentKey(idempotentKey);
}
try {
Order order = new Order();
order.setOrderNo(generateOrderId());
order.setIdempotentKey(idempotentKey);
// 设置其他订单属性...
return orderRepository.save(order);
} catch (DataIntegrityViolationException e) {
// 并发情况下捕获唯一约束异常
return orderRepository.findByidempotentKey(idempotentKey);
}
}
}
🔄 分布式事务解决方案
Seata AT 模式订单创建:
java
@Service
public class OrderCreationService {
@GlobalTransactional(name = "create-order-tx", timeoutMills = 300000)
public OrderResult createOrder(OrderRequest request) {
// 1. 创建订单(主事务)
Order order = orderService.createOrder(request);
// 2. 扣减库存(分支事务)
inventoryService.deductStock(order.getItems());
// 3. 清空购物车(分支事务)
cartService.clearCart(order.getUserId());
// 4. 记录订单日志(分支事务)
orderLogService.recordCreation(order);
return OrderResult.success(order);
}
}
// 库存服务 - 分支事务
@Service
public class InventoryService {
@Transactional(rollbackFor = Exception.class)
public void deductStock(List<OrderItem> items) {
for (OrderItem item : items) {
// 使用乐观锁防止超卖
int affectedRows = inventoryMapper.deductStock(
item.getSkuId(), item.getQuantity());
if (affectedRows == 0) {
throw new InsufficientStockException("库存不足: " + item.getSkuId());
}
}
}
}
// MyBatis 乐观锁实现
@Mapper
public interface InventoryMapper {
@Update("UPDATE inventory SET stock = stock - #{quantity}, " +
"version = version + 1 WHERE sku_id = #{skuId} " +
"AND stock >= #{quantity} AND version = #{version}")
int deductStockWithVersion(@Param("skuId") Long skuId,
@Param("quantity") Integer quantity,
@Param("version") Long version);
}
📦 四、库存扣减的分布式锁实战
🔒 库存扣减的并发挑战
超卖问题示意图:
用户A 用户B 库存服务 数据库 请求扣减库存(数量:1) 请求扣减库存(数量:1) 查询库存(当前:1) 查询库存(当前:1) 返回库存:1 返回库存:1 扣减库存(1-1=0) 扣减库存(1-1=0) 超卖发生!库存变为-1 用户A 用户B 库存服务 数据库
🛡️ Redis 分布式锁实现
可重入分布式锁设计:
java
@Component
public class RedisDistributedLock {
private final RedisTemplate<String, String> redisTemplate;
private static final String LOCK_PREFIX = "lock:inventory:";
private static final long DEFAULT_EXPIRE_TIME = 30000; // 30秒
/**
* 尝试获取分布式锁
*/
public boolean tryLock(String lockKey, String requestId, long expireTime) {
String key = LOCK_PREFIX + lockKey;
return Boolean.TRUE.equals(redisTemplate.execute(
(RedisCallback<Boolean>) connection -> {
// SET key value NX PX timeout
byte[] keyBytes = key.getBytes();
byte[] valueBytes = requestId.getBytes();
byte[] pxBytes = String.valueOf(expireTime).getBytes();
return connection.execute("SET", keyBytes, valueBytes,
"NX".getBytes(), "PX".getBytes(), pxBytes) != null;
}
));
}
/**
* 释放分布式锁
*/
public boolean releaseLock(String lockKey, String requestId) {
String key = LOCK_PREFIX + lockKey;
String script =
"if redis.call('get', KEYS[1]) == ARGV[1] then " +
"return redis.call('del', KEYS[1]) else return 0 end";
Long result = redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Collections.singletonList(key), requestId);
return result != null && result == 1;
}
/**
* 库存扣减的锁应用
*/
public boolean deductStockWithLock(Long skuId, Integer quantity) {
String lockKey = "sku:" + skuId;
String requestId = UUID.randomUUID().toString();
try {
// 尝试获取锁,最多等待3秒
long waitTime = 3000;
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < waitTime) {
if (tryLock(lockKey, requestId, DEFAULT_EXPIRE_TIME)) {
// 获取锁成功,执行库存扣减
return doDeductStock(skuId, quantity);
}
Thread.sleep(100); // 短暂休眠后重试
}
return false; // 获取锁超时
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
} finally {
releaseLock(lockKey, requestId);
}
}
private boolean doDeductStock(Long skuId, Integer quantity) {
// 实际的库存扣减逻辑
Inventory inventory = inventoryMapper.selectBySkuId(skuId);
if (inventory.getAvailableStock() >= quantity) {
inventoryMapper.updateStock(skuId, inventory.getAvailableStock() - quantity);
return true;
}
return false;
}
}
📊 库存预扣减方案
Redis 库存预扣减设计:
java
@Service
public class InventoryPreDeductionService {
private final RedisTemplate<String, String> redisTemplate;
/**
* 库存预热到Redis
*/
public void warmUpInventory(Long skuId, Integer stock) {
String key = "inventory:sku:" + skuId;
redisTemplate.opsForValue().set(key, stock.toString());
}
/**
* Redis预扣减库存
*/
public boolean preDeductStock(Long skuId, Integer quantity) {
String key = "inventory:sku:" + skuId;
// Lua脚本保证原子性
String script =
"local current = tonumber(redis.call('get', KEYS[1]) or 0) " +
"if current >= tonumber(ARGV[1]) then " +
"redis.call('set', KEYS[1], current - ARGV[1]) " +
"return 1 else return 0 end";
Long result = redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Collections.singletonList(key), quantity.toString());
return result != null && result == 1;
}
/**
* 同步Redis库存到数据库
*/
@Scheduled(fixedRate = 60000) // 每分钟同步一次
public void syncInventoryToDB() {
Set<String> keys = redisTemplate.keys("inventory:sku:*");
for (String key : keys) {
Long skuId = extractSkuIdFromKey(key);
String stockStr = redisTemplate.opsForValue().get(key);
if (stockStr != null) {
Integer stock = Integer.parseInt(stockStr);
inventoryMapper.updateStock(skuId, stock);
}
}
}
}
⚡ 五、秒杀高并发架构实践
🚀 秒杀系统架构设计
秒杀系统分层架构:
用户请求 负载均衡层 网关层 业务逻辑层 数据访问层 限流降级 风控校验 队列缓冲 数据库
🛡️ 多层次防护策略
网关层限流配置:
yaml
# Spring Cloud Gateway 限流配置
spring:
cloud:
gateway:
routes:
- id: seckill_route
uri: lb://seckill-service
predicates:
- Path=/api/seckill/**
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 1000 # 每秒令牌数
redis-rate-limiter.burstCapacity: 2000 # 突发容量
key-resolver: "#{@userKeyResolver}"
- name: CircuitBreaker
args:
name: seckillCircuitBreaker
fallbackUri: forward:/fallback/seckill
# 自定义Key解析器
@Component
public class UserKeyResolver implements KeyResolver {
@Override
public Mono<String> resolve(ServerWebExchange exchange) {
// 按用户ID限流
return Mono.just(exchange.getRequest()
.getQueryParams().getFirst("userId"));
}
}
业务层限流实现:
java
@Service
public class SeckillRateLimitService {
// Guava RateLimiter - 令牌桶算法
private final RateLimiter rateLimiter = RateLimiter.create(1000); // 1000 QPS
// Redis + Lua 分布式限流
public boolean acquireToken(String key, int maxCount, int duration) {
String luaScript =
"local current = redis.call('get', KEYS[1]) " +
"if current and tonumber(current) > tonumber(ARGV[1]) then " +
"return 0 end " +
"current = redis.call('incr', KEYS[1]) " +
"if tonumber(current) == 1 then " +
"redis.call('expire', KEYS[1], ARGV[2]) end " +
"return 1";
Long result = redisTemplate.execute(
new DefaultRedisScript<>(luaScript, Long.class),
Collections.singletonList("rate_limit:" + key),
String.valueOf(maxCount), String.valueOf(duration));
return result != null && result == 1;
}
}
🔄 异步化与队列缓冲
RabbitMQ 秒杀队列设计:
java
@Configuration
public class SeckillRabbitConfig {
// 秒杀订单队列
@Bean
public Queue seckillOrderQueue() {
return new Queue("seckill.order.queue", true, false, false);
}
// 死信队列处理失败订单
@Bean
public Queue seckillDlq() {
return QueueBuilder.durable("seckill.order.dlq")
.withArgument("x-dead-letter-exchange", "")
.withArgument("x-dead-letter-routing-key", "seckill.order.queue")
.build();
}
}
// 秒杀服务异步处理
@Service
public class SeckillAsyncService {
@Autowired
private RabbitTemplate rabbitTemplate;
/**
* 接收秒杀请求,进入队列
*/
public SeckillResponse submitSeckillRequest(SeckillRequest request) {
// 1. 初步校验(用户资格、活动状态)
if (!preValidate(request)) {
return SeckillResponse.failed("校验失败");
}
// 2. 生成唯一请求ID
String requestId = generateRequestId(request);
// 3. 写入Redis记录请求
redisTemplate.opsForValue().set(
"seckill:request:" + requestId,
"pending", Duration.ofMinutes(5));
// 4. 发送到消息队列
rabbitTemplate.convertAndSend(
"seckill.order.queue",
buildSeckillMessage(request, requestId));
return SeckillResponse.processing("请求已接收", requestId);
}
/**
* 消息消费者处理秒杀订单
*/
@RabbitListener(queues = "seckill.order.queue")
public void processSeckillOrder(SeckillMessage message) {
try {
// 1. 库存预扣减
if (!inventoryService.preDeductStock(
message.getSkuId(), message.getQuantity())) {
throw new InsufficientStockException("库存不足");
}
// 2. 创建订单
Order order = orderService.createSeckillOrder(message);
// 3. 更新请求状态
redisTemplate.opsForValue().set(
"seckill:request:" + message.getRequestId(),
"success", Duration.ofMinutes(5));
// 4. 发送成功通知
notificationService.sendSeckillSuccess(message.getUserId(), order);
} catch (Exception e) {
// 处理失败,进入死信队列
log.error("秒杀订单处理失败: {}", message.getRequestId(), e);
redisTemplate.opsForValue().set(
"seckill:request:" + message.getRequestId(),
"failed:" + e.getMessage(), Duration.ofMinutes(5));
throw new AmqpRejectAndDontRequeueException(e);
}
}
}
💾 数据库优化策略
分库分表设计:
sql
-- 订单表分表策略(按用户ID取模)
CREATE TABLE orders_0000 (
id BIGINT PRIMARY KEY,
order_no VARCHAR(32) NOT NULL,
user_id BIGINT NOT NULL,
-- 其他字段...
INDEX idx_user_id (user_id),
UNIQUE KEY uk_order_no (order_no)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-- 库存表优化
CREATE TABLE inventory (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
sku_id BIGINT NOT NULL,
available_stock INT NOT NULL DEFAULT 0,
locked_stock INT NOT NULL DEFAULT 0,
version BIGINT NOT NULL DEFAULT 0,
UNIQUE KEY uk_sku_id (sku_id),
INDEX idx_stock (available_stock)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
MyBatis 分表路由:
java
@Component
public class OrderTableRouter {
private static final int TABLE_COUNT = 16;
/**
* 根据用户ID计算表后缀
*/
public String getTableSuffix(Long userId) {
int suffix = (int) (userId % TABLE_COUNT);
return String.format("_%04d", suffix);
}
/**
* 动态表名拦截器
*/
@Intercepts({@Signature(type = StatementHandler.class,
method = "prepare", args = {Connection.class, Integer.class})})
public class TableNameInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler handler = (StatementHandler) invocation.getTarget();
MetaObject metaObject = SystemMetaObject.forObject(handler);
MappedStatement mappedStatement = (MappedStatement)
metaObject.getValue("delegate.mappedStatement");
// 替换SQL中的表名
String sql = (String) metaObject.getValue("delegate.boundSql.sql");
if (sql.contains("orders")) {
Long userId = extractUserIdFromSql(sql);
String newSql = sql.replace("orders",
"orders" + getTableSuffix(userId));
metaObject.setValue("delegate.boundSql.sql", newSql);
}
return invocation.proceed();
}
}
}
🎯 六、技术选型与架构总结
📊 技术栈全景图
电商系统技术选型矩阵:
技术领域 | 核心组件 | 备选方案 | 选型理由 | 架构定位 |
---|---|---|---|---|
微服务框架 | Spring Cloud Alibaba | Spring Cloud Netflix | 与阿里生态无缝衔接(Nacos、Sentinel、RocketMQ、Seata),版本维护积极 | 微服务治理核心框架 |
服务注册与发现 | Nacos | Consul、Eureka | 注册发现 + 配置中心一体化,高可用支持完善 | 服务发现与动态配置 |
配置中心 | Nacos Config | Apollo、Spring Cloud Config | 支持配置热刷新、命名空间隔离与灰度发布 | 配置集中化与动态管理 |
分布式事务 | Seata | RocketMQ 事务消息、TCC 手动实现 | 提供 AT/TCC/XA/SAGA 模式,简化事务编排 | 全局事务一致性保障 |
消息队列 | RabbitMQ | RocketMQ、Kafka | 支持确认机制、延迟队列、死信队列,适合交易类系统 | 异步削峰与事件驱动 |
缓存中间件 | Redis Cluster | Memcached | 提供丰富数据结构、分布式锁、持久化能力 | 高速缓存与热点数据防穿透 |
数据库 | MySQL 8.x | PostgreSQL、TiDB | 生态成熟、分库分表工具完善(ShardingSphere、MyCat) | 核心交易与订单存储 |
搜索引擎 | Elasticsearch | Solr | 提供全文检索、聚合分析、实时性强 | 搜索与推荐模块 |
链路追踪与监控 | Prometheus + Grafana | SkyWalking、Zipkin | 指标监控 + 可视化告警,易与K8s融合 | 服务可观测性体系 |
容器与调度 | Kubernetes + Docker | OpenShift、Mesos | 云原生主流方案,弹性伸缩与服务编排能力强 | 微服务容器化运行 |
CI/CD | Jenkins + ArgoCD | GitLab CI、Tekton | 支持流水线构建与声明式部署,自动化程度高 | 自动化交付与回滚保障 |
API 网关 | Spring Cloud Gateway | Kong、Nginx+Lua | 响应式架构、支持熔断/限流/鉴权 | 流量入口与安全防护 |
🏗️ 系统架构总览
电商平台整体架构图:
客户端 CDN 负载均衡SLB API网关 用户服务 商品服务 搜索服务 购物车服务 订单服务 库存服务 支付服务 物流服务 用户数据库 商品数据库 Elasticsearch Redis集群 订单数据库 库存数据库 消息队列 监控系统 Prometheus Grafana 告警中心
📈 性能指标与SLA
系统性能目标:
指标名称 | 目标值(SLO) | 监控方式(SLI来源) | 告警阈值 | 说明与优化方向 |
---|---|---|---|---|
订单创建响应时间 | P99 < 200ms | Prometheus + AOP Metrics埋点 | >500ms(连续3次) | 影响用户体验,应优化数据库索引与异步下单逻辑 |
库存查询响应时间 | P99 < 50ms | 应用日志 + Zipkin链路追踪 | >100ms(连续5次) | 接口为热点路径,建议启用Redis缓存与本地副本缓存 |
支付成功率 | >99.95% | 业务事件监控(订单状态变化) | <99.9% | 关键资金指标,启用幂等+重试+补偿机制 |
系统可用性 | 99.99% | 健康检查(K8s Liveness/Readiness) | <99.95% | 微服务需具备自愈与限流能力 |
并发处理能力 | ≥10,000 TPS | 压力测试(JMeter/Gatling) | 达峰值80%触发预警 | 关键活动前进行容量评估,支持自动弹性伸缩 |
消息积压量 | <1000条 | MQ指标监控(RabbitMQ Exporter) | >5000条 | 避免消费者异常或延迟导致数据堆积 |
数据库QPS | <80%容量上限 | 数据源监控(Druid、MySQL Exporter) | >90% | 超阈值自动扩容或读写分离 |
缓存命中率 | >95% | Redis Exporter | <90% | 命中率下降将导致数据库压力上升,应监控热点Key变化 |
接口错误率 | <0.1% | Prometheus + Spring Boot Actuator | >0.5% | 触发自动降级与熔断策略 |
🔧 部署架构方案
Kubernetes 部署配置:
yaml
# order-service-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: order-service
namespace: ecommerce
spec:
replicas: 3
selector:
matchLabels:
app: order-service
template:
metadata:
labels:
app: order-service
spec:
containers:
- name: order-service
image: registry.cn-hangzhou.aliyuncs.com/ecommerce/order-service:v1.2.0
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "kubernetes"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "500m"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 5
periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
name: order-service
namespace: ecommerce
spec:
selector:
app: order-service
ports:
- port: 80
targetPort: 8080
type: ClusterIP