Я напишу серию статей о микросервисах, так что настраивайтесь!
Что такое шина событий?
Представьте себе, у вас есть один микросервис для пользователей, а другой - для транзакций. Каждый раз, когда пользователь создает одну транзакцию, транзакции микросервиса должны знать, что это за транзакция и какой пользователь. Таким образом, микросервис шлюза отправит событие, а транзакция микросервиса будет прослушивать событие. И позаботьтесь о совершенной новой транзакции.
Шина событий будет отвечать за публикацию события и доставку события в нужный микросервис (простой способ понять).
С помощью шины событий вы можете сделать вашу коммуникацию асинхронной, а также потерять связь между микросервисами. Потому что, если вы используете HTTP для связи между микросервисами, вы заставите пользователя ждать каждого микросервиса. Будет похоже на водопад: для запуска микросервиса необходимо завершить предыдущий микросервис и так далее. Не очень эффективно.
Брокер сообщений
Но для этого нам понадобится брокер сообщений. Я буду использовать RabbitMQ, правильный способ будет выглядеть так: служба A публикует событие, используя шину событий, шина событий опубликует событие в некоторой очереди в RabbitMQ, затем шина событий будет прослушивать RabbitMQ и подписываться и доставит событие в правильный обработчик микросервиса (микросервис B).
Абстракции
public interface IEventBus { void Publish(Event _event); void Subscribe<T, TH>() where T : Event where TH : IEventHandler<T>; void Unsubscribe<T, TH>() where T : Event where TH : IEventHandler<T>; }
Моя шина событий - это DLL, поэтому каждый микросервис может иметь доступ. Метод Publish предназначен для публикации события, Subscribe - для подписки на разные обработчики.
В файле Startup.cs вам просто нужно подписаться на каждый обработчик и зарегистрировать обработчик.
eventBus.Subscribe<EventFromMicroserviceA, EventFromMicroserviceAHanlder>(); builder.Register(c => new EventFromMicroserviceAHanlder());
Событие
public class Event { public Event() { Id = Guid.NewGuid(); CreationDate = DateTime.UtcNow; } [JsonConstructor] public Event(Guid id, DateTime createDate) { Id = id; CreationDate = createDate; } [JsonProperty] public Guid Id { get; private set; } [JsonProperty] public DateTime CreationDate { get; private set; } }
Это событие для шины событий, автобус событий просто знает это. Не нужно знать о различных событиях, которые происходят в вашем приложении.
public class EventFromMicroserviceA : EventBus.Events.Event { public string Name { get; set; } public string Message { get; set; } }
«Настоящие» события похожи на это, они наследуют событие от шины событий.
Обработчик
public class EventFromMicroserviceAHandler : IEventHandler<EventFromMicroserviceA> { public async Task Handler(EventFromMicroserviceA _event) { string eventReceive = JsonConvert.SerializeObject(_event); using (System.IO.StreamWriter file = new System.IO.StreamWriter(@"..\MicroserviceB\EventMessage.txt", true)) { await file.WriteLineAsync(eventReceive + "\n"); } } }
Это всего лишь пустышка. Обработчик отвечает за получение только события с именем EventFromMicroserviceA. И в этом случае сохраним в файл. Каждый обработчик должен заботиться только об одном событии. В будущем, если вам нужно было изменить, вам нужно будет изменить только логику одного обработчика, а не нескольких обработчиков.
GitHub - › https://github.com/bteixeira691/EventBus