您好,登錄后才能下訂單哦!
這篇文章主要介紹“微服務架構eShopOnContainers怎么使用”,在日常操作中,相信很多人在微服務架構eShopOnContainers怎么使用問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”微服務架構eShopOnContainers怎么使用”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!
我們知道使用EventBus是為了解除Publisher和Subscriber之間的依賴性,這樣我們的Publisher就不需要知道有多少Subscribers,只需要通過EventBus進行注冊管理就好了,在eShop項目中,有一個這樣的接口IEventBus(eShopOnContainers\src\BuildingBlocks\EventBus\EventBus\Abstractions)
public interface IEventBus
{
void Subscribe<T, TH>(Func<TH> handler) where T : IntegrationEvent where TH : IIntegrationEventHandler<T>;
void Unsubscribe<T, TH>() where TH : IIntegrationEventHandler<T> where T : IntegrationEvent;
void Publish(IntegrationEvent @event);
}
我們可以看到這個接口定義了EventBus所需的一些操作, 對比大神的EventBus,相關功能都是一致的,我們看下它的實現類:EventBusRabbitMQ,從名字上可以看出,這是一個通過RabbitMQ來進行管理的EventBus,我們可以看到它使用了IEventBusSubscriptionsManager進行訂閱存儲,也就是大神文中的:
private readonly ConcurrentDictionary<Type, List<Type>> _eventAndHandlerMapping;
微軟在Demo中把其提取出了接口,把一些常用方法給提煉了出來,但是核心還是Dictionary<string, List<Delegate>>, 使用Dictionary進行Map映射。通過Subscribe和UnSubscribe進行訂閱和取消,使用Publish方法進行發布操作。
public void Subscribe<T, TH>(Func<TH> handler) where T : IntegrationEvent where TH : IIntegrationEventHandler<T>{
var eventName = typeof(T).Name;
var containsKey = _subsManager.HasSubscriptionsForEvent<T>();
if (!containsKey)
{
if (!_persistentConnection.IsConnected)
{
_persistentConnection.TryConnect();
}
using (var channel = _persistentConnection.CreateModel())
{
channel.QueueBind(queue: _queueName,
exchange: BROKER_NAME,
routingKey: eventName);
}
}
_subsManager.AddSubscription<T, TH>(handler);
}
我們看到在訂閱的時候,EventBus會檢查下在Map中是否有相應的注冊,如果沒有的話首先回去RabbitMQ中創建一個新的channel進行綁定,隨后在Map中進行注冊映射。
UnSubscribe則直接從Map中取消映射,通過OnEventRemoved事件判斷Map下此映射的subscriber是否為空,為空則從RabbitMQ中關閉channel。
在RabbitMQ的構造方法中,我們看到這樣一個創建:CreateConsumerChannel(),這里創建了一個EventingBasicConsumer,當Queue中有新的消息時會通過ProcessEvent執行Map中注冊的handler(subscribers)
在ProcessEvent方法中,回去Map中找尋subscribers,然后通過動態反射進行執行:
private async Task ProcessEvent(string eventName, string message)
{ if (_subsManager.HasSubscriptionsForEvent(eventName))
{
var eventType = _subsManager.GetEventTypeByName(eventName); var integrationEvent = JsonConvert.DeserializeObject(message, eventType); var handlers = _subsManager.GetHandlersForEvent(eventName);
foreach (var handlerfactory in handlers)
{
var handler = handlerfactory.DynamicInvoke();
var concreteType = typeof(IIntegrationEventHandler<>).MakeGenericType(eventType);
await (Task)concreteType.GetMethod("Handle").Invoke(handler, new object[] { integrationEvent });
}
}
}
微軟通過簡單的代碼解耦了Publisher和Subscribers之間的依賴關系,我們引用大神的總結:
在catalog.api中,微軟出現了EventBus,我在上一篇中也提到了,這是我的一個疑惑,因為在catalog中并沒有訂閱操作,直接執行了Publish操作,原先以為是一個空操作,后來看了Basket.Api我才知道為何微軟要用RabbitMQ。
使用RabbitMQ,我們不僅是從類之間的解耦,更可以跨項目,跨語言,跨平臺的解耦,publisher僅僅需要把消息體(IntegrationEvent)傳送到RabbitMQ,Consumer從Queue中獲取消息體,然后推送到Subscribers執行相應的操作。我們看下Basket.Api.Startup.cs:
protected virtual void ConfigureEventBus(IApplicationBuilder app)
{
var catalogPriceHandler = app.ApplicationServices .GetService<IIntegrationEventHandler<ProductPriceChangedIntegrationEvent>>(); var orderStartedHandler = app.ApplicationServices
.GetService<IIntegrationEventHandler<OrderStartedIntegrationEvent>>(); var eventBus = app.ApplicationServices.GetRequiredService<IEventBus>();
eventBus.Subscribe<ProductPriceChangedIntegrationEvent, ProductPriceChangedIntegrationEventHandler>
(() => app.ApplicationServices.GetRequiredService<ProductPriceChangedIntegrationEventHandler>());
eventBus.Subscribe<OrderStartedIntegrationEvent, OrderStartedIntegrationEventHandler>
(() => app.ApplicationServices.GetRequiredService<OrderStartedIntegrationEventHandler>());
}
到此,關于“微服務架構eShopOnContainers怎么使用”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。