基於微服務框架Micronaut和Eventuate Tram實現分散式事務的開源案例
Micronaut是一個類似Spring Boot的微服務框架,Eventuate Tram是提供事務性訊息的框架,提供事務發件箱模式,也就是將傳送的訊息首先儲存到帶有主鍵的關聯式資料庫,然後透過訊息系統傳送到接收者,保證近似正好一次的傳遞,該機制類似Apache Kafka事務性訊息,只不過使用該框架可以在RabbitMQ或Akka的訊息系統中實現事務性訊息。
該原始碼案例點選標題進入。該開源作者是《微服務模式》書籍的作者Chris Richardson。
這個應用案例展示了跨微服務實現Saga的機制,以及CQRS模式。
訂單服務是實現CQRS的命令模型,而Order History Service實現CQRS檢視,其訂閱了來自訂單服務發出的領域事件。
這個案例的特殊之處在於,它不是基於DDD聚合設計的領域事件,而是直接在微服務中發出領域事件,Order訂單淪為JPA的實體貧血物件了。以下是訂單服務的程式碼:
@Singleton public class OrderService { @Inject private DomainEventPublisher domainEventPublisher; @PersistenceContext private EntityManager entityManager; @Transactional public Order createOrder(OrderDetails orderDetails) { ResultWithEvents<Order> orderWithEvents = Order.createOrder(orderDetails); Order order = orderWithEvents.result; entityManager.persist(order); domainEventPublisher.publish(Order.class, order.getId(), orderWithEvents.events); return order; } public void approveOrder(Long orderId) { Order order = Optional.ofNullable(entityManager.find(Order.class, orderId)) .orElseThrow(() -> new IllegalArgumentException(String.format("order with id %s not found", orderId))); order.noteCreditReserved(); OrderDetails orderDetails = new OrderDetails(order.getOrderDetails().getCustomerId(), new Money(order.getOrderDetails().getOrderTotal().getAmount())); domainEventPublisher.publish(Order.class, orderId, singletonList(new OrderApprovedEvent(orderDetails))); } public void rejectOrder(Long orderId) { Order order = Optional .ofNullable(entityManager.find(Order.class, orderId)) .orElseThrow(() -> new IllegalArgumentException(String.format("order with id %s not found", orderId))); order.noteCreditReservationFailed(); OrderDetails orderDetails = new OrderDetails(order.getOrderDetails().getCustomerId(), new Money(order.getOrderDetails().getOrderTotal().getAmount())); domainEventPublisher.publish(Order.class, orderId, singletonList(new OrderRejectedEvent(orderDetails))); } } |
批准訂單和拒絕訂單這些應該屬於訂單聚合重要的業務動作被放入了微服務內,微服務成為業務決策者,而不是協調者,正如飯店服務員成為飯店的決策者了。
亮點是透過Saga組成的微服務分散式事務,每個服務內部透過JPA實現ACID,服務之間的訊息透過事務性訊息機制實現正好一次傳遞,透過Saga實現回滾回退補償,以下是其流程,關聯式資料庫在其中實現傳遞訊息的冪等性。
相關文章
- .net core 自帶分散式事務的微服務開源框架JMS分散式微服務框架
- 基於RocketMQ實現分散式事務MQ分散式
- 微服務分散式事務Saga框架微服務分散式框架
- [開源] Golang 實現的分散式 WebSocket 微服務Golang分散式Web微服務
- 快速瞭解阿里微服務熱門開源分散式事務框架——Seata阿里微服務分散式框架
- GRIT:eBay基於微服務的分散式事務協議微服務分散式協議
- 第三代微服務架構:基於 Go 的部落格微服務實戰案例,支援分散式事務微服務架構Go分散式
- Eventuate:基於操作CRDT的服務框架框架
- 微服務痛點-基於Dubbo + Seata的分散式事務(AT)模式微服務分散式模式
- MySQL 中基於 XA 實現的分散式事務MySql分散式
- 阿里分散式事務框架GTS開源啦!阿里分散式框架
- 微服務痛點-基於Dubbo + Seata的分散式事務(TCC模式)微服務分散式模式
- php基於dtm分散式事務管理器實現tcc模式分散式事務demoPHP分散式模式
- 微服務分散式事務解決方案-開源軟體seata微服務分散式
- DTM:Golang中微服務架構的分散式事務框架Golang微服務架構分散式框架
- 基於Seata探尋分散式事務的實現方案分散式
- Laravel基於reset機制實現分散式事務Laravel分散式
- 分散式事務(3)---RocketMQ實現分散式事務原理分散式MQ
- PHP 微服務之【分散式事務】PHP微服務分散式
- PHP 微服務之 [分散式事務]PHP微服務分散式
- 分散式事務(八)Spring Cloud微服務系統基於Rocketmq可靠訊息最終一致性實現分散式事務分散式SpringCloud微服務MQ
- 分散式事務(4)---RocketMQ實現分散式事務專案分散式MQ
- 實戰與原理:如何基於RocketMQ實現分散式事務?MQ分散式
- go-zero微服務實戰系列(十、分散式事務如何實現)Go微服務分散式
- 微服務架構 | 11.1 整合 Seata AT 模式實現分散式事務微服務架構模式分散式
- 微服務分散式事務元件 Seata(一)微服務分散式元件
- MassTransit | 基於StateMachine實現Saga編排式分散式事務Mac分散式
- 構建基於RocketMQ的分散式事務服務MQ分散式
- 分散式事務:基於可靠訊息服務分散式
- Spring Cloud Seata系列:基於AT模式實現分散式事務SpringCloud模式分散式
- 比較微服務中的分散式事務模式微服務分散式模式
- 微服務的分散式事務模式比較 | RedHat微服務分散式模式Redhat
- 使用分散式Actor實現微服務分散式微服務
- 微服務分散式企業框架微服務分散式框架
- 微服務架構 | 11. 分散式事務微服務架構分散式
- 微服務分散式事務4種解決方案實戰微服務分散式
- 微服務架構中分散式事務實現方案怎樣何取捨微服務架構分散式
- 分散式事務(一)—分散式事務的概念分散式