第375集用户续费订单Java微服务后端架构实战 | 字数总计: 3.7k | 阅读时长: 16分钟 | 阅读量:
用户续费订单Java微服务后端架构实战 1. 架构概述 用户续费订单系统是电商平台和租赁平台的核心模块,需要支持基于有效订单复制生成新订单,简化用户续费流程。本篇文章将深入讲解如何基于Java微服务架构实现一个高性能、高可用、用户友好的用户续费订单系统。
1.1 系统架构图 1 2 3 4 5 6 7 8 9 10 11 用户端 → 用户网关 → 订单服务 → 数据库 ↓ 身份认证 ↓ 判断用户存在有效订单 ↓ 复制有效订单信息 ↓ 生成新未支付订单 ↓ 返回续费结果
1.2 核心组件
用户网关(User Gateway) :负责用户请求的接入、身份认证、请求路由
订单服务(Order Service) :负责订单管理、有效订单查询、订单信息复制、新订单生成
数据库(MySQL) :持久化订单信息
分布式锁(Redisson) :保证订单生成的并发安全
事务管理 :保证续费订单生成的原子性和一致性
2. 用户网关服务实现 2.1 用户网关服务核心代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 @RestController @RequestMapping("/api/user/gateway") @Slf4j public class UserGatewayController { @Autowired private AuthService authService; @Autowired private OrderServiceClient orderServiceClient; @PostMapping("/order/renewal") public Result<OrderRenewalResult> renewalOrder ( @RequestHeader("Authorization") String token, @RequestBody OrderRenewalRequest request) { try { UserInfo userInfo = authService.authenticate(token); if (userInfo == null ) { return Result.error("身份认证失败" ); } request.setUserId(userInfo.getUserId()); OrderRenewalResult result = orderServiceClient.renewalOrder(request); if (!result.isSuccess()) { return Result.error(result.getMessage()); } log.info("用户续费订单成功: userId={}, originalOrderId={}, newOrderId={}, newOrderNo={}" , userInfo.getUserId(), request.getOriginalOrderId(), result.getNewOrderId(), result.getNewOrderNo()); return Result.success(result); } catch (Exception e) { log.error("用户续费订单失败: originalOrderId={}, error={}" , request.getOriginalOrderId(), e.getMessage(), e); return Result.error("续费订单失败: " + e.getMessage()); } } }
2.2 身份认证服务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 @Service @Slf4j public class AuthService { @Autowired private RedisTemplate<String, Object> redisTemplate; @Autowired private UserServiceClient userServiceClient; public UserInfo authenticate (String token) { try { String userId = parseToken(token); if (StringUtils.isEmpty(userId)) { return null ; } String userCacheKey = "user:info:" + userId; UserInfo userInfo = (UserInfo) redisTemplate.opsForValue().get(userCacheKey); if (userInfo != null ) { return userInfo; } userInfo = userServiceClient.getUserInfo(userId); if (userInfo != null ) { redisTemplate.opsForValue().set(userCacheKey, userInfo, 30 , TimeUnit.MINUTES); } return userInfo; } catch (Exception e) { log.error("身份认证失败: token={}, error={}" , token, e.getMessage(), e); return null ; } } private String parseToken (String token) { if (StringUtils.isEmpty(token) || !token.startsWith("Bearer " )) { return null ; } String jwtToken = token.substring(7 ); return extractUserIdFromJWT(jwtToken); } private String extractUserIdFromJWT (String jwtToken) { return "user123" ; } }
3. 订单服务实现 3.1 订单服务核心代码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 @Service @Slf4j public class OrderService { @Autowired private OrderMapper orderMapper; @Autowired private RedissonClient redissonClient; @Transactional(rollbackFor = Exception.class) public OrderRenewalResult renewalOrder (OrderRenewalRequest request) { String lockKey = "order:renewal:lock:" + request.getUserId(); RLock lock = redissonClient.getLock(lockKey); try { if (lock.tryLock(10 , TimeUnit.SECONDS)) { Order originalOrder = null ; if (request.getOriginalOrderId() != null ) { originalOrder = orderMapper.selectById(request.getOriginalOrderId()); if (originalOrder == null ) { return OrderRenewalResult.failed("原订单不存在" ); } if (!originalOrder.getUserId().equals(request.getUserId())) { return OrderRenewalResult.failed("无权限续费该订单" ); } } else { List<Order> validOrders = getValidOrders(request.getUserId(), request.getProductId()); if (validOrders.isEmpty()) { return OrderRenewalResult.failed("用户不存在有效订单,无法续费" ); } originalOrder = validOrders.get(0 ); } if (!isValidOrderForRenewal(originalOrder)) { return OrderRenewalResult.failed("原订单状态不允许续费,当前状态: " + originalOrder.getStatus()); } Order newOrder = copyOrderInfo(originalOrder); newOrder.setOrderNo(generateOrderNo()); newOrder.setStatus(OrderStatus.UNPAID.getCode()); newOrder.setOriginalOrderId(originalOrder.getId()); newOrder.setOriginalOrderNo(originalOrder.getOrderNo()); newOrder.setRenewalType("MANUAL" ); newOrder.setCreateTime(new Date ()); newOrder.setUpdateTime(new Date ()); newOrder.setPayTime(null ); newOrder.setTransactionNo(null ); orderMapper.insert(newOrder); log.info("续费订单生成成功: originalOrderId={}, originalOrderNo={}, newOrderId={}, newOrderNo={}, userId={}" , originalOrder.getId(), originalOrder.getOrderNo(), newOrder.getId(), newOrder.getOrderNo(), request.getUserId()); OrderRenewalResult result = new OrderRenewalResult (); result.setSuccess(true ); result.setOriginalOrderId(originalOrder.getId()); result.setOriginalOrderNo(originalOrder.getOrderNo()); result.setNewOrderId(newOrder.getId()); result.setNewOrderNo(newOrder.getOrderNo()); result.setAmount(newOrder.getFinalAmount()); result.setProductId(newOrder.getProductId()); result.setProductName(newOrder.getProductName()); result.setMessage("续费订单生成成功" ); return result; } else { return OrderRenewalResult.failed("续费订单操作超时,请稍后再试" ); } } catch (Exception e) { log.error("续费订单失败: userId={}, originalOrderId={}, error={}" , request.getUserId(), request.getOriginalOrderId(), e.getMessage(), e); return OrderRenewalResult.failed("续费订单失败: " + e.getMessage()); } finally { if (lock.isHeldByCurrentThread()) { lock.unlock(); } } } private List<Order> getValidOrders (Long userId, Long productId) { QueryWrapper<Order> queryWrapper = new QueryWrapper <>(); queryWrapper.eq("user_id" , userId); if (productId != null ) { queryWrapper.eq("product_id" , productId); } queryWrapper.in("status" , OrderStatus.PAID.getCode(), OrderStatus.COMPLETED.getCode()); queryWrapper.eq("deleted" , 0 ); queryWrapper.orderByDesc("create_time" ); return orderMapper.selectList(queryWrapper); } private boolean isValidOrderForRenewal (Order order) { String status = order.getStatus(); return OrderStatus.PAID.getCode().equals(status) || OrderStatus.COMPLETED.getCode().equals(status); } private Order copyOrderInfo (Order originalOrder) { Order newOrder = new Order (); newOrder.setUserId(originalOrder.getUserId()); newOrder.setProductId(originalOrder.getProductId()); newOrder.setProductName(originalOrder.getProductName()); newOrder.setQuantity(originalOrder.getQuantity()); newOrder.setOriginalAmount(originalOrder.getOriginalAmount()); newOrder.setDiscountAmount(originalOrder.getDiscountAmount()); newOrder.setFinalAmount(originalOrder.getFinalAmount()); newOrder.setDepositAmount(originalOrder.getDepositAmount()); newOrder.setCouponIds(originalOrder.getCouponIds()); newOrder.setProductType(originalOrder.getProductType()); newOrder.setProductCode(originalOrder.getProductCode()); newOrder.setRemark("续费订单,原订单号: " + originalOrder.getOrderNo()); return newOrder; } private String generateOrderNo () { return "ORD" + System.currentTimeMillis() + RandomUtils.nextInt(10000 , 99999 ); } public List<Order> getUserRenewalOrders (Long userId, Long originalOrderId) { QueryWrapper<Order> queryWrapper = new QueryWrapper <>(); queryWrapper.eq("user_id" , userId); queryWrapper.eq("original_order_id" , originalOrderId); queryWrapper.eq("deleted" , 0 ); queryWrapper.orderByDesc("create_time" ); return orderMapper.selectList(queryWrapper); } }
4. 数据模型定义 4.1 订单续费请求 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Data public class OrderRenewalRequest { private Long userId; private Long originalOrderId; private Long productId; }
4.2 订单续费结果 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 @Data public class OrderRenewalResult { private Boolean success; private Long originalOrderId; private String originalOrderNo; private Long newOrderId; private String newOrderNo; private BigDecimal amount; private Long productId; private String productName; private String message; public static OrderRenewalResult failed (String message) { OrderRenewalResult result = new OrderRenewalResult (); result.setSuccess(false ); result.setMessage(message); return result; } }
4.3 订单(更新字段) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 @Data @TableName("order") public class Order { @TableId(type = IdType.AUTO) private Long id; private String orderNo; private Long userId; private Long productId; private String productName; private String productType; private String productCode; private Integer quantity; private BigDecimal originalAmount; private BigDecimal discountAmount; private BigDecimal finalAmount; private BigDecimal depositAmount; private String couponIds; private String status; private Long originalOrderId; private String originalOrderNo; private String renewalType; private String transactionNo; private Date payTime; private String remark; private Date createTime; private Date updateTime; }
4.4 订单状态枚举 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 public enum OrderStatus { UNPAID("UNPAID" , "未支付" ), PAID("PAID" , "已支付" ), CANCELLED("CANCELLED" , "已取消" ), COMPLETED("COMPLETED" , "已完成" ), REFUNDED("REFUNDED" , "已退款" ); private final String code; private final String name; OrderStatus(String code, String name) { this .code = code; this .name = name; } public String getCode () { return code; } public String getName () { return name; } }
5. 数据库Mapper实现 5.1 OrderMapper 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 @Mapper public interface OrderMapper extends BaseMapper <Order> { @Select("SELECT * FROM `order` WHERE order_no = #{orderNo} AND deleted = 0") Order selectByOrderNo (@Param("orderNo") String orderNo) ; @Select("SELECT * FROM `order` " + "WHERE user_id = #{userId} " + "AND product_id = #{productId} " + "AND status IN ('PAID', 'COMPLETED') " + "AND deleted = 0 " + "ORDER BY create_time DESC") List<Order> selectValidOrdersByUserIdAndProductId ( @Param("userId") Long userId, @Param("productId") Long productId) ; @Select("SELECT * FROM `order` " + "WHERE user_id = #{userId} " + "AND original_order_id = #{originalOrderId} " + "AND deleted = 0 " + "ORDER BY create_time DESC") List<Order> selectRenewalOrdersByOriginalOrderId ( @Param("userId") Long userId, @Param("originalOrderId") Long originalOrderId) ;}
6. 数据库表设计 6.1 订单表(更新字段) 1 2 3 4 5 6 7 ALTER TABLE `order ` ADD COLUMN `original_order_id` bigint (20 ) DEFAULT NULL COMMENT '原订单ID(续费订单关联的原订单)' AFTER `status`,ADD COLUMN `original_order_no` varchar (64 ) DEFAULT NULL COMMENT '原订单号(续费订单关联的原订单号)' AFTER `original_order_id`,ADD COLUMN `renewal_type` varchar (20 ) DEFAULT NULL COMMENT '续费类型:MANUAL-手动续费, AUTO-自动续费' AFTER `original_order_no`,ADD KEY `idx_original_order_id` (`original_order_id`),ADD KEY `idx_user_id_product_id` (`user_id`, `product_id`);
7. 续费订单查询服务 7.1 续费订单查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 @Service @Slf4j public class OrderRenewalQueryService { @Autowired private OrderMapper orderMapper; public List<Order> getValidOrdersForRenewal (Long userId, Long productId) { try { List<Order> validOrders = orderMapper.selectValidOrdersByUserIdAndProductId( userId, productId); return validOrders; } catch (Exception e) { log.error("查询用户有效订单失败: userId={}, productId={}, error={}" , userId, productId, e.getMessage(), e); return new ArrayList <>(); } } public List<Order> getRenewalOrders (Long userId, Long originalOrderId) { try { List<Order> renewalOrders = orderMapper.selectRenewalOrdersByOriginalOrderId( userId, originalOrderId); return renewalOrders; } catch (Exception e) { log.error("查询续费订单列表失败: userId={}, originalOrderId={}, error={}" , userId, originalOrderId, e.getMessage(), e); return new ArrayList <>(); } } public OrderRenewalHistory getOrderRenewalHistory (Long originalOrderId) { try { Order originalOrder = orderMapper.selectById(originalOrderId); if (originalOrder == null ) { return null ; } List<Order> renewalOrders = orderMapper.selectRenewalOrdersByOriginalOrderId( originalOrder.getUserId(), originalOrderId); OrderRenewalHistory history = new OrderRenewalHistory (); history.setOriginalOrder(originalOrder); history.setRenewalOrders(renewalOrders); history.setRenewalCount(renewalOrders.size()); return history; } catch (Exception e) { log.error("查询订单续费历史失败: originalOrderId={}, error={}" , originalOrderId, e.getMessage(), e); return null ; } } }
7.2 续费历史数据模型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Data public class OrderRenewalHistory { private Order originalOrder; private List<Order> renewalOrders; private Integer renewalCount; }
8. 性能优化策略 8.1 有效订单缓存 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 @Service @Slf4j public class ValidOrderCacheService { @Autowired private RedisTemplate<String, Object> redisTemplate; @Autowired private OrderMapper orderMapper; public List<Order> getValidOrders (Long userId, Long productId) { String cacheKey = "user:valid:orders:" + userId + ":" + productId; List<Order> orders = (List<Order>) redisTemplate.opsForValue().get(cacheKey); if (orders != null ) { return orders; } orders = orderMapper.selectValidOrdersByUserIdAndProductId(userId, productId); if (orders != null && !orders.isEmpty()) { redisTemplate.opsForValue().set(cacheKey, orders, 5 , TimeUnit.MINUTES); } return orders != null ? orders : new ArrayList <>(); } public void updateValidOrderCache (Long userId, Long productId) { String cacheKey = "user:valid:orders:" + userId + ":" + productId; redisTemplate.delete(cacheKey); } public void deleteValidOrderCache (Long userId, Long productId) { String cacheKey = "user:valid:orders:" + userId + ":" + productId; redisTemplate.delete(cacheKey); } }
9. 续费订单扩展功能 9.1 自动续费功能 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 @Service @Slf4j public class AutoRenewalService { @Autowired private OrderService orderService; @Autowired private OrderMapper orderMapper; @Scheduled(cron = "0 0 1 * * ?") public void autoRenewalOrders () { try { Date expiryDate = DateUtils.addDays(new Date (), 3 ); List<Order> expiringOrders = orderMapper.selectExpiringOrders(expiryDate); log.info("查询到即将到期的订单数量: {}" , expiringOrders.size()); for (Order order : expiringOrders) { try { OrderRenewalRequest request = new OrderRenewalRequest (); request.setUserId(order.getUserId()); request.setOriginalOrderId(order.getId()); OrderRenewalResult result = orderService.renewalOrder(request); if (result.isSuccess()) { log.info("自动续费订单生成成功: originalOrderId={}, newOrderId={}" , order.getId(), result.getNewOrderId()); } else { log.warn("自动续费订单生成失败: originalOrderId={}, error={}" , order.getId(), result.getMessage()); } } catch (Exception e) { log.error("自动续费订单处理失败: orderId={}, error={}" , order.getId(), e.getMessage(), e); } } } catch (Exception e) { log.error("自动续费订单任务执行失败: error={}" , e.getMessage(), e); } } }
9.2 续费订单统计 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 @Service @Slf4j public class OrderRenewalStatisticsService { @Autowired private OrderMapper orderMapper; public Integer countUserRenewalTimes (Long userId, Long originalOrderId) { List<Order> renewalOrders = orderMapper.selectRenewalOrdersByOriginalOrderId( userId, originalOrderId); return renewalOrders.size(); } public BigDecimal calculateUserRenewalTotalAmount (Long userId, Long originalOrderId) { List<Order> renewalOrders = orderMapper.selectRenewalOrdersByOriginalOrderId( userId, originalOrderId); return renewalOrders.stream() .map(Order::getFinalAmount) .reduce(BigDecimal.ZERO, BigDecimal::add); } }
10. 总结 本文详细介绍了用户续费订单的Java微服务架构实现,包括:
用户网关服务 :负责用户请求接入、身份认证、请求路由
订单服务 :负责订单管理、有效订单查询、订单信息复制、新订单生成
续费流程 :
用户续费订单请求
身份认证
判断用户存在有效订单
复制有效订单信息
生成新未支付订单
返回续费结果
订单复制 :完整复制原订单的商品信息、金额信息、优惠券信息
有效订单查询 :支持按用户ID和商品ID查询有效订单
续费历史 :支持查询订单续费历史记录
自动续费 :支持定时任务自动续费
性能优化 :有效订单缓存,提升查询性能
该架构具有以下优势:
用户友好 :简化续费流程,一键续费
数据一致性 :事务管理保证续费订单生成的原子性
高性能 :分布式锁保证并发安全,有效订单缓存提升性能
高可用 :数据库持久化,支持数据恢复
可扩展 :微服务架构,支持水平扩展
完整性 :完整的续费订单管理和历史记录
通过本文的实战代码,可以快速搭建一个高性能、高可用、用户友好的用户续费订单系统。