当前位置: 首页 > news >正文

【基于 Spring Cloud Alibaba 的微服务电商项目】完整实现思路

文章目录

  • 基于Spring Cloud Alibaba的微服务电商项目全流程实战(高并发+高可用+一致性保障)
    • 一、需求分析
      • 1. 业务需求
      • 2. 技术需求
    • 二、数据库表设计(按服务拆分)
      • 1. 数据库拆分原则
      • 2. 核心表结构(MySQL)
        • (1)用户服务数据库(user_db)
        • (2)商品服务数据库(product_db)
        • (3)订单服务数据库(order_db)
        • (4)库存服务数据库(inventory_db)
        • (5)支付服务数据库(pay_db)
    • 三、技术栈选型(Spring Cloud Alibaba生态)
    • 四、微服务架构设计
      • 1. 架构分层(从上到下)
      • 2. 服务拆分原则
      • 3. 核心链路调用流程
    • 五、核心微服务开发实现
      • 1. 通用基础配置(所有服务依赖)
        • (1)pom.xml核心依赖(Spring Boot 2.7.x + Spring Cloud Alibaba 2021.0.4.0)
        • (2)bootstrap.yml(连接Nacos配置中心)
      • 2. 用户服务(user-service)
        • (1)核心功能:JWT鉴权
        • (2)登录接口
      • 3. 商品服务(product-service)
        • (1)核心功能:商品缓存(Cache Aside Pattern)
      • 4. 库存服务(inventory-service)
        • (1)核心功能:库存扣减(防超卖+分布式锁)
      • 5. 订单服务(order-service)
        • (1)核心功能:创建订单(整合Seata TCC分布式事务)
        • (2)订单超时取消(监听RocketMQ延迟队列)
      • 6. 支付服务(pay-service)
        • (1)核心功能:对接支付宝支付
    • 六、服务注册与配置中心(Nacos实战)
      • 1. Nacos部署(Docker方式)
      • 2. Nacos配置中心使用
        • (1)创建配置文件
        • (2)动态刷新配置
    • 七、网关层设计(Sentinel Gateway)
      • 1. 网关配置(application.yml)
      • 2. 统一鉴权过滤器
    • 八、分布式事务一致性保障(Seata实战)
      • 1. Seata部署(Docker)
      • 2. Seata配置(registry.conf)
      • 3. 微服务集成Seata(application.yml)
      • 4. 分布式事务模式选择
    • 九、缓存问题全解(Redis+一致性+防雪崩)
      • 1. 缓存三大问题解决方案
      • 2. 缓存一致性(Cache Aside Pattern)
    • 十、中间件选型与使用
      • 1. RocketMQ(消息队列)
        • (1)核心使用场景
        • (2)关键配置
      • 2. Redis(缓存+分布式锁)
        • (1)Redis集群部署(3主3从)
        • (2)Redisson分布式锁
      • 3. Sharding-JDBC(分库分表)
        • (1)订单表分库分表配置(application.yml)
    • 十一、核心业务实现
      • 1. 订单超时自动取消(两种方案对比)
      • 2. 库存防超卖(三重保障)
    • 十二、特殊场景优化(秒杀/高并发)
      • 1. 秒杀场景优化方案
        • (1)架构层面
        • (2)代码层面
      • 2. 接口幂等性(防重复提交)
    • 十三、环境配置与部署(Docker+K8s)
      • 1. Docker镜像构建(Dockerfile)
      • 2. K8s部署配置(order-service-deployment.yaml)
      • 3. 部署流程
    • 十四、监控与运维
      • 1. 全链路监控(Prometheus+Grafana)
        • (1)微服务集成Prometheus
        • (2)application.yml配置
        • (3)Grafana面板配置
      • 2. 日志收集(ELK)
      • 3. 告警机制
    • 总结

基于Spring Cloud Alibaba的微服务电商项目全流程实战(高并发+高可用+一致性保障)

若对您有帮助的话,请点赞收藏加关注哦,您的关注是我持续创作的动力!有问题请私信或联系邮箱:funian.gm@gmail.com

在这里插入图片描述

一、需求分析

1. 业务需求

核心模块核心功能
用户服务注册/登录(JWT鉴权)、用户信息管理、地址管理
商品服务商品CRUD、分类管理、商品上下架、库存关联
订单服务订单创建、订单状态流转、订单查询、超时取消
库存服务库存扣减、库存锁定、库存回滚、防超卖
支付服务对接支付宝/微信支付、支付回调、退款处理
秒杀服务秒杀商品发布、限流削峰、异步下单
网关服务路由转发、限流熔断、统一鉴权、日志收集

2. 技术需求

  • 高并发:支持秒杀场景10万QPS,普通下单1万QPS
  • 高可用:服务可用性99.99%,核心链路无单点故障
  • 一致性:分布式事务保证订单-库存-支付数据一致
  • 可扩展:支持水平扩容,应对流量峰值
  • 安全性:接口幂等性、防SQL注入、防缓存穿透/击穿/雪崩
  • 可监控:全链路监控、告警机制(响应时间>3s告警)

二、数据库表设计(按服务拆分)

1. 数据库拆分原则

  • 每个微服务独立数据库,避免跨库联查
  • 核心表设计冗余字段(如订单表存商品名称/价格,避免查商品库)
  • 分库分表:订单表、商品表按规则拆分(Sharding-JDBC)

2. 核心表结构(MySQL)

(1)用户服务数据库(user_db)
表名核心字段索引设计
userid(PK)、username、password(加密)、phone、statususername(唯一)、phone(唯一)
user_addressid(PK)、user_id(FK)、receiver、phone、addressuser_id(普通索引)
(2)商品服务数据库(product_db)
表名核心字段索引设计
productid(PK)、name、price、stock、status、category_idcategory_id(普通)、name(模糊索引)
product_categoryid(PK)、name、parent_id、levelparent_id(普通)
(3)订单服务数据库(order_db)
表名核心字段索引设计
order_mainid(PK)、order_sn(订单号)、user_id、total_amount、status、create_timeorder_sn(唯一)、user_id(普通)、create_time(普通)
order_itemid(PK)、order_id(FK)、product_id、product_name、price、quantityorder_id(普通)、product_id(普通)
message_queueid(PK)、order_id、message、status(0未发送1已发送)、create_timeorder_id(普通)、status(普通)
(4)库存服务数据库(inventory_db)
表名核心字段索引设计
inventoryid(PK)、product_id、stock、locked_stock(锁定库存)product_id(唯一)
inventory_logid(PK)、product_id、operate_type(1扣减2回滚)、quantity、order_idproduct_id(普通)、order_id(普通)
(5)支付服务数据库(pay_db)
表名核心字段索引设计
paymentid(PK)、order_sn、user_id、pay_amount、pay_type(1支付宝2微信)、statusorder_sn(唯一)、user_id(普通)
refundid(PK)、payment_id(FK)、refund_amount、status、refund_timepayment_id(普通)

三、技术栈选型(Spring Cloud Alibaba生态)

技术分层选型组件核心作用
微服务框架Spring Cloud Alibaba微服务生态核心(整合各类组件)
注册中心Nacos服务注册与发现(支持健康检查)
配置中心Nacos Config动态配置、环境隔离(dev/test/prod)
网关Sentinel Gateway路由转发、限流、熔断、鉴权
RPC通信Dubbo高性能RPC调用(替代OpenFeign,支持负载均衡)
熔断降级Sentinel服务熔断、降级、限流(支持注解式配置)
分布式事务Seata保证订单-库存-支付一致性(TCC/AT模式)
缓存Redis(集群)商品缓存、分布式锁、会话缓存
消息队列RocketMQ异步通信、延迟队列(订单超时)、削峰
数据库MySQL(主从复制)业务数据存储(主写从读)
分库分表Sharding-JDBC订单表/商品表水平拆分(应对大数据量)
分布式锁Redisson库存扣减防超卖、秒杀锁
鉴权JWT无状态登录鉴权(替代Session)
监控Prometheus+Grafana全链路指标监控(QPS/响应时间/错误率)
日志ELK(Elasticsearch+Logstash+Kibana)日志收集与分析
部署Docker+K8s容器化部署、自动扩缩容

四、微服务架构设计

1. 架构分层(从上到下)

客户端层(APP/小程序/PC)→ CDN(静态资源加速)→ 网关层(Sentinel Gateway)→ 微服务层 → 中间件层 → 基础设施层

2. 服务拆分原则

  • 单一职责:每个服务只负责一个核心领域(如订单服务只处理订单相关)
  • 高内聚低耦合:服务内部逻辑紧密,服务间通过接口通信
  • 数据自治:每个服务独立管理自己的数据库,不跨库操作
  • 可独立部署:服务之间无依赖,支持单独扩容/升级

3. 核心链路调用流程

下单流程:用户→网关→订单服务(创建订单)→ Dubbo调用库存服务(预扣库存)→ Dubbo调用支付服务(发起支付)→ 支付回调→订单服务(更新状态)→ 库存服务(确认扣减)

五、核心微服务开发实现

1. 通用基础配置(所有服务依赖)

(1)pom.xml核心依赖(Spring Boot 2.7.x + Spring Cloud Alibaba 2021.0.4.0)
<!-- Spring Cloud Alibaba 核心依赖 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-alibaba-dependencies</artifactId><version>2021.0.4.0</version><type>pom</type><scope>import</scope>
</dependency>
<!-- Nacos 注册中心 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- Nacos 配置中心 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- Dubbo RPC -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
<!-- Sentinel 熔断降级 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- Seata 分布式事务 -->
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>
(2)bootstrap.yml(连接Nacos配置中心)
spring:application:name: order-service # 服务名(对应Nacos配置)cloud:nacos:discovery:server-addr: 192.168.1.100:8848 # Nacos注册中心地址config:server-addr: 192.168.1.100:8848 # Nacos配置中心地址file-extension: yaml # 配置文件格式namespace: dev # 环境隔离(dev/test/prod)group: ORDER_GROUP # 配置分组(按服务分组)
dubbo:registry:address: nacos://192.168.1.100:8848 # Dubbo基于Nacos服务发现protocol:name: dubboport: -1 # 随机端口

2. 用户服务(user-service)

(1)核心功能:JWT鉴权
// JWT工具类
@Component
public class JwtUtil {@Value("${jwt.secret}")private String secret;@Value("${jwt.expire}")private long expire;// 生成Tokenpublic String generateToken(Long userId) {Date now = new Date();Date expireDate = new Date(now.getTime() + expire * 1000);return Jwts.builder().setSubject(userId.toString()).setIssuedAt(now).setExpiration(expireDate).signWith(SignatureAlgorithm.HS256, secret).compact();}// 验证Tokenpublic boolean validateToken(String token) {try {Jwts.parser().setSigningKey(secret).parseClaimsJws(token);return true;} catch (Exception e) {return false;}}// 从Token中获取用户IDpublic Long getUserIdFromToken(String token) {Claims claims = Jwts.parser().setSigningKey(secret).parseClaimsJws(token).getBody();return Long.parseLong(claims.getSubject());}
}
(2)登录接口
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate JwtUtil jwtUtil;@PostMapping("/login")public Result<String> login(@RequestBody LoginDTO loginDTO) {// 验证用户名密码(省略加密校验逻辑)User user = userService.getUserByUsername(loginDTO.getUsername());if (user == null || !user.getPassword().equals(loginDTO.getPassword())) {return Result.fail("用户名或密码错误");}// 生成JWT TokenString token = jwtUtil.generateToken(user.getId());return Result.success(token);}
}

3. 商品服务(product-service)

(1)核心功能:商品缓存(Cache Aside Pattern)
@Service
public class ProductServiceImpl implements ProductService {@Autowiredprivate ProductMapper productMapper;@Autowiredprivate StringRedisTemplate redisTemplate;private static final String CACHE_KEY_PRODUCT = "product:";// 查询商品详情(缓存优先)@Overridepublic Product getProductById(Long productId) {// 1. 查缓存String key = CACHE_KEY_PRODUCT + productId;String json = redisTemplate.opsForValue().get(key);if (StrUtil.isNotBlank(json)) {return JSONUtil.toBean(json, Product.class);}// 2. 缓存未命中,查数据库Product product = productMapper.selectById(productId);if (product != null) {// 3. 存入缓存(过期时间1小时,加随机值防雪崩)redisTemplate.opsForValue().set(key, JSONUtil.toJsonStr(product), 3600 + new Random().nextInt(600), TimeUnit.SECONDS);} else {// 4. 缓存空值(防穿透)redisTemplate.opsForValue().set(key, "", 60, TimeUnit.SECONDS);}return product;}// 更新商品(更新数据库+删除缓存)@Override@Transactionalpublic boolean updateProduct(Product product) {// 1. 更新数据库boolean success = productMapper.updateById(product) > 0;if (success) {// 2. 删除缓存(避免缓存脏数据)String key = CACHE_KEY_PRODUCT + product.getId();redisTemplate.delete(key);}return success;}
}

4. 库存服务(inventory-service)

(1)核心功能:库存扣减(防超卖+分布式锁)
@Service
public class InventoryServiceImpl implements InventoryService {@Autowiredprivate InventoryMapper inventoryMapper;@Autowiredprivate RedissonClient redissonClient;private static final String LOCK_KEY_INVENTORY = "lock:inventory:";// 预扣库存(TCC模式的Try方法)@Overridepublic boolean deductStock(Long productId, Integer quantity, String orderId) {// 1. 分布式锁(Redisson),防止并发超卖RLock lock = redissonClient.getLock(LOCK_KEY_INVENTORY + productId);lock.lock(30, TimeUnit.SECONDS); // 锁超时30秒try {// 2. 查库存(带行锁,避免幻读)Inventory inventory = inventoryMapper.selectByProductIdForUpdate(productId);if (inventory == null || inventory.getStock() < quantity) {return false; // 库存不足}// 3. 预扣库存(锁定库存增加,可用库存减少)inventory.setStock(inventory.getStock() - quantity);inventory.setLockedStock(inventory.getLockedStock() + quantity);// 4. 记录库存日志(用于回滚)InventoryLog log = new InventoryLog();log.setProductId(productId);log.setQuantity(quantity);log.setOrderId(orderId);log.setOperateType(1); // 1=扣减inventoryLogMapper.insert(log);return inventoryMapper.updateById(inventory) > 0;} finally {lock.unlock(); // 释放锁}}// 确认扣减(TCC模式的Confirm方法)@Overridepublic boolean confirmDeduct(Long productId, Integer quantity) {// 无需操作,TCC最终确认(实际可清理日志)return true;}// 回滚库存(TCC模式的Cancel方法)@Overridepublic boolean cancelDeduct(Long productId, Integer quantity, String orderId) {RLock lock = redissonClient.getLock(LOCK_KEY_INVENTORY + productId);lock.lock(30, TimeUnit.SECONDS);try {// 回滚库存:可用库存增加,锁定库存减少Inventory inventory = inventoryMapper.selectById(productId);inventory.setStock(inventory.getStock() + quantity);inventory.setLockedStock(inventory.getLockedStock() - quantity);// 记录回滚日志InventoryLog log = new InventoryLog();log.setProductId(productId);log.setQuantity(quantity);log.setOrderId(orderId);log.setOperateType(2); // 2=回滚inventoryLogMapper.insert(log);return inventoryMapper.updateById(inventory) > 0;} finally {lock.unlock();}}
}

5. 订单服务(order-service)

(1)核心功能:创建订单(整合Seata TCC分布式事务)
// 订单TCC接口(本地事务接口)
public interface OrderTccService {// Try:创建订单(待支付)+ 预扣库存@TwoPhaseBusinessAction(name = "createOrderTcc", commitMethod = "confirm", rollbackMethod = "cancel")boolean tryCreateOrder(@BusinessActionContextParameter(paramName = "orderDTO") OrderDTO orderDTO, BusinessActionContext context);// Confirm:确认订单(支付成功后)boolean confirm(BusinessActionContext context);// Cancel:取消订单(支付失败/超时)boolean cancel(BusinessActionContext context);
}@Service
public class OrderTccServiceImpl implements OrderTccService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate OrderItemMapper orderItemMapper;// Dubbo远程调用库存服务@DubboReferenceprivate InventoryService inventoryService;@Autowiredprivate RocketMQTemplate rocketMQTemplate;@Override@Transactionalpublic boolean tryCreateOrder(OrderDTO orderDTO, BusinessActionContext context) {// 1. 生成订单号String orderSn = IdUtil.fastSimpleUUID();// 2. 创建主订单(状态:待支付)OrderMain orderMain = new OrderMain();orderMain.setOrderSn(orderSn);orderMain.setUserId(orderDTO.getUserId());orderMain.setTotalAmount(orderDTO.getTotalAmount());orderMain.setStatus(0); // 0=待支付orderMapper.insert(orderMain);// 3. 创建订单项for (OrderItemDTO itemDTO : orderDTO.getItems()) {OrderItem orderItem = new OrderItem();orderItem.setOrderId(orderMain.getId());orderItem.setProductId(itemDTO.getProductId());orderItem.setProductName(itemDTO.getProductName());orderItem.setPrice(itemDTO.getPrice());orderItem.setQuantity(itemDTO.getQuantity());orderItemMapper.insert(orderItem);}// 4. 远程调用库存服务预扣库存(Dubbo)boolean deductSuccess = inventoryService.deductStock(orderDTO.getItems().get(0).getProductId(), // 简化:单商品订单,多商品需循环orderDTO.getItems().get(0).getQuantity(),orderSn);if (!deductSuccess) {throw new RuntimeException("库存不足");}// 5. 发送延迟队列(订单超时取消,30分钟延迟)rocketMQTemplate.send("order-delay-topic", MessageBuilder.withPayload(orderSn).setHeader(RocketMQHeaders.DELAY_TIME_LEVEL, 9) // RocketMQ延迟级别9=30分钟.build());// 6. 保存订单号到上下文(用于Confirm/Cancel)context.setActionContext("orderSn", orderSn);return true;}@Override@Transactionalpublic boolean confirm(BusinessActionContext context) {// 支付成功,更新订单状态为“已支付”String orderSn = (String) context.getActionContext("orderSn");OrderMain orderMain = orderMapper.selectByOrderSn(orderSn);orderMain.setStatus(1); // 1=已支付orderMain.setPayTime(new Date());return orderMapper.updateById(orderMain) > 0;}@Override@Transactionalpublic boolean cancel(BusinessActionContext context) {// 支付失败/超时,取消订单+回滚库存String orderSn = (String) context.getActionContext("orderSn");// 1. 更新订单状态为“已取消”OrderMain orderMain = orderMapper.selectByOrderSn(orderSn);orderMain.setStatus(-1); // -1=已取消orderMapper.updateById(orderMain);// 2. 远程调用库存服务回滚库存OrderItem orderItem = orderItemMapper.selectByOrderId(orderMain.getId()).get(0);inventoryService.cancelDeduct(orderItem.getProductId(), orderItem.getQuantity(), orderSn);return true;}
}
(2)订单超时取消(监听RocketMQ延迟队列)
@Component
@RocketMQMessageListener(topic = "order-delay-topic", consumerGroup = "order-delay-consumer")
public class OrderDelayConsumer implements RocketMQListener<String> {@Autowiredprivate OrderMainMapper orderMainMapper;@Autowiredprivate OrderTccService orderTccService;@Overridepublic void onMessage(String orderSn) {// 1. 查询订单状态OrderMain orderMain = orderMainMapper.selectByOrderSn(orderSn);if (orderMain == null) {return;}// 2. 若订单仍为“待支付”,触发取消逻辑if (orderMain.getStatus() == 0) {// 模拟Seata Cancel操作(实际通过Seata事务上下文触发)BusinessActionContext context = new BusinessActionContext();context.setActionContext("orderSn", orderSn);orderTccService.cancel(context);System.out.println("订单" + orderSn + "超时未支付,已自动取消");}}
}

6. 支付服务(pay-service)

(1)核心功能:对接支付宝支付
@Service
public class AlipayServiceImpl implements PayService {@Autowiredprivate PaymentMapper paymentMapper;@DubboReferenceprivate OrderTccService orderTccService;@Value("${alipay.appId}")private String appId;@Value("${alipay.privateKey}")private String privateKey;@Value("${alipay.publicKey}")private String publicKey;@Value("${alipay.notifyUrl}")private String notifyUrl;// 发起支付宝支付@Overridepublic String createAlipayOrder(String orderSn, Long userId, BigDecimal amount) {try {// 1. 构建支付宝客户端AlipayClient client = new DefaultAlipayClient("https://openapi.alipay.com/gateway.do",appId, privateKey, "json", "UTF-8", publicKey, "RSA2");// 2. 构建支付请求AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();request.setReturnUrl("http://localhost:8080/pay/return"); // 同步回调地址request.setNotifyUrl(notifyUrl); // 异步回调地址// 3. 封装请求参数JSONObject bizContent = new JSONObject();bizContent.put("out_trade_no", orderSn); // 订单号(与订单服务一致)bizContent.put("total_amount", amount); // 支付金额bizContent.put("subject", "电商订单支付"); // 订单标题bizContent.put("product_code", "FAST_INSTANT_TRADE_PAY"); // 支付产品码request.setBizContent(bizContent.toString());// 4. 发起请求,获取支付链接AlipayTradePagePayResponse response = client.pageExecute(request);if (response.isSuccess()) {// 5. 记录支付记录Payment payment = new Payment();payment.setOrderSn(orderSn);payment.setUserId(userId);payment.setPayAmount(amount);payment.setPayType(1); // 1=支付宝payment.setStatus(0); // 0=待支付paymentMapper.insert(payment);return response.getBody(); // 返回支付宝支付页面HTML} else {throw new RuntimeException("支付宝支付创建失败:" + response.getMsg());}} catch (Exception e) {throw new RuntimeException("支付异常", e);}}// 支付宝异步回调(验证支付结果)@Overridepublic String handleAlipayNotify(Map<String, String> params) {try {// 1. 验证签名boolean signVerified = AlipaySignature.rsaCheckV1(params, publicKey, "UTF-8", "RSA2");if (!signVerified) {return "fail"; // 签名验证失败}// 2. 验证支付状态String tradeStatus = params.get("trade_status");if (!"TRADE_SUCCESS".equals(tradeStatus)) {return "fail";}// 3. 获取订单信息String orderSn = params.get("out_trade_no");String tradeNo = params.get("trade_no"); // 支付宝交易号BigDecimal payAmount = new BigDecimal(params.get("total_amount"));// 4. 更新支付记录状态Payment payment = paymentMapper.selectByOrderSn(orderSn);if (payment == null || payment.getStatus() != 0) {return "fail"; // 支付记录不存在或已支付}payment.setStatus(1); // 1=已支付payment.setPayTime(new Date());payment.setTradeNo(tradeNo);paymentMapper.updateById(payment);// 5. 触发订单TCC Confirm操作(确认订单)BusinessActionContext context = new BusinessActionContext();context.setActionContext("orderSn", orderSn);orderTccService.confirm(context);return "success"; // 回调成功} catch (Exception e) {return "fail";}}
}

六、服务注册与配置中心(Nacos实战)

1. Nacos部署(Docker方式)

# 拉取Nacos镜像
docker pull nacos/nacos-server:v2.2.3
# 启动Nacos(单机模式)
docker run -d \-p 8848:8848 \-e MODE=standalone \-e SPRING_DATASOURCE_PLATFORM=mysql \-e MYSQL_SERVICE_HOST=192.168.1.100 \-e MYSQL_SERVICE_PORT=3306 \-e MYSQL_SERVICE_DB_NAME=nacos_config \-e MYSQL_SERVICE_USER=root \-e MYSQL_SERVICE_PASSWORD=123456 \--name nacos \nacos/nacos-server:v2.2.3

2. Nacos配置中心使用

(1)创建配置文件
  • 命名规则:${spring.application.name}-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
  • 示例:order-service-dev.yaml(订单服务dev环境配置)
  • 配置内容:
# 数据库配置
spring:datasource:url: jdbc:mysql://192.168.1.100:3306/order_db?useSSL=false&serverTimezone=Asia/Shanghaiusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
# Redis配置
redis:host: 192.168.1.100port: 6379password: 123456database: 0
# JWT配置
jwt:secret: abc1234567890xyzexpire: 86400 # 24小时
# Sentinel配置
sentinel:transport:dashboard: 192.168.1.100:8080 # Sentinel控制台地址
(2)动态刷新配置

在需要动态刷新的类上添加@RefreshScope注解:

@RestController
@RequestMapping("/order")
@RefreshScope // 动态刷新配置
public class OrderController {@Value("${order.timeout:30}") // 默认30分钟private Integer orderTimeout;// 接口使用orderTimeout配置
}

七、网关层设计(Sentinel Gateway)

1. 网关配置(application.yml)

spring:cloud:sentinel:gateway:routes:- id: user-serviceuri: lb://user-servicepredicates:- Path=/api/user/**filters:- StripPrefix=1 # 去掉/api前缀- name: SentinelGatewayFilter # Sentinel限流过滤器- id: order-serviceuri: lb://order-servicepredicates:- Path=/api/order/**filters:- StripPrefix=1- name: SentinelGatewayFilterrules:# 限流规则:按路径限流(订单服务最大QPS=1000)- resource: order-servicelimitApp: defaultgrade: 1 # 1=QPS限流count: 1000 # 最大QPSintervalSec: 1 # 统计时间窗口(秒)# 限流规则:按用户限流(单用户最大QPS=100)- resource: user-servicelimitApp: ${spring.application.name}grade: 1count: 100intervalSec: 1controlBehavior: 2 # 2=匀速排队

2. 统一鉴权过滤器

@Component
public class AuthFilter implements GlobalFilter, Ordered {@Autowiredprivate JwtUtil jwtUtil;@Overridepublic Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {// 1. 跳过登录接口String path = exchange.getRequest().getPath().value();if (path.contains("/user/login")) {return chain.filter(exchange);}// 2. 获取TokenString token = exchange.getRequest().getHeaders().getFirst("Authorization");if (StrUtil.isBlank(token) || !token.startsWith("Bearer ")) {exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}token = token.substring(7);// 3. 验证Tokenif (!jwtUtil.validateToken(token)) {exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);return exchange.getResponse().setComplete();}// 4. 解析用户ID,存入请求头Long userId = jwtUtil.getUserIdFromToken(token);exchange.getRequest().mutate().header("userId", userId.toString()).build();return chain.filter(exchange);}@Overridepublic int getOrder() {return -1; // 执行顺序:先鉴权,再限流}
}

八、分布式事务一致性保障(Seata实战)

1. Seata部署(Docker)

# 拉取Seata镜像
docker pull seataio/seata-server:1.6.1
# 启动Seata Server(TC事务协调器)
docker run -d \-p 8091:8091 \-e SEATA_IP=192.168.1.100 \-e SEATA_PORT=8091 \-e SEATA_CONFIG_NAME=file:/root/seata-config/registry \-v /root/seata-config:/root/seata-config \--name seata-server \seataio/seata-server:1.6.1

2. Seata配置(registry.conf)

registry {type = "nacos" # 注册中心用Nacosnacos {application = "seata-server"serverAddr = "192.168.1.100:8848"group = "SEATA_GROUP"namespace = "dev"username = "nacos"password = "nacos"}
}config {type = "nacos" # 配置中心用Nacosnacos {serverAddr = "192.168.1.100:8848"namespace = "dev"group = "SEATA_GROUP"username = "nacos"password = "nacos"}
}

3. 微服务集成Seata(application.yml)

seata:enabled: trueapplication-id: ${spring.application.name}tx-service-group: order_tx_group # 事务组(需与Seata配置一致)registry:type: nacosnacos:server-addr: 192.168.1.100:8848group: SEATA_GROUPnamespace: devconfig:type: nacosnacos:server-addr: 192.168.1.100:8848group: SEATA_GROUPnamespace: devservice:vgroup-mapping:order_tx_group: default # 事务组映射client:rm:report-success-enable: true

4. 分布式事务模式选择

模式适用场景优点缺点
TCC核心链路(下单-库存-支付)强一致性、性能高代码侵入性高(需写Try/Confirm/Cancel)
AT非核心链路(如订单通知)无侵入性、易实现弱一致性(最终一致)、依赖数据库事务
可靠消息最终一致异步场景(如日志同步)解耦、性能高一致性延迟、需处理消息丢失

九、缓存问题全解(Redis+一致性+防雪崩)

1. 缓存三大问题解决方案

问题解决方案代码示例
缓存穿透(查不存在的数据)布隆过滤器+缓存空值java // 布隆过滤器初始化 @PostConstruct public void initBloomFilter() { List<Long> productIds = productMapper.selectAllProductIds(); BloomFilter<Long> filter = BloomFilter.create(Funnels.longFunnel(), productIds.size(), 0.001); for (Long id : productIds) { filter.put(id); } redisTemplate.opsForValue().set("bloom:product", filter); } // 查询前校验布隆过滤器 if (!filter.mightContain(productId)) { return null; }
缓存击穿(热点key过期)互斥锁+热点数据永不过期java // 互斥锁解决击穿 String lockKey = "lock:product:" + productId; RLock lock = redissonClient.getLock(lockKey); lock.tryLock(5, 30, TimeUnit.SECONDS); try { // 再次查缓存,避免重复查库 String json = redisTemplate.opsForValue().get(cacheKey); if (StrUtil.isNotBlank(json)) { return JSONUtil.toBean(json, Product.class); } // 查库并更新缓存... } finally { lock.unlock(); }
缓存雪崩(大量key同时过期)过期时间加随机值+Redis集群java // 过期时间加随机值 int expire = 3600 + new Random().nextInt(600); redisTemplate.opsForValue().set(cacheKey, json, expire, TimeUnit.SECONDS);

2. 缓存一致性(Cache Aside Pattern)

  • 读流程:先查缓存→缓存命中直接返回→缓存未命中查数据库→存入缓存
  • 写流程:先更数据库→再删缓存(而非更新缓存)
  • 为什么删缓存而非更新?避免并发场景下的缓存脏数据(如A更新数据库,B更新缓存,A再删缓存,导致缓存是B的旧数据)

十、中间件选型与使用

1. RocketMQ(消息队列)

(1)核心使用场景
  • 异步通信:订单创建后通知用户、日志收集
  • 延迟队列:订单超时取消(30分钟延迟)
  • 削峰填谷:秒杀场景异步下单(避免直接压垮数据库)
(2)关键配置
rocketmq:name-server: 192.168.1.100:9876producer:group: order-producer-groupsend-message-timeout: 3000consumer:group: order-consumer-groupmessage-model: CLUSTERING # 集群消费模式

2. Redis(缓存+分布式锁)

(1)Redis集群部署(3主3从)
# 用Docker Compose部署Redis集群(省略复杂配置,实际生产用官方集群工具)
version: '3'
services:redis-master1:image: redis:6.2.6command: redis-server --port 6379 --requirepass 123456ports:- "6379:6379"redis-slave1:image: redis:6.2.6command: redis-server --port 6380 --requirepass 123456 --slaveof redis-master1 6379ports:- "6380:6380"
# 其他主从节点配置省略...
(2)Redisson分布式锁
@Autowired
private RedissonClient redissonClient;// 秒杀场景分布式锁
public boolean seckill(Long productId, Long userId) {String lockKey = "lock:seckill:" + productId;RLock lock = redissonClient.getLock(lockKey);try {// 尝试加锁,5秒超时,30秒自动释放boolean locked = lock.tryLock(5, 30, TimeUnit.SECONDS);if (!locked) {return false; // 秒杀失败(已被抢完)}// 查库存→扣库存→创建订单(省略业务逻辑)return true;} finally {if (lock.isHeldByCurrentThread()) {lock.unlock();}}
}

3. Sharding-JDBC(分库分表)

(1)订单表分库分表配置(application.yml)
spring:shardingsphere:datasource:names: db0,db1 # 两个分库db0:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.1.100:3306/order_db0?useSSL=falseusername: rootpassword: 123456db1:type: com.zaxxer.hikari.HikariDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://192.168.1.100:3306/order_db1?useSSL=falseusername: rootpassword: 123456rules:sharding:tables:order_main: # 订单主表actual-data-nodes: db${0..1}.order_main_${202401..202412} # 分库分表规则(2库12表)database-strategy: # 分库策略:按用户ID哈希standard:sharding-column: user_idsharding-algorithm-name: order_db_inlinetable-strategy: # 分表策略:按创建时间分月standard:sharding-column: create_timesharding-algorithm-name: order_table_inlinesharding-algorithms:order_db_inline:type: INLINEprops:algorithm-expression: db${user_id % 2} # 用户ID%2→db0/db1order_table_inline:type: INLINEprops:algorithm-expression: order_main_${date_format(create_time,'yyyyMM')} # 按年月分表

十一、核心业务实现

1. 订单超时自动取消(两种方案对比)

方案实现方式优点缺点推荐场景
RocketMQ延迟队列订单创建时发送延迟消息,到期消费可靠性高、延迟精度高依赖RocketMQ集群核心订单场景(推荐)
Redis过期键通知订单创建时设置Redis键,监听过期事件实现简单、无中间件依赖过期通知可能延迟、不保证100%送达非核心场景(如优惠券过期)

2. 库存防超卖(三重保障)

  1. 数据库层面:库存扣减时加行锁(select ... for update
  2. 缓存层面:Redis分布式锁(Redisson)
  3. 业务层面:库存预扣+TCC回滚(支付失败回滚库存)

十二、特殊场景优化(秒杀/高并发)

1. 秒杀场景优化方案

(1)架构层面
  • 限流:网关限流(Sentinel)+ 服务限流(Sentinel注解)
  • 削峰:RocketMQ异步下单(避免直接操作数据库)
  • 缓存预热:秒杀商品库存提前加载到Redis(避免缓存穿透)
  • 隔离:秒杀服务独立部署(避免影响核心服务)
(2)代码层面
@Service
public class SeckillServiceImpl implements SeckillService {@Autowiredprivate StringRedisTemplate redisTemplate;@Autowiredprivate RedissonClient redissonClient;@Autowiredprivate RocketMQTemplate rocketMQTemplate;private static final String SECKILL_STOCK_KEY = "seckill:stock:";private static final String SECKILL_USER_KEY = "seckill:user:"; // 防重复秒杀@Override@SentinelResource(value = "seckill", blockHandler = "seckillBlockHandler")public Result<String> seckill(Long productId, Long userId) {String stockKey = SECKILL_STOCK_KEY + productId;String userKey = SECKILL_USER_KEY + productId + ":" + userId;// 1. 防重复秒杀(Redis判断用户是否已秒杀)Boolean hasSeckill = redisTemplate.hasKey(userKey);if (Boolean.TRUE.equals(hasSeckill)) {return Result.fail("您已参与秒杀,请勿重复提交");}// 2. 扣减Redis库存(原子操作,避免超卖)Long stock = redisTemplate.opsForValue().decrement(stockKey);if (stock == null || stock < 0) {// 库存不足,回滚Redis库存redisTemplate.opsForValue().increment(stockKey);return Result.fail("秒杀已结束,库存不足");}// 3. 记录秒杀用户(防止重复)redisTemplate.opsForValue().set(userKey, "1", 24, TimeUnit.HOURS);// 4. 发送异步消息,创建订单(削峰填谷)SeckillDTO seckillDTO = new SeckillDTO();seckillDTO.setProductId(productId);seckillDTO.setUserId(userId);rocketMQTemplate.send("seckill-order-topic", MessageBuilder.withPayload(seckillDTO).build());return Result.success("秒杀成功,订单正在创建");}// Sentinel限流降级回调public Result<String> seckillBlockHandler(Long productId, Long userId, BlockException e) {return Result.fail("当前秒杀人数过多,请稍后再试");}
}

2. 接口幂等性(防重复提交)

  • 实现方式:基于订单号/请求ID去重(Redis)
  • 代码示例:
// 幂等性注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Idempotent {long expire() default 300; // 过期时间(秒)
}// 幂等性切面
@Component
@Aspect
public class IdempotentAspect {@Autowiredprivate StringRedisTemplate redisTemplate;@Around("@annotation(idempotent)")public Object around(ProceedingJoinPoint joinPoint, Idempotent idempotent) throws Throwable {// 1. 获取请求ID(从请求头或参数中)HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();String requestId = request.getHeader("Request-Id");if (StrUtil.isBlank(requestId)) {return Result.fail("Request-Id不能为空");}// 2. 构建Redis键String key = "idempotent:" + requestId;// 3. 尝试设置Redis键(原子操作)Boolean success = redisTemplate.opsForValue().setIfAbsent(key, "1", idempotent.expire(), TimeUnit.SECONDS);if (Boolean.FALSE.equals(success)) {return Result.fail("请勿重复提交");}// 4. 执行目标方法return joinPoint.proceed();}
}// 接口使用
@PostMapping("/createOrder")
@Idempotent(expire = 60) // 60秒内防重复提交
public Result<String> createOrder(@RequestBody OrderDTO orderDTO) {// 下单逻辑
}

十三、环境配置与部署(Docker+K8s)

1. Docker镜像构建(Dockerfile)

# 基础镜像
FROM openjdk:11-jre-slim
# 工作目录
WORKDIR /app
# 复制jar包
COPY target/order-service-1.0.0.jar app.jar
# 暴露端口
EXPOSE 8080
# 启动命令
ENTRYPOINT ["java", "-jar", "app.jar", "--spring.profiles.active=prod"]

2. K8s部署配置(order-service-deployment.yaml)

apiVersion: apps/v1
kind: Deployment
metadata:name: order-servicenamespace: e-commerce
spec:replicas: 3 # 3个副本(高可用)selector:matchLabels:app: order-servicetemplate:metadata:labels:app: order-servicespec:containers:- name: order-serviceimage: order-service:1.0.0ports:- containerPort: 8080resources:limits:cpu: "1"memory: "1Gi"requests:cpu: "0.5"memory: "512Mi"livenessProbe: # 健康检查httpGet:path: /actuator/healthport: 8080initialDelaySeconds: 60periodSeconds: 10readinessProbe:httpGet:path: /actuator/healthport: 8080initialDelaySeconds: 30periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:name: order-servicenamespace: e-commerce
spec:selector:app: order-serviceports:- port: 80targetPort: 8080type: ClusterIP # 集群内部访问

3. 部署流程

# 1. 打包Jar包
mvn clean package -Dmaven.test.skip=true
# 2. 构建Docker镜像
docker build -t order-service:1.0.0 .
# 3. 推送镜像到仓库(Harbor)
docker tag order-service:1.0.0 192.168.1.100:8080/e-commerce/order-service:1.0.0
docker push 192.168.1.100:8080/e-commerce/order-service:1.0.0
# 4. K8s部署
kubectl apply -f order-service-deployment.yaml
# 5. 查看部署状态
kubectl get pods -n e-commerce

十四、监控与运维

1. 全链路监控(Prometheus+Grafana)

(1)微服务集成Prometheus
<!-- pom.xml依赖 -->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency><groupId>io.micrometer</groupId><artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
(2)application.yml配置
management:endpoints:web:exposure:include: health,info,prometheus # 暴露监控端点metrics:tags:application: ${spring.application.name} # 增加应用名称标签endpoint:health:show-details: always # 显示健康详情
(3)Grafana面板配置
  • 导入Spring Boot监控模板(ID:12856)
  • 监控指标:QPS、响应时间、错误率、JVM内存、数据库连接数

2. 日志收集(ELK)

  • Logstash:收集微服务日志(Docker日志挂载到宿主机)
  • Elasticsearch:存储日志数据
  • Kibana:可视化日志查询与分析

3. 告警机制

  • 配置Prometheus告警规则(如响应时间>3s、错误率>5%)
  • 集成AlertManager,通过邮件/钉钉/短信发送告警

总结

本文基于Spring Cloud Alibaba生态,详细讲解了微服务电商项目的全流程开发,从需求分析、数据库设计、技术选型,到核心服务开发、分布式事务、缓存优化、高并发处理,再到部署运维,覆盖了电商项目的核心痛点(如分布式一致性、库存超卖、订单超时、高并发秒杀)。

关键亮点:

  1. 基于Seata TCC模式保证核心链路一致性
  2. 多重缓存策略解决缓存穿透/击穿/雪崩问题
  3. RocketMQ延迟队列实现订单超时取消
  4. 分布式锁+数据库行锁双重防超卖
  5. K8s容器化部署保证高可用

实际开发中,需根据业务规模调整架构(如小体量项目可简化分库分表、Seata用AT模式),同时定期进行故障演练(如Chaos Monkey模拟服务宕机),验证熔断、降级、兜底逻辑的有效性。

http://www.dtcms.com/a/606409.html

相关文章:

  • 2025中国密码学会年会“人才培养论坛”成功举办,产学共探密码人才培育新路径
  • 高质量网站外链建设大揭秘网址收录大全
  • 网站建设的数字化和互联网化建设局工作怎么样
  • resource 和 K8S 对接部分 apifox
  • C语言编译器下载地址 | 提供多种C语言编译工具下载链接与使用指南
  • 网站备案跟网安备案区别展厅设计制作
  • 公司建立网站流程图开原网站制作
  • Python工程师的职业发展路径:专家访谈
  • 研发管理知识库(8)Terraform 简介
  • 网站后台常用密码工业设计公司如何选择
  • 做民宿的网站有哪些抖音代运营大概多少钱一个月
  • C++模块化项目构建入门教
  • Ansible Playbook入门指南:核心语法与实战
  • 苏州高端网站建设设计公司哪家好wordpress 多个页面
  • 云手机是真实手机吗
  • 制作网站的详细步骤江阴便宜做网站
  • 建设局考试通知文件网站苏州工业园区有哪些企业
  • Git LFS
  • 负氧离子监测站:精准捕捉空气中的负氧离子浓度
  • GitLab下载安装
  • 建网站公司哪里好了解做房产广告的网站
  • 机器人运动控制全解析:从经典架构到AI智能体的进化之路
  • 北京三原色ps网站北京个人网站公司
  • 东莞网站建设求职简历类似淘宝网站模板
  • laravel插件---验证码插件
  • 网站1级域名换2级的影响收录吗seo工具助力集群式网站升级
  • 用大模型的“生成力”弥补检索的“语义缺口”
  • 北京著名网站建设如何在海外推广网站
  • 网站开发与维护做网站的电脑配置
  • MySQL全面安全加固实战指南