实战案例:电商系统订单处理流程的技术实现
场景需求分析
业务背景
电商系统的订单处理是一个复杂的业务流程,涉及多个环节的协调配合。从用户下单到订单完成,需要经过订单创建、支付验证、库存检查、物流分配等多个步骤。每个步骤都有其特定的业务逻辑和异常处理需求。
核心业务流程
flowchart TD
A[用户下单] --> B[订单创建]
B --> C[参数验证]
C --> D[库存检查]
D --> E[价格计算]
E --> F[优惠券验证]
F --> G[支付验证]
G --> H[库存扣减]
H --> I[物流分配]
I --> J[订单确认]
J --> K[发送通知]
C -->|验证失败| L[订单取消]
D -->|库存不足| L
F -->|优惠券无效| L
G -->|支付失败| L
H -->|扣减失败| M[回滚操作]
I -->|分配失败| M
业务需求
- 订单创建:验证用户信息、商品信息、收货地址等
- 支付验证:验证支付方式、支付金额、支付状态等
- 库存检查:检查商品库存、预占库存、库存扣减
- 物流分配:选择配送方式、计算运费、分配仓库
- 异常处理:支持流程回滚、异常通知、重试机制
- 性能要求:高并发处理、快速响应、数据一致性
责任链模式设计思路
整体架构设计
classDiagram
class OrderContext {
-orderId: String
-userId: String
-orderItems: List~OrderItem~
-paymentInfo: PaymentInfo
-shippingInfo: ShippingInfo
-orderStatus: OrderStatus
+getOrderAmount() BigDecimal
+addOrderItem(OrderItem item)
+setOrderStatus(OrderStatus status)
}
class OrderHandler {
<<abstract>>
+handle(OrderContext context) boolean
+rollback(OrderContext context) void
}
class OrderValidationHandler {
+handle(OrderContext context) boolean
+rollback(OrderContext context) void
}
class InventoryCheckHandler {
+handle(OrderContext context) boolean
+rollback(OrderContext context) void
}
class PaymentHandler {
+handle(OrderContext context) boolean
+rollback(OrderContext context) void
}
class LogisticsHandler {
+handle(OrderContext context) boolean
+rollback(OrderContext context) void
}
OrderHandler <|-- OrderValidationHandler
OrderHandler <|-- InventoryCheckHandler
OrderHandler <|-- PaymentHandler
OrderHandler <|-- LogisticsHandler
设计原则
- 单一职责:每个处理器只负责一个特定的业务环节
- 可扩展性:支持动态添加新的处理步骤
- 事务性:支持流程回滚和补偿机制
- 可监控性:提供详细的执行日志和性能指标
- 容错性:具备异常处理和重试能力
核心代码实现
1. 订单上下文定义
/**
* 订单处理上下文
*/
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class OrderContext {
// 基本信息
private String orderId;
private String userId;
private Long timestamp;
// 订单商品
private List<OrderItem> orderItems;
// 支付信息
private PaymentInfo paymentInfo;
// 配送信息
private ShippingInfo shippingInfo;
// 订单状态
private OrderStatus orderStatus;
// 处理结果
private OrderResult orderResult;
// 扩展属性
private Map<String, Object> attributes = new HashMap<>();
// 回滚栈
private Stack<RollbackAction> rollbackStack = new Stack<>();
/**
* 计算订单总金额
*/
public BigDecimal getOrderAmount() {
return orderItems.stream()
.map(item -> item.getPrice().multiply(BigDecimal.valueOf(item.getQuantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
/**
* 添加回滚动作
*/
public void addRollbackAction(RollbackAction action) {
rollbackStack.push(action);
}
/**
* 执行回滚
*/
public void executeRollback() {
while (!rollbackStack.isEmpty()) {
RollbackAction action = rollbackStack.pop();
try {
action.rollback();
} catch (Exception e) {
log.error("Rollback action failed: {}", e.getMessage(), e);
}
}
}
/**
* 设置处理结果
*/
public void setResult(boolean success, String message) {
this.orderResult = OrderResult.builder()
.success(success)
.message(message)
.timestamp(System.currentTimeMillis())
.build();
}
}
/**
* 订单商品
*/
@Data
@Builder
public class OrderItem {
private String productId;
private String productName;
private BigDecimal price;
private Integer quantity;
private String skuId;
private Map<String, Object> attributes;
}
/**
* 支付信息
*/
@Data
@Builder
public class PaymentInfo {
private String paymentMethod;
private BigDecimal amount;
private String paymentId;
private String paymentStatus;
private Long paymentTime;
}
/**
* 配送信息
*/
@Data
@Builder
public class ShippingInfo {
private String receiverName;
private String receiverPhone;
private String shippingAddress;
private String shippingMethod;
private BigDecimal shippingFee;
private String warehouseId;
}
/**
* 订单状态枚举
*/
public enum OrderStatus {
CREATED("已创建"),
VALIDATED("已验证"),
INVENTORY_CHECKED("库存已检查"),
PAYMENT_VERIFIED("支付已验证"),
INVENTORY_RESERVED("库存已预占"),
LOGISTICS_ASSIGNED("物流已分配"),
CONFIRMED("已确认"),
CANCELLED("已取消"),
FAILED("处理失败");
private final String description;
OrderStatus(String description) {
this.description = description;
}
}
/**
* 回滚动作接口
*/
@FunctionalInterface
public interface RollbackAction {
void rollback() throws Exception;
}
2. 抽象订单处理器
/**
* 抽象订单处理器
*/
@Slf4j
public abstract class AbstractOrderHandler extends AbstractHandler<OrderContext, OrderResult> {
@Override
protected final boolean doHandle(Context<OrderContext, OrderResult> context) {
OrderContext orderContext = context.getRequest();
try {
// 记录处理开始
logProcessStart(orderContext);
// 执行具体的业务逻辑
boolean result = processOrder(orderContext);
if (result) {
// 处理成功,记录日志
logProcessSuccess(orderContext);
return true;
} else {
// 处理失败,执行回滚
logProcessFailure(orderContext, "Business logic returned false");
executeRollback(orderContext);
return false;
}
} catch (Exception e) {
// 异常处理
logProcessError(orderContext, e);
executeRollback(orderContext);
// 设置错误结果
orderContext.setResult(false, "Processing failed: " + e.getMessage());
context.setResponse(orderContext.getOrderResult());
return false;
}
}
/**
* 具体的订单处理逻辑,由子类实现
*/
protected abstract boolean processOrder(OrderContext orderContext) throws Exception;
/**
* 执行回滚操作
*/
private void executeRollback(OrderContext orderContext) {
try {
orderContext.executeRollback();
log.info("Rollback completed for order: {}", orderContext.getOrderId());
} catch (Exception e) {
log.error("Rollback failed for order: {}", orderContext.getOrderId(), e);
}
}
/**
* 记录处理开始
*/
private void logProcessStart(OrderContext orderContext) {
log.info("Starting {} for order: {}, status: {}",
this.getClass().getSimpleName(),
orderContext.getOrderId(),
orderContext.getOrderStatus());
}
/**
* 记录处理成功
*/
private void logProcessSuccess(OrderContext orderContext) {
log.info("Completed {} for order: {}, new status: {}",
this.getClass().getSimpleName(),
orderContext.getOrderId(),
orderContext.getOrderStatus());
}
/**
* 记录处理失败
*/
private void logProcessFailure(OrderContext orderContext, String reason) {
log.warn("Failed {} for order: {}, reason: {}",
this.getClass().getSimpleName(),
orderContext.getOrderId(),
reason);
}
/**
* 记录处理异常
*/
private void logProcessError(OrderContext orderContext, Exception e) {
log.error("Error in {} for order: {}",
this.getClass().getSimpleName(),
orderContext.getOrderId(), e);
}
}
3. 具体处理器实现
订单验证处理器
/**
* 订单验证处理器
*/
@Component
@Slf4j
public class OrderValidationHandler extends AbstractOrderHandler {
@Autowired
private UserService userService;
@Autowired
private ProductService productService;
@Override
protected boolean processOrder(OrderContext orderContext) throws Exception {
// 1. 验证用户信息
if (!validateUser(orderContext)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 2. 验证商品信息
if (!validateProducts(orderContext)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 3. 验证收货地址
if (!validateShippingInfo(orderContext)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 4. 验证订单金额
if (!validateOrderAmount(orderContext)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 验证通过,更新状态
orderContext.setOrderStatus(OrderStatus.VALIDATED);
return true;
}
/**
* 验证用户信息
*/
private boolean validateUser(OrderContext orderContext) {
try {
User user = userService.getUserById(orderContext.getUserId());
if (user == null) {
log.warn("User not found: {}", orderContext.getUserId());
return false;
}
if (!user.isActive()) {
log.warn("User is not active: {}", orderContext.getUserId());
return false;
}
// 将用户信息存储到上下文
orderContext.getAttributes().put("user", user);
return true;
} catch (Exception e) {
log.error("Failed to validate user: {}", orderContext.getUserId(), e);
return false;
}
}
/**
* 验证商品信息
*/
private boolean validateProducts(OrderContext orderContext) {
try {
for (OrderItem item : orderContext.getOrderItems()) {
Product product = productService.getProductById(item.getProductId());
if (product == null) {
log.warn("Product not found: {}", item.getProductId());
return false;
}
if (!product.isAvailable()) {
log.warn("Product is not available: {}", item.getProductId());
return false;
}
// 验证价格
if (item.getPrice().compareTo(product.getPrice()) != 0) {
log.warn("Price mismatch for product: {}, expected: {}, actual: {}",
item.getProductId(), product.getPrice(), item.getPrice());
return false;
}
}
return true;
} catch (Exception e) {
log.error("Failed to validate products for order: {}", orderContext.getOrderId(), e);
return false;
}
}
/**
* 验证收货地址
*/
private boolean validateShippingInfo(OrderContext orderContext) {
ShippingInfo shippingInfo = orderContext.getShippingInfo();
if (StringUtils.isBlank(shippingInfo.getReceiverName())) {
log.warn("Receiver name is required for order: {}", orderContext.getOrderId());
return false;
}
if (StringUtils.isBlank(shippingInfo.getReceiverPhone())) {
log.warn("Receiver phone is required for order: {}", orderContext.getOrderId());
return false;
}
if (StringUtils.isBlank(shippingInfo.getShippingAddress())) {
log.warn("Shipping address is required for order: {}", orderContext.getOrderId());
return false;
}
return true;
}
/**
* 验证订单金额
*/
private boolean validateOrderAmount(OrderContext orderContext) {
BigDecimal calculatedAmount = orderContext.getOrderAmount();
BigDecimal paymentAmount = orderContext.getPaymentInfo().getAmount();
if (calculatedAmount.compareTo(paymentAmount) != 0) {
log.warn("Amount mismatch for order: {}, calculated: {}, payment: {}",
orderContext.getOrderId(), calculatedAmount, paymentAmount);
return false;
}
return true;
}
}
库存检查处理器
/**
* 库存检查处理器
*/
@Component
@Slf4j
public class InventoryCheckHandler extends AbstractOrderHandler {
@Autowired
private InventoryService inventoryService;
@Override
protected boolean processOrder(OrderContext orderContext) throws Exception {
List<String> insufficientProducts = new ArrayList<>();
// 检查所有商品的库存
for (OrderItem item : orderContext.getOrderItems()) {
int availableStock = inventoryService.getAvailableStock(item.getProductId(), item.getSkuId());
if (availableStock < item.getQuantity()) {
log.warn("Insufficient stock for product: {}, required: {}, available: {}",
item.getProductId(), item.getQuantity(), availableStock);
insufficientProducts.add(item.getProductId());
}
}
// 如果有库存不足的商品,返回失败
if (!insufficientProducts.isEmpty()) {
orderContext.setResult(false, "Insufficient stock for products: " +
String.join(", ", insufficientProducts));
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 预占库存
if (!reserveInventory(orderContext)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 库存检查通过
orderContext.setOrderStatus(OrderStatus.INVENTORY_CHECKED);
return true;
}
/**
* 预占库存
*/
private boolean reserveInventory(OrderContext orderContext) {
List<InventoryReservation> reservations = new ArrayList<>();
try {
// 逐个预占库存
for (OrderItem item : orderContext.getOrderItems()) {
InventoryReservation reservation = inventoryService.reserveInventory(
item.getProductId(), item.getSkuId(), item.getQuantity(), orderContext.getOrderId());
if (reservation == null) {
log.error("Failed to reserve inventory for product: {}", item.getProductId());
// 回滚已预占的库存
rollbackReservations(reservations);
return false;
}
reservations.add(reservation);
}
// 添加回滚动作
orderContext.addRollbackAction(() -> rollbackReservations(reservations));
// 将预占信息存储到上下文
orderContext.getAttributes().put("inventoryReservations", reservations);
log.info("Successfully reserved inventory for order: {}", orderContext.getOrderId());
return true;
} catch (Exception e) {
log.error("Failed to reserve inventory for order: {}", orderContext.getOrderId(), e);
rollbackReservations(reservations);
return false;
}
}
/**
* 回滚库存预占
*/
private void rollbackReservations(List<InventoryReservation> reservations) {
for (InventoryReservation reservation : reservations) {
try {
inventoryService.releaseReservation(reservation.getReservationId());
log.info("Released inventory reservation: {}", reservation.getReservationId());
} catch (Exception e) {
log.error("Failed to release inventory reservation: {}",
reservation.getReservationId(), e);
}
}
}
}
支付验证处理器
/**
* 支付验证处理器
*/
@Component
@Slf4j
public class PaymentVerificationHandler extends AbstractOrderHandler {
@Autowired
private PaymentService paymentService;
@Override
protected boolean processOrder(OrderContext orderContext) throws Exception {
PaymentInfo paymentInfo = orderContext.getPaymentInfo();
// 1. 验证支付方式
if (!validatePaymentMethod(paymentInfo)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 2. 验证支付状态
if (!verifyPaymentStatus(paymentInfo)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 3. 验证支付金额
if (!verifyPaymentAmount(orderContext)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 4. 创建支付记录
if (!createPaymentRecord(orderContext)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 支付验证通过
orderContext.setOrderStatus(OrderStatus.PAYMENT_VERIFIED);
return true;
}
/**
* 验证支付方式
*/
private boolean validatePaymentMethod(PaymentInfo paymentInfo) {
String paymentMethod = paymentInfo.getPaymentMethod();
if (StringUtils.isBlank(paymentMethod)) {
log.warn("Payment method is required");
return false;
}
// 检查支付方式是否支持
if (!paymentService.isPaymentMethodSupported(paymentMethod)) {
log.warn("Unsupported payment method: {}", paymentMethod);
return false;
}
return true;
}
/**
* 验证支付状态
*/
private boolean verifyPaymentStatus(PaymentInfo paymentInfo) {
try {
PaymentStatus status = paymentService.getPaymentStatus(paymentInfo.getPaymentId());
if (status != PaymentStatus.SUCCESS) {
log.warn("Payment not successful: {}, status: {}",
paymentInfo.getPaymentId(), status);
return false;
}
return true;
} catch (Exception e) {
log.error("Failed to verify payment status: {}", paymentInfo.getPaymentId(), e);
return false;
}
}
/**
* 验证支付金额
*/
private boolean verifyPaymentAmount(OrderContext orderContext) {
BigDecimal orderAmount = orderContext.getOrderAmount();
BigDecimal paymentAmount = orderContext.getPaymentInfo().getAmount();
if (orderAmount.compareTo(paymentAmount) != 0) {
log.warn("Payment amount mismatch for order: {}, order: {}, payment: {}",
orderContext.getOrderId(), orderAmount, paymentAmount);
return false;
}
return true;
}
/**
* 创建支付记录
*/
private boolean createPaymentRecord(OrderContext orderContext) {
try {
PaymentRecord record = PaymentRecord.builder()
.orderId(orderContext.getOrderId())
.userId(orderContext.getUserId())
.paymentId(orderContext.getPaymentInfo().getPaymentId())
.amount(orderContext.getPaymentInfo().getAmount())
.paymentMethod(orderContext.getPaymentInfo().getPaymentMethod())
.status(PaymentRecordStatus.VERIFIED)
.createTime(System.currentTimeMillis())
.build();
String recordId = paymentService.createPaymentRecord(record);
// 添加回滚动作
orderContext.addRollbackAction(() -> {
paymentService.cancelPaymentRecord(recordId);
});
// 将支付记录ID存储到上下文
orderContext.getAttributes().put("paymentRecordId", recordId);
log.info("Created payment record: {} for order: {}", recordId, orderContext.getOrderId());
return true;
} catch (Exception e) {
log.error("Failed to create payment record for order: {}", orderContext.getOrderId(), e);
return false;
}
}
}
物流分配处理器
/**
* 物流分配处理器
*/
@Component
@Slf4j
public class LogisticsAssignmentHandler extends AbstractOrderHandler {
@Autowired
private LogisticsService logisticsService;
@Autowired
private WarehouseService warehouseService;
@Override
protected boolean processOrder(OrderContext orderContext) throws Exception {
// 1. 选择最优仓库
String warehouseId = selectOptimalWarehouse(orderContext);
if (warehouseId == null) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 2. 计算运费
BigDecimal shippingFee = calculateShippingFee(orderContext, warehouseId);
orderContext.getShippingInfo().setShippingFee(shippingFee);
orderContext.getShippingInfo().setWarehouseId(warehouseId);
// 3. 创建物流订单
if (!createLogisticsOrder(orderContext)) {
orderContext.setOrderStatus(OrderStatus.FAILED);
return false;
}
// 物流分配完成
orderContext.setOrderStatus(OrderStatus.LOGISTICS_ASSIGNED);
return true;
}
/**
* 选择最优仓库
*/
private String selectOptimalWarehouse(OrderContext orderContext) {
try {
String shippingAddress = orderContext.getShippingInfo().getShippingAddress();
List<OrderItem> orderItems = orderContext.getOrderItems();
// 获取可用仓库列表
List<Warehouse> availableWarehouses = warehouseService.getAvailableWarehouses(orderItems);
if (availableWarehouses.isEmpty()) {
log.warn("No available warehouse for order: {}", orderContext.getOrderId());
return null;
}
// 选择距离最近且有库存的仓库
Warehouse optimalWarehouse = availableWarehouses.stream()
.min(Comparator.comparing(warehouse ->
calculateDistance(warehouse.getAddress(), shippingAddress)))
.orElse(null);
if (optimalWarehouse == null) {
log.warn("Failed to select optimal warehouse for order: {}", orderContext.getOrderId());
return null;
}
log.info("Selected warehouse: {} for order: {}",
optimalWarehouse.getId(), orderContext.getOrderId());
return optimalWarehouse.getId();
} catch (Exception e) {
log.error("Failed to select warehouse for order: {}", orderContext.getOrderId(), e);
return null;
}
}
/**
* 计算运费
*/
private BigDecimal calculateShippingFee(OrderContext orderContext, String warehouseId) {
try {
ShippingCalculationRequest request = ShippingCalculationRequest.builder()
.warehouseId(warehouseId)
.shippingAddress(orderContext.getShippingInfo().getShippingAddress())
.shippingMethod(orderContext.getShippingInfo().getShippingMethod())
.orderItems(orderContext.getOrderItems())
.build();
return logisticsService.calculateShippingFee(request);
} catch (Exception e) {
log.error("Failed to calculate shipping fee for order: {}", orderContext.getOrderId(), e);
return BigDecimal.ZERO;
}
}
/**
* 创建物流订单
*/
private boolean createLogisticsOrder(OrderContext orderContext) {
try {
LogisticsOrder logisticsOrder = LogisticsOrder.builder()
.orderId(orderContext.getOrderId())
.warehouseId(orderContext.getShippingInfo().getWarehouseId())
.receiverName(orderContext.getShippingInfo().getReceiverName())
.receiverPhone(orderContext.getShippingInfo().getReceiverPhone())
.shippingAddress(orderContext.getShippingInfo().getShippingAddress())
.shippingMethod(orderContext.getShippingInfo().getShippingMethod())
.shippingFee(orderContext.getShippingInfo().getShippingFee())
.orderItems(orderContext.getOrderItems())
.status(LogisticsOrderStatus.CREATED)
.createTime(System.currentTimeMillis())
.build();
String logisticsOrderId = logisticsService.createLogisticsOrder(logisticsOrder);
// 添加回滚动作
orderContext.addRollbackAction(() -> {
logisticsService.cancelLogisticsOrder(logisticsOrderId);
});
// 将物流订单ID存储到上下文
orderContext.getAttributes().put("logisticsOrderId", logisticsOrderId);
log.info("Created logistics order: {} for order: {}",
logisticsOrderId, orderContext.getOrderId());
return true;
} catch (Exception e) {
log.error("Failed to create logistics order for order: {}", orderContext.getOrderId(), e);
return false;
}
}
/**
* 计算距离(简化实现)
*/
private double calculateDistance(String address1, String address2) {
// 实际实现中应该使用地理位置服务计算真实距离
return Math.random() * 100;
}
}
4. 订单处理链构建
/**
* 订单处理链构建器
*/
@Component
@Slf4j
public class OrderProcessingChainBuilder {
@Autowired
private OrderValidationHandler validationHandler;
@Autowired
private InventoryCheckHandler inventoryHandler;
@Autowired
private PaymentVerificationHandler paymentHandler;
@Autowired
private LogisticsAssignmentHandler logisticsHandler;
/**
* 构建标准订单处理链
*/
public Handler buildStandardOrderChain() {
return new AdvancedChainBuilder<OrderContext, OrderResult>()
.addHandler(validationHandler)
.addHandler(inventoryHandler)
.addHandler(paymentHandler)
.addHandler(logisticsHandler)
.build();
}
/**
* 构建快速订单处理链(跳过某些验证)
*/
public Handler buildFastOrderChain() {
return new AdvancedChainBuilder<OrderContext, OrderResult>()
.addHandler(validationHandler)
.addHandler(inventoryHandler)
.addHandler(paymentHandler)
// 跳过物流分配,后续异步处理
.build();
}
/**
* 构建预售订单处理链
*/
public Handler buildPresaleOrderChain() {
return new AdvancedChainBuilder<OrderContext, OrderResult>()
.addHandler(validationHandler)
// 预售订单跳过库存检查
.addHandler(paymentHandler)
.addHandler(logisticsHandler)
.build();
}
}
5. 订单处理服务
/**
* 订单处理服务
*/
@Service
@Slf4j
public class OrderProcessingService {
@Autowired
private OrderProcessingChainBuilder chainBuilder;
@Autowired
private ChainExecutor<OrderContext, OrderResult> chainExecutor;
@Autowired
private OrderRepository orderRepository;
@Autowired
private NotificationService notificationService;
/**
* 处理订单
*/
public OrderResult processOrder(OrderContext orderContext) {
String orderId = orderContext.getOrderId();
try {
log.info("Starting order processing: {}", orderId);
// 设置初始状态
orderContext.setOrderStatus(OrderStatus.CREATED);
// 选择处理链
Handler chain = selectProcessingChain(orderContext);
// 创建执行上下文
Context<OrderContext, OrderResult> context = new DefaultContext<>(orderContext);
// 执行处理链
OrderResult result = chainExecutor.execute("order-processing", context);
// 处理结果
if (result != null && result.isSuccess()) {
handleSuccessfulOrder(orderContext);
} else {
handleFailedOrder(orderContext, result);
}
return result;
} catch (Exception e) {
log.error("Order processing failed: {}", orderId, e);
return handleOrderException(orderContext, e);
}
}
/**
* 异步处理订单
*/
@Async
public CompletableFuture<OrderResult> processOrderAsync(OrderContext orderContext) {
return CompletableFuture.supplyAsync(() -> processOrder(orderContext));
}
/**
* 选择处理链
*/
private Handler selectProcessingChain(OrderContext orderContext) {
// 根据订单类型选择不同的处理链
String orderType = (String) orderContext.getAttributes().get("orderType");
switch (orderType) {
case "FAST":
return chainBuilder.buildFastOrderChain();
case "PRESALE":
return chainBuilder.buildPresaleOrderChain();
default:
return chainBuilder.buildStandardOrderChain();
}
}
/**
* 处理成功的订单
*/
private void handleSuccessfulOrder(OrderContext orderContext) {
try {
// 更新订单状态
orderContext.setOrderStatus(OrderStatus.CONFIRMED);
// 保存订单
saveOrder(orderContext);
// 发送通知
sendOrderConfirmationNotification(orderContext);
log.info("Order processed successfully: {}", orderContext.getOrderId());
} catch (Exception e) {
log.error("Failed to handle successful order: {}", orderContext.getOrderId(), e);
}
}
/**
* 处理失败的订单
*/
private void handleFailedOrder(OrderContext orderContext, OrderResult result) {
try {
// 更新订单状态
orderContext.setOrderStatus(OrderStatus.FAILED);
// 保存订单
saveOrder(orderContext);
// 发送失败通知
sendOrderFailureNotification(orderContext, result);
log.warn("Order processing failed: {}, reason: {}",
orderContext.getOrderId(),
result != null ? result.getMessage() : "Unknown error");
} catch (Exception e) {
log.error("Failed to handle failed order: {}", orderContext.getOrderId(), e);
}
}
/**
* 处理订单异常
*/
private OrderResult handleOrderException(OrderContext orderContext, Exception e) {
try {
// 执行回滚
orderContext.executeRollback();
// 更新订单状态
orderContext.setOrderStatus(OrderStatus.FAILED);
// 保存订单
saveOrder(orderContext);
// 发送异常通知
sendOrderExceptionNotification(orderContext, e);
return OrderResult.builder()
.success(false)
.message("Order processing exception: " + e.getMessage())
.timestamp(System.currentTimeMillis())
.build();
} catch (Exception ex) {
log.error("Failed to handle order exception: {}", orderContext.getOrderId(), ex);
return OrderResult.builder()
.success(false)
.message("Critical error in order processing")
.timestamp(System.currentTimeMillis())
.build();
}
}
/**
* 保存订单
*/
private void saveOrder(OrderContext orderContext) {
try {
Order order = convertToOrder(orderContext);
orderRepository.save(order);
} catch (Exception e) {
log.error("Failed to save order: {}", orderContext.getOrderId(), e);
}
}
/**
* 发送订单确认通知
*/
private void sendOrderConfirmationNotification(OrderContext orderContext) {
try {
NotificationRequest notification = NotificationRequest.builder()
.userId(orderContext.getUserId())
.type(NotificationType.ORDER_CONFIRMED)
.title("订单确认")
.content("您的订单 " + orderContext.getOrderId() + " 已确认,正在准备发货")
.build();
notificationService.sendNotification(notification);
} catch (Exception e) {
log.error("Failed to send order confirmation notification: {}",
orderContext.getOrderId(), e);
}
}
/**
* 发送订单失败通知
*/
private void sendOrderFailureNotification(OrderContext orderContext, OrderResult result) {
try {
NotificationRequest notification = NotificationRequest.builder()
.userId(orderContext.getUserId())
.type(NotificationType.ORDER_FAILED)
.title("订单处理失败")
.content("您的订单 " + orderContext.getOrderId() + " 处理失败:" +
(result != null ? result.getMessage() : "未知错误"))
.build();
notificationService.sendNotification(notification);
} catch (Exception e) {
log.error("Failed to send order failure notification: {}",
orderContext.getOrderId(), e);
}
}
/**
* 发送订单异常通知
*/
private void sendOrderExceptionNotification(OrderContext orderContext, Exception e) {
try {
NotificationRequest notification = NotificationRequest.builder()
.userId(orderContext.getUserId())
.type(NotificationType.ORDER_EXCEPTION)
.title("订单处理异常")
.content("您的订单 " + orderContext.getOrderId() + " 处理时发生异常,我们正在处理中")
.build();
notificationService.sendNotification(notification);
} catch (Exception ex) {
log.error("Failed to send order exception notification: {}",
orderContext.getOrderId(), ex);
}
}
/**
* 转换为订单实体
*/
private Order convertToOrder(OrderContext orderContext) {
return Order.builder()
.orderId(orderContext.getOrderId())
.userId(orderContext.getUserId())
.orderItems(orderContext.getOrderItems())
.paymentInfo(orderContext.getPaymentInfo())
.shippingInfo(orderContext.getShippingInfo())
.orderStatus(orderContext.getOrderStatus())
.createTime(orderContext.getTimestamp())
.updateTime(System.currentTimeMillis())
.build();
}
}
异常处理机制和流程回滚方案
1. 异常分类
/**
* 订单处理异常基类
*/
public abstract class OrderProcessingException extends Exception {
private final String orderId;
private final String handlerName;
public OrderProcessingException(String message, String orderId, String handlerName) {
super(message);
this.orderId = orderId;
this.handlerName = handlerName;
}
public OrderProcessingException(String message, Throwable cause, String orderId, String handlerName) {
super(message, cause);
this.orderId = orderId;
this.handlerName = handlerName;
}
// getters
}
/**
* 业务验证异常
*/
public class OrderValidationException extends OrderProcessingException {
public OrderValidationException(String message, String orderId, String handlerName) {
super(message, orderId, handlerName);
}
}
/**
* 库存不足异常
*/
public class InsufficientInventoryException extends OrderProcessingException {
private final List<String> insufficientProducts;
public InsufficientInventoryException(String message, String orderId,
List<String> insufficientProducts) {
super(message, orderId, "InventoryCheckHandler");
this.insufficientProducts = insufficientProducts;
}
public List<String> getInsufficientProducts() {
return insufficientProducts;
}
}
/**
* 支付验证异常
*/
public class PaymentVerificationException extends OrderProcessingException {
public PaymentVerificationException(String message, String orderId) {
super(message, orderId, "PaymentVerificationHandler");
}
}
/**
* 物流分配异常
*/
public class LogisticsAssignmentException extends OrderProcessingException {
public LogisticsAssignmentException(String message, String orderId) {
super(message, orderId, "LogisticsAssignmentHandler");
}
}
2. 回滚机制实现
/**
* 回滚管理器
*/
@Component
@Slf4j
public class RollbackManager {
/**
* 执行完整回滚
*/
public void executeFullRollback(OrderContext orderContext) {
log.info("Starting full rollback for order: {}", orderContext.getOrderId());
try {
// 执行上下文中的回滚动作
orderContext.executeRollback();
// 执行额外的清理工作
performAdditionalCleanup(orderContext);
log.info("Full rollback completed for order: {}", orderContext.getOrderId());
} catch (Exception e) {
log.error("Full rollback failed for order: {}", orderContext.getOrderId(), e);
// 记录回滚失败,需要人工介入
recordRollbackFailure(orderContext, e);
}
}
/**
* 执行部分回滚
*/
public void executePartialRollback(OrderContext orderContext, String fromHandler) {
log.info("Starting partial rollback from {} for order: {}",
fromHandler, orderContext.getOrderId());
try {
// 根据处理器名称执行特定的回滚逻辑
switch (fromHandler) {
case "PaymentVerificationHandler":
rollbackPayment(orderContext);
// fall through
case "InventoryCheckHandler":
rollbackInventory(orderContext);
break;
case "LogisticsAssignmentHandler":
rollbackLogistics(orderContext);
rollbackPayment(orderContext);
rollbackInventory(orderContext);
break;
}
log.info("Partial rollback completed for order: {}", orderContext.getOrderId());
} catch (Exception e) {
log.error("Partial rollback failed for order: {}", orderContext.getOrderId(), e);
recordRollbackFailure(orderContext, e);
}
}
/**
* 回滚库存
*/
private void rollbackInventory(OrderContext orderContext) {
@SuppressWarnings("unchecked")
List<InventoryReservation> reservations =
(List<InventoryReservation>) orderContext.getAttributes().get("inventoryReservations");
if (reservations != null) {
for (InventoryReservation reservation : reservations) {
try {
// 释放库存预占
inventoryService.releaseReservation(reservation.getReservationId());
log.info("Released inventory reservation: {}", reservation.getReservationId());
} catch (Exception e) {
log.error("Failed to release inventory reservation: {}",
reservation.getReservationId(), e);
}
}
}
}
/**
* 回滚支付
*/
private void rollbackPayment(OrderContext orderContext) {
String paymentRecordId = (String) orderContext.getAttributes().get("paymentRecordId");
if (paymentRecordId != null) {
try {
// 取消支付记录
paymentService.cancelPaymentRecord(paymentRecordId);
log.info("Cancelled payment record: {}", paymentRecordId);
} catch (Exception e) {
log.error("Failed to cancel payment record: {}", paymentRecordId, e);
}
}
}
/**
* 回滚物流
*/
private void rollbackLogistics(OrderContext orderContext) {
String logisticsOrderId = (String) orderContext.getAttributes().get("logisticsOrderId");
if (logisticsOrderId != null) {
try {
// 取消物流订单
logisticsService.cancelLogisticsOrder(logisticsOrderId);
log.info("Cancelled logistics order: {}", logisticsOrderId);
} catch (Exception e) {
log.error("Failed to cancel logistics order: {}", logisticsOrderId, e);
}
}
}
/**
* 执行额外的清理工作
*/
private void performAdditionalCleanup(OrderContext orderContext) {
// 清理临时数据
// 发送回滚通知
// 记录回滚日志
}
/**
* 记录回滚失败
*/
private void recordRollbackFailure(OrderContext orderContext, Exception e) {
// 记录到数据库,供人工处理
// 发送告警通知
}
}
3. 重试机制
/**
* 重试配置
*/
@Configuration
public class RetryConfiguration {
@Bean
public RetryTemplate orderProcessingRetryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
// 重试策略
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(1000); // 1秒间隔
retryTemplate.setBackOffPolicy(backOffPolicy);
// 重试条件
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy();
retryPolicy.setMaxAttempts(3);
Map<Class<? extends Throwable>, Boolean> retryableExceptions = new HashMap<>();
retryableExceptions.put(InventoryServiceException.class, true);
retryableExceptions.put(PaymentServiceException.class, true);
retryableExceptions.put(LogisticsServiceException.class, true);
retryPolicy.setRetryableExceptions(retryableExceptions);
retryTemplate.setRetryPolicy(retryPolicy);
return retryTemplate;
}
}
/**
* 带重试的订单处理服务
*/
@Service
public class RetryableOrderProcessingService {
@Autowired
private OrderProcessingService orderProcessingService;
@Autowired
private RetryTemplate orderProcessingRetryTemplate;
/**
* 带重试的订单处理
*/
public OrderResult processOrderWithRetry(OrderContext orderContext) {
return orderProcessingRetryTemplate.execute(context -> {
log.info("Processing order with retry, attempt: {}, order: {}",
context.getRetryCount() + 1, orderContext.getOrderId());
return orderProcessingService.processOrder(orderContext);
}, context -> {
log.error("Order processing failed after {} attempts, order: {}",
context.getRetryCount(), orderContext.getOrderId());
return OrderResult.builder()
.success(false)
.message("Order processing failed after retries")
.timestamp(System.currentTimeMillis())
.build();
});
}
}
性能优化建议
1. 异步处理优化
/**
* 异步订单处理配置
*/
@Configuration
@EnableAsync
public class AsyncOrderProcessingConfiguration {
@Bean("orderProcessingExecutor")
public TaskExecutor orderProcessingExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(200);
executor.setThreadNamePrefix("order-processing-");
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}
/**
* 异步订单处理服务
*/
@Service
public class AsyncOrderProcessingService {
@Async("orderProcessingExecutor")
public CompletableFuture<OrderResult> processOrderAsync(OrderContext orderContext) {
try {
OrderResult result = orderProcessingService.processOrder(orderContext);
return CompletableFuture.completedFuture(result);
} catch (Exception e) {
CompletableFuture<OrderResult> future = new CompletableFuture<>();
future.completeExceptionally(e);
return future;
}
}
/**
* 批量异步处理订单
*/
public CompletableFuture<List<OrderResult>> processOrdersBatch(List<OrderContext> orderContexts) {
List<CompletableFuture<OrderResult>> futures = orderContexts.stream()
.map(this::processOrderAsync)
.collect(Collectors.toList());
return CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]))
.thenApply(v -> futures.stream()
.map(CompletableFuture::join)
.collect(Collectors.toList()));
}
}
2. 缓存优化
/**
* 缓存配置
*/
@Configuration
@EnableCaching
public class CacheConfiguration {
@Bean
public CacheManager cacheManager() {
RedisCacheManager.Builder builder = RedisCacheManager
.RedisCacheManagerBuilder
.fromConnectionFactory(redisConnectionFactory())
.cacheDefaults(cacheConfiguration());
return builder.build();
}
private RedisCacheConfiguration cacheConfiguration() {
return RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10))
.serializeKeysWith(RedisSerializationContext.SerializationPair
.fromSerializer(new StringRedisSerializer()))
.serializeValuesWith(RedisSerializationContext.SerializationPair
.fromSerializer(new GenericJackson2JsonRedisSerializer()));
}
}
/**
* 缓存服务
*/
@Service
public class OrderCacheService {
@Cacheable(value = "products", key = "#productId")
public Product getProductById(String productId) {
return productService.getProductById(productId);
}
@Cacheable(value = "inventory", key = "#productId + '_' + #skuId")
public Integer getAvailableStock(String productId, String skuId) {
return inventoryService.getAvailableStock(productId, skuId);
}
@Cacheable(value = "users", key = "#userId")
public User getUserById(String userId) {
return userService.getUserById(userId);
}
}
3. 数据库优化
/**
* 数据库配置优化
*/
@Configuration
public class DatabaseConfiguration {
@Bean
@Primary
public DataSource primaryDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/order_db");
config.setUsername("username");
config.setPassword("password");
config.setMaximumPoolSize(20);
config.setMinimumIdle(5);
config.setConnectionTimeout(30000);
config.setIdleTimeout(600000);
config.setMaxLifetime(1800000);
return new HikariDataSource(config);
}
@Bean
public DataSource readOnlyDataSource() {
// 配置只读数据源
HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3307/order_db_readonly");
config.setUsername("readonly_user");
config.setPassword("readonly_password");
config.setMaximumPoolSize(10);
config.setReadOnly(true);
return new HikariDataSource(config);
}
}
/**
* 读写分离服务
*/
@Service
public class OrderQueryService {
@Autowired
@Qualifier("readOnlyDataSource")
private DataSource readOnlyDataSource;
/**
* 从只读库查询订单
*/
public Order getOrderById(String orderId) {
// 使用只读数据源查询
return orderRepository.findById(orderId);
}
/**
* 分页查询订单
*/
public Page<Order> getOrdersByUserId(String userId, Pageable pageable) {
return orderRepository.findByUserId(userId, pageable);
}
}
4. 监控和指标
/**
* 订单处理监控
*/
@Component
public class OrderProcessingMetrics {
private final MeterRegistry meterRegistry;
private final Counter orderProcessedCounter;
private final Counter orderFailedCounter;
private final Timer orderProcessingTimer;
public OrderProcessingMetrics(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
this.orderProcessedCounter = Counter.builder("order.processed")
.description("Number of orders processed")
.register(meterRegistry);
this.orderFailedCounter = Counter.builder("order.failed")
.description("Number of orders failed")
.register(meterRegistry);
this.orderProcessingTimer = Timer.builder("order.processing.duration")
.description("Order processing duration")
.register(meterRegistry);
}
public void recordOrderProcessed(String orderType) {
orderProcessedCounter.increment(Tags.of("type", orderType));
}
public void recordOrderFailed(String orderType, String reason) {
orderFailedCounter.increment(Tags.of("type", orderType, "reason", reason));
}
public Timer.Sample startTimer() {
return Timer.start(meterRegistry);
}
public void recordProcessingTime(Timer.Sample sample, String orderType) {
sample.stop(Timer.builder("order.processing.duration")
.tag("type", orderType)
.register(meterRegistry));
}
}
常见问题解决方案
1. 高并发场景下的库存超卖问题
问题描述:在高并发场景下,多个订单同时检查库存时可能出现超卖现象。
解决方案:
/**
* 防超卖库存服务
*/
@Service
public class ConcurrentSafeInventoryService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
/**
* 使用Redis分布式锁防止超卖
*/
public boolean reserveInventoryWithLock(String productId, String skuId,
int quantity, String orderId) {
String lockKey = "inventory_lock:" + productId + ":" + skuId;
String lockValue = orderId + ":" + System.currentTimeMillis();
try {
// 获取分布式锁
Boolean lockAcquired = redisTemplate.opsForValue()
.setIfAbsent(lockKey, lockValue, Duration.ofSeconds(10));
if (!lockAcquired) {
log.warn("Failed to acquire lock for inventory: {}-{}", productId, skuId);
return false;
}
// 检查库存
int availableStock = getAvailableStock(productId, skuId);
if (availableStock < quantity) {
return false;
}
// 扣减库存
boolean success = deductInventory(productId, skuId, quantity);
return success;
} finally {
// 释放锁
releaseLock(lockKey, lockValue);
}
}
/**
* 使用Lua脚本原子性操作
*/
public boolean reserveInventoryWithLua(String productId, String skuId,
int quantity, String orderId) {
String script =
"local stock = redis.call('GET', KEYS[1])n" +
"if not stock thenn" +
" return 0n" +
"endn" +
"if tonumber(stock) >= tonumber(ARGV[1]) thenn" +
" redis.call('DECRBY', KEYS[1], ARGV[1])n" +
" return 1n" +
"elsen" +
" return 0n" +
"end";
String stockKey = "stock:" + productId + ":" + skuId;
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
redisScript.setScriptText(script);
redisScript.setResultType(Long.class);
Long result = redisTemplate.execute(redisScript,
Collections.singletonList(stockKey),
String.valueOf(quantity));
return result != null && result == 1L;
}
}
2. 支付回调处理的幂等性问题
问题描述:支付系统可能会重复发送回调通知,需要保证处理的幂等性。
解决方案:
/**
* 幂等性支付回调处理
*/
@Service
public class IdempotentPaymentCallbackService {
@Autowired
private RedisTemplate<String, String> redisTemplate;
/**
* 幂等性处理支付回调
*/
public boolean handlePaymentCallback(PaymentCallback callback) {
String idempotentKey = "payment_callback:" + callback.getPaymentId();
try {
// 检查是否已处理
Boolean processed = redisTemplate.opsForValue()
.setIfAbsent(idempotentKey, "processed", Duration.ofHours(24));
if (!processed) {
log.info("Payment callback already processed: {}", callback.getPaymentId());
return true;
}
// 处理支付回调
return processPaymentCallback(callback);
} catch (Exception e) {
// 处理失败时删除幂等性标记
redisTemplate.delete(idempotentKey);
throw e;
}
}
}
3. 订单状态不一致问题
问题描述:在分布式环境下,订单状态可能在不同服务间出现不一致。
解决方案:
/**
* 订单状态一致性保证
*/
@Service
public class OrderStateConsistencyService {
@Autowired
private ApplicationEventPublisher eventPublisher;
/**
* 发布订单状态变更事件
*/
public void publishOrderStateChange(String orderId, OrderStatus oldStatus,
OrderStatus newStatus) {
OrderStateChangeEvent event = OrderStateChangeEvent.builder()
.orderId(orderId)
.oldStatus(oldStatus)
.newStatus(newStatus)
.timestamp(System.currentTimeMillis())
.build();
eventPublisher.publishEvent(event);
}
/**
* 监听订单状态变更事件
*/
@EventListener
@Async
public void handleOrderStateChange(OrderStateChangeEvent event) {
// 同步状态到其他服务
syncOrderStateToOtherServices(event);
// 发送状态变更通知
sendStateChangeNotification(event);
}
}
4. 长时间运行的订单处理超时问题
问题描述:某些订单处理步骤可能耗时较长,导致整个处理链超时。
解决方案:
/**
* 超时处理机制
*/
@Component
public class TimeoutOrderHandler extends AbstractOrderHandler {
private static final long DEFAULT_TIMEOUT = 30000; // 30秒
@Override
protected boolean processOrder(OrderContext orderContext) throws Exception {
CompletableFuture<Boolean> future = CompletableFuture.supplyAsync(() -> {
try {
return doActualProcessing(orderContext);
} catch (Exception e) {
throw new RuntimeException(e);
}
});
try {
return future.get(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS);
} catch (TimeoutException e) {
future.cancel(true);
log.error("Order processing timeout: {}", orderContext.getOrderId());
return false;
}
}
protected boolean doActualProcessing(OrderContext orderContext) throws Exception {
// 实际的处理逻辑
return true;
}
}
总结
通过责任链模式实现的电商订单处理系统具有以下优势:
- 模块化设计:每个处理步骤独立实现,便于维护和测试
- 灵活扩展:可以轻松添加新的处理步骤或修改处理顺序
- 异常处理:完善的回滚机制保证数据一致性
- 性能优化:支持异步处理、缓存优化等性能提升手段
- 监控完善:提供详细的处理日志和性能指标
在实际应用中,还需要根据具体的业务需求和技术环境进行相应的调整和优化。