溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

微服務(wù)架構(gòu)eShopOnContainers怎么使用

發(fā)布時(shí)間:2021-12-20 09:21:51 來(lái)源:億速云 閱讀:307 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要介紹“微服務(wù)架構(gòu)eShopOnContainers怎么使用”,在日常操作中,相信很多人在微服務(wù)架構(gòu)eShopOnContainers怎么使用問(wèn)題上存在疑惑,小編查閱了各式資料,整理出簡(jiǎn)單好用的操作方法,希望對(duì)大家解答”微服務(wù)架構(gòu)eShopOnContainers怎么使用”的疑惑有所幫助!接下來(lái),請(qǐng)跟著小編一起來(lái)學(xué)習(xí)吧!

解析源碼

我們知道使用EventBus是為了解除Publisher和Subscriber之間的依賴性,這樣我們的Publisher就不需要知道有多少Subscribers,只需要通過(guò)EventBus進(jìn)行注冊(cè)管理就好了,在eShop項(xiàng)目中,有一個(gè)這樣的接口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); }

我們可以看到這個(gè)接口定義了EventBus所需的一些操作, 對(duì)比大神的EventBus,相關(guān)功能都是一致的,我們看下它的實(shí)現(xiàn)類:EventBusRabbitMQ,從名字上可以看出,這是一個(gè)通過(guò)RabbitMQ來(lái)進(jìn)行管理的EventBus,我們可以看到它使用了IEventBusSubscriptionsManager進(jìn)行訂閱存儲(chǔ),也就是大神文中的:

private readonly ConcurrentDictionary<Type, List<Type>> _eventAndHandlerMapping;

微軟在Demo中把其提取出了接口,把一些常用方法給提煉了出來(lái),但是核心還是Dictionary<string, List<Delegate>>, 使用Dictionary進(jìn)行Map映射。通過(guò)Subscribe和UnSubscribe進(jìn)行訂閱和取消,使用Publish方法進(jìn)行發(fā)布操作。

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); }

我們看到在訂閱的時(shí)候,EventBus會(huì)檢查下在Map中是否有相應(yīng)的注冊(cè),如果沒(méi)有的話首先回去RabbitMQ中創(chuàng)建一個(gè)新的channel進(jìn)行綁定,隨后在Map中進(jìn)行注冊(cè)映射。

UnSubscribe則直接從Map中取消映射,通過(guò)OnEventRemoved事件判斷Map下此映射的subscriber是否為空,為空則從RabbitMQ中關(guān)閉channel。

在RabbitMQ的構(gòu)造方法中,我們看到這樣一個(gè)創(chuàng)建:CreateConsumerChannel(),這里創(chuàng)建了一個(gè)EventingBasicConsumer,當(dāng)Queue中有新的消息時(shí)會(huì)通過(guò)ProcessEvent執(zhí)行Map中注冊(cè)的handler(subscribers)

在ProcessEvent方法中,回去Map中找尋subscribers,然后通過(guò)動(dòng)態(tài)反射進(jìn)行執(zhí)行:

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 });        }    } }

微軟通過(guò)簡(jiǎn)單的代碼解耦了Publisher和Subscribers之間的依賴關(guān)系,我們引用大神的總結(jié):

微服務(wù)架構(gòu)eShopOnContainers怎么使用

應(yīng)用

在catalog.api中,微軟出現(xiàn)了EventBus,我在上一篇中也提到了,這是我的一個(gè)疑惑,因?yàn)樵赾atalog中并沒(méi)有訂閱操作,直接執(zhí)行了Publish操作,原先以為是一個(gè)空操作,后來(lái)看了Basket.Api我才知道為何微軟要用RabbitMQ。

使用RabbitMQ,我們不僅是從類之間的解耦,更可以跨項(xiàng)目,跨語(yǔ)言,跨平臺(tái)的解耦,publisher僅僅需要把消息體(IntegrationEvent)傳送到RabbitMQ,Consumer從Queue中獲取消息體,然后推送到Subscribers執(zhí)行相應(yīng)的操作。我們看下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>()); }

到此,關(guān)于“微服務(wù)架構(gòu)eShopOnContainers怎么使用”的學(xué)習(xí)就結(jié)束了,希望能夠解決大家的疑惑。理論與實(shí)踐的搭配能更好的幫助大家學(xué)習(xí),快去試試吧!若想繼續(xù)學(xué)習(xí)更多相關(guān)知識(shí),請(qǐng)繼續(xù)關(guān)注億速云網(wǎng)站,小編會(huì)繼續(xù)努力為大家?guī)?lái)更多實(shí)用的文章!

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI