Directory
- Design Focus
- Flow chart
- Pseudo code
2.1. Publishevent
2.2. Subscribeevent
2.3. Publisher
2.4. Subscriber
- Micro-Service Strong consistency
3.1 Publisher
3.2 Subscriber
- Event Bus-cross-service final consistency
4.1 Publisher & Subscriber All open local transactions, ensuring strong consistency
4.2 Problem Scenario One: What happens when ③ fails to publish?
4.3 Problem Scenario Two: What if the ③ release succeeds but the ④ update event state fails?
4.4 Problem Scenario Three: Publisher side Ok,subscriber consumption error
0. Design Focus
- publisher localization publishevent Guarantee Event Publishing reliability
- subscriber localization subscribeevent guaranteed Event Subscription Reliability
- Subscribeevent guaranteed non-recurring consumption events through EventId & handlertype combination constraints
- Event Central Console handles Publisher & subscriber Event retry
1. Execution flowchart
2. Pseudo-code 2.1 publishevent
public abstract class Event { public Event() { Id = Guid.NewGuid(); CreationTime = DateTime.UtcNow; } public Guid Id { get; set; } public DateTime CreationTime { get; set; } } public class PublishEvent : Event { public PublishEvent(Event @event) { Id = @event.Id; CreationTime = @event.CreationTime; Type = @event.GetType().FullName; Data = JsonConvert.SerializeObject(@event); Status = PublishEventStatus.NotPublished; } public String Type { get; set; } public String Data { get; set; } public PublishEventStatus Status { get; set; } } public enum PublishEventStatus { NotPublished = 0, Published = 1, PublishedFailed = 2 }
2.2 Subscribeevent
public class SubscribeEvent { public SubscribeEvent(Event @event, IEventHandler handler) { EventId = @event.Id; EventCreationTime = @event.CreationTime; EventType = @event.GetType().FullName; EventData = JsonConvert.SerializeObject(@event); HandlerType = handler.GetType().FullName; HandlingStatus = HandlingStatus.HandleSucceeded; HandlingTime = DateTime.Now; } public Guid EventId { get; set; } public String EventType { get; set; } public String EventData { get; set; } public DateTime EventCreationTime { get; set; } public String HandlerType { get; set; } public DateTime HandlingTime { get; set; } public HandlingStatus HandlingStatus { get; set; } } public enum HandlingStatus { HandleSucceeded = 0, HandleFailed = 1 }
2.3 Publisher
try { BeginTransaction(); // ① //Biz Flow EventRepository.PubilshEvent(@event);// ② CommitTransaction(); } catch(Exception ex){ RollbackTransaction(); throw ex; } EventBus.Publish(@event); // ③ EventResitory.EventPublished(@event.ToString()); // ④
2.4 Subscriber
try { BeginTransaction(); //Biz Flow EventRepository.SubscribeEvent(@event , eventHandler); // ⑤ CommitTransaction(); } catch(Exception ex){ RollbackTransaction(); throw ex; }
3. Micro-Service Strong consistency 3.1 Publisher
- Enable local transactions to achieve strong consistency
- Execute local business code
- Save Event Pre-release status inside local transaction ②
- Publish event to Event bus ③
- Modify event publication status to published ④
3.2 Subscriber
- Enable local transactions to achieve strong consistency
- Execute local business code
- Save subscription events to the local warehouse
4 Event Bus-cross-service final consistency 4.1 Publisher & Subscriber all on-premises transactions, guaranteed strong Consistency 4.2 problem scenario One: What happens when ③ fails to publish?
- ③ publish failure, meaning throw exception, ④ does not execute, then event status remains pre-release state
- Subsequent events retry republishing the event and update the event status to published
4.3 Problem Scenario Two: What if the ③ release succeeds but the ④ update event state fails? 4.3.1 Scene Figure Subscriber subscription succeeded
- ③ Publish succeeded, but ④ update event status failed, event status is still pre-release status
- subscriber Successful execution of business code after subscribing to this event
- Subscriber Save subscription events to the local subscription event warehouse ⑤
Problem with this scenario: publisher will retry publishing the pre-release status event via an event , then subscriber will repeat the event
Scenario: The problem we can avoid repeated consumption by combining subscribeevent EventId & handlertype with UNIQUE constraints
4.3.2 Scene Shi Shi Subscriber subscription failed
- ③ Publish succeeded, but ④ update event status failed, event status is still pre-release status
- Subscriber failed to execute consumption
- subscriber rolling back local transactions
There is no problem with this scenario because publisher retries the pre-release status event again with an event retry .
4.4 Problem Scenario Three: Publisher side Ok,subscriber consumption error
- Publisher -side processing goes smoothly
- Subscriber consumption failed, rollback of local transaction, subscribeevent not stored to local warehouse at this time
Problems with this scenario:
Publisher is sent successfully, and the local publishevent event is published , meaning that it is not known from the publisher side Subscriber consumption failure needs re-consumption
Solution:
- Get publishevent for event retry by detecting publishevent & subscribeevent
- Republish publishevent to subscriber
5. Support the above programming model with NuGet installation components
Install-Package SmartEventBus.RabbitMQImplInstall-Package SmartEventBus.Repository
6. Orm:smartsql Advertise
Smartsql = Dapper + MyBatis + Cache (Memory | Redis) + ZooKeeper + r/w splitting + ...
How to properly implement the internal consistency of microservices through localization events, and the final consistency between event bus across MicroServices