SmartOrder — 第4部分:深入库存服务
Source: Dev.to
请提供您希望翻译的完整文本内容(除代码块和 URL 之外),我将按照要求将其翻译成简体中文并保留原有的格式。
所有权与边界
Inventory Service 拥有每个商品的库存状态——available、reserved、out of stock、discontinued。它 不 管理订单生命周期或定价。边界是严格的:
- No cross‑service joins
- No shared schemas
- No synchronous calls
它消费 OrderCreated 事件并作出响应,使 解耦的、最终一致的微服务 —— SmartOrder 架构的基石。
领域模型与 commons 集成
@Entity
@Table
@Data
@Builder(toBuilder = true)
@NoArgsConstructor
@AllArgsConstructor
@Jacksonized
@EntityListeners(AuditingEntityListener.class)
public class Inventory implements it.portus84.business.commons.model.Entity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
private UUID id;
private String description;
@NotNull
@Builder.Default
@Enumerated(EnumType.STRING)
private InventoryStatus status = InventoryStatus.PENDING;
@CreatedDate
@Setter(AccessLevel.NONE)
@Column(nullable = false, updatable = false)
private LocalDateTime createdDate;
@LastModifiedDate
@Setter(AccessLevel.NONE)
@Column(nullable = false)
private LocalDateTime lastModifiedDate;
}
InventoryStatus驱动 saga。@CreatedDate/@LastModifiedDate利用 commons‑business auditing。
该仓库(Repository)故意保持简洁:
public interface InventoryRepository extends JpaRepository {}
多语言持久化
- Inventory Service 使用 Spring Data JPA 与 H2/Postgres。
- Order Service 使用 MongoDB。
为什么要混合使用?
| 需求 | 选择 |
|---|---|
| 原子库存级别更新 | JPA 事务语义 |
| 预订(reserve → commit) | 事务保证 |
| 审计与时间戳 | JPA 审计(commons 集成) |
Commons 模块提供 基础实体、映射器接口和助手,确保各服务之间模式一致。
事件驱动的消费
@Bean
public Consumer orderCreatedConsumer() {
return event -> orderConfirmationPublisher.send(event);
}
spring:
cloud:
function:
definition: orderCreatedConsumer
stream:
function:
bindings:
orderCreatedConsumer-in-0: consumeOrderCreated
bindings:
consumeOrderCreated:
destination: pending-orders
group: inventory-group
inventory-group保证 在所有实例中对每个事件仅处理一次。- 该消费者是 无状态 且 纯粹事件驱动 的。
公共库提供 共享 DTO 和绑定常量:
@UtilityClass
public class BindingNames {
public static final String PUBLISH_ORDER_CONFIRMED = "publishOrderConfirmed";
public static final String PUBLISH_ORDER_OUT_OF_STOCK = "publishOrderOutOfStock";
}
可用性检查与条件事件发布
@Slf4j
@Component
@RequiredArgsConstructor
public class OrderConfirmationPublisher {
private final StreamBridge streamBridge;
private final InventoryService inventoryService;
public void send(OrderCreatedEvent event) {
boolean available = inventoryService.checkAvailability(event.getOrderId());
if (available) {
streamBridge.send(BindingNames.PUBLISH_ORDER_CONFIRMED,
new OrderConfirmedEvent(event.getOrderId()));
} else {
streamBridge.send(BindingNames.PUBLISH_ORDER_OUT_OF_STOCK,
new OrderOutOfStockEvent(event.getOrderId(),
"Insufficient stock"));
}
}
}
- 决策逻辑是 命令式的,但通过事件实现完全解耦。
- 来自 commons 的共享 events‑model 确保序列化的一致性。
StreamBridge使得输出绑定的动态选择成为可能。
HATEOAS in REST responses
@Override
public ResponseEntity> getInventoryById(UUID id) {
return inventoryService.findById(id)
.map(inventoryMapper::toDTO)
.map(hateoasHelper::toEntityModel)
.map(ResponseEntity::ok)
.orElseThrow(() -> new InventoryNotFoundException(id));
}
- 通过
hateoasHelper生成的 HATEOAS 链接动态引导客户端。 - 支持 PATCH / UPDATE 操作,无需硬编码 URI。
Commons 提供 共享的 mapper 接口、分页 mapper 和 HATEOAS 辅助工具。
事件驱动工作流:已解决的挑战
- 订单服务 publishes
OrderCreated。 - 库存服务 consumes it。
OrderConfirmationPublisherdecides based on stock。- Either
OrderConfirmedEventorOrderOutOfStockEventis published。 - 订单服务 updates its state accordingly。
已解决的挑战
| 挑战 | 解决方案 |
|---|---|
| 事件驱动的库存预留 | 无分布式事务;通过事件实现最终一致性 |
| 原子可用性检查 | 库存服务中的 JPA 事务语义 |
| 样板代码减少 | 共享公共基础设施(实体、映射器、DTO、辅助类) |
待办:checkAvailability
@Override
public boolean checkAvailability(String orderId) {
// TODO: validate each
}
实现需要获取订单行,累计所需数量,与当前库存进行比较,并可能在单个事务中预留这些商品。
产品项目与实际库存
return true;
占位符始终返回
true
开发者的下一步
将 OrderCreatedEvent 中的产品行项目集成,并对每个库存记录的数量进行验证。
注意: 此 TODO 不属于本文范围,但对于完整的库存正确性至关重要。
引导和测试数据(开发者提示)
@AutoConfiguration
@ConditionalOnClass(Instancio.class)
public class TestDataLoaderConfiguration {
@Bean
CommandLineRunner loadTestData(InventoryService service) {
return args -> service.saveAll(
Instancio.ofList(Inventory.class)
.size(5)
.ignoreFields()
.create()
);
}
}
- Instancio 为本地开发生成种子数据。
- 确保 一致的设置,且不影响生产环境。
接下来:commons 模块
重点关注 services/commons:
在 order-service 和 inventory-service 中共享的 业务逻辑、DTO、事件定义和辅助工具。
包含内容
- 实体基类
- MapStruct 映射器
- HATEOAS 辅助工具
- 测试数据加载器
Commons 是在不复制样板代码的情况下扩展 SmartOrder 的关键。
Repository: →