- 引言:电商开发中的“三座大山”
在电商系统开发中,商品选品、实时比价、库存查询是三个高频且核心的业务场景。传统模式下,前端或客户端需要分别调用三个独立的API接口,这不仅增加了网络请求次数,也带来了复杂的异步状态管理和数据拼接逻辑。尤其是在移动端弱网环境下,多次请求的延迟和失败率会显著影响用户体验。
“组合API”的设计理念应运而生,旨在通过一次请求,将多个关联的查询逻辑在服务端聚合,并返回结构化的组合数据。本文将围绕“选品-比价-库存”这一典型业务链路,探讨如何设计、实现并优化一个高效可靠的组合API。
- 核心价值与业务场景
组合API的核心价值在于“降本增效”:
降低客户端复杂度:一次调用替代多次串行/并行调用,简化前端代码。
提升响应速度:服务端内网通信更快,并可并行处理子查询,大幅减少总耗时。
保证数据一致性:所有子查询基于同一时间点的快照,避免因多次请求时间差导致的数据状态矛盾(如比价时显示有货,下单时却无货)。
减少网络开销:合并请求与响应,节省Header等冗余数据传输。
典型业务场景:
商品详情页:展示商品信息(选品)、推荐相似商品及价格(比价)、实时库存状态。
购物车/结算页:批量校验多个商品的库存和最新价格。
营销活动页:根据用户画像推荐商品(选品),并突出显示价格优势(比价)。
- 系统架构设计
一个典型的组合API后端架构可分为三层:
3.1 API网关层
统一入口:接收客户端请求,进行认证、限流、日志记录。
请求解析:解析客户端传入的商品ID列表、用户位置、渠道等参数。
响应组装:将下游各个服务的结果按约定格式组装成最终响应。
3.2 业务聚合层(BFF - Backend for Frontend)
这是组合API的核心,负责协调和调用下游微服务。其关键设计模式包括:
并行调用:使用CompletableFuture(Java)、asyncio(Python)或Promise.all(Node.js)并发调用选品、比价、库存服务。
超时与熔断:为每个下游服务设置独立的超时时间,并集成熔断器(如Hystrix, Resilience4j),防止单个服务故障拖垮整个组合API。
降级策略:当某个子服务(如比价服务)不可用时,返回默认值或部分数据,保证核心流程(选品、库存)可用。
3.3 下游微服务层
选品服务:基于商品ID、用户标签、实时热度等返回商品详细信息。
比价服务:查询该商品在不同渠道(自营、第三方店铺)的实时价格。
库存服务:查询商品在各级仓库(总仓、区域仓、门店)的实时可用库存。
- 关键技术实现(以Java Spring Boot为例)
4.1 定义统一数据模型与API协议
// 请求体
@Data
public class CompositeQueryRequest {
private List productIds; // 商品ID列表
private String userId; // 用户ID,用于个性化选品
private String location; // 用户位置,用于库存和比价
}
// 响应体
@Data
public class CompositeQueryResponse {
private List products;
private String traceId; // 用于链路追踪
}
@Data
public class ProductCompositeDTO {
private String productId;
private ProductInfoDTO selection; // 选品信息
private PriceComparisonDTO priceComparison; // 比价信息
private InventoryDTO inventory; // 库存信息
}
4.2 实现并行调用与结果聚合
@Service
public class CompositeQueryService {
@Autowired
private SelectionService selectionService;
@Autowired
private PriceService priceService;
@Autowired
private InventoryService inventoryService;
public CompositeQueryResponse queryProducts(CompositeQueryRequest request) {
List<String> productIds = request.getProductIds();
String userId = request.getUserId();
String location = request.getLocation();
// 1. 并行调用下游服务
CompletableFuture<Map<String, ProductInfoDTO>> selectionFuture =
CompletableFuture.supplyAsync(() -> selectionService.batchQuery(productIds, userId));
CompletableFuture<Map<String, PriceComparisonDTO>> priceFuture =
CompletableFuture.supplyAsync(() -> priceService.batchCompare(productIds, location));
CompletableFuture<Map<String, InventoryDTO>> inventoryFuture =
CompletableFuture.supplyAsync(() -> inventoryService.batchQuery(productIds, location));
// 2. 等待所有结果完成(带超时)
CompletableFuture.allOf(selectionFuture, priceFuture, inventoryFuture)
.orTimeout(3000, TimeUnit.MILLISECONDS) // 总超时3秒
.join();
// 3. 组装最终响应
List<ProductCompositeDTO> result = new ArrayList<>();
for (String productId : productIds) {
ProductCompositeDTO dto = new ProductCompositeDTO();
dto.setProductId(productId);
dto.setSelection(selectionFuture.join().get(productId));
dto.setPriceComparison(priceFuture.join().get(productId));
dto.setInventory(inventoryFuture.join().get(productId));
result.add(dto);
}
CompositeQueryResponse response = new CompositeQueryResponse();
response.setProducts(result);
response.setTraceId(MDC.get("traceId"));
return response;
}
}
4.3 集成熔断与降级
// 使用 Resilience4j 为比价服务添加熔断器
@CircuitBreaker(name = "priceService", fallbackMethod = "priceFallback")
public Map batchCompareWithCircuitBreaker(List productIds, String location) {
return priceService.batchCompare(productIds, location);
}
// 降级方法:返回空比价信息
private Map priceFallback(List productIds, String location, Throwable t) {
log.warn("Price service fallback triggered for products: {}", productIds, t);
return productIds.stream()
.collect(Collectors.toMap(id -> id, id -> new PriceComparisonDTO()));
}
- 性能优化与最佳实践
5.1 缓存策略
多级缓存:在API网关或BFF层使用Redis缓存完整的组合结果(Key可为product:composite:{productId}:{location}),缓存时间根据业务敏感性设置(如库存30秒,价格5分钟)。
缓存穿透/击穿/雪崩防护:使用布隆过滤器、互斥锁、随机过期时间等常见方案。
5.2 异步与流式响应
对于超长商品列表,可采用分页或流式响应(如Server-Sent Events, WebSocket),先返回已就绪的数据,避免用户长时间等待。
5.3 监控与告警
关键指标:监控组合API的P99延迟、成功率,以及各下游服务的调用延迟和错误率。
链路追踪:集成SkyWalking、Jaeger,在一次请求中贯穿所有服务调用,便于故障定位。
- 总结
组合API通过将“选品、比价、库存查询”这三个强关联的业务查询一键打通,显著提升了电商系统的整体性能和开发效率。其核心在于服务端聚合与并行处理,并需辅以完善的熔断、降级、缓存和监控策略,才能在生产环境中提供稳定可靠的服务。
随着业务发展,组合API可以进一步扩展,集成优惠券计算、运费估算、用户评价摘要等更多功能,真正实现“一次请求,万物皆达”的体验。如有任何疑问,欢迎大家留言探讨!