Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Suggerimento
Questo contenuto è un estratto dell'eBook, Architettura di microservizi .NET per applicazioni .NET containerizzati, disponibile in documentazione .NET o come PDF scaricabile gratuitamente leggibile offline.
È consigliabile iniziare dicendo che se si crea il bus di eventi personalizzato basato su RabbitMQ in esecuzione in un contenitore, come fa l'applicazione eShopOnContainers, deve essere usata solo per gli ambienti di sviluppo e test. Non usarlo per l'ambiente di produzione reale, a meno che non lo si stia costruendo come parte di un bus di servizio pronto per l'ambiente di produzione, come descritto nella sezione Risorse aggiuntive di seguito. Un bus di eventi personalizzato semplice potrebbe non avere molte funzionalità critiche pronte per la produzione di cui dispone un bus di servizio commerciale.
Una delle implementazioni personalizzate del bus di eventi in eShopOnContainers è fondamentalmente una libreria che usa l'API RabbitMQ. È disponibile un'altra implementazione basata sul bus di servizio di Azure.
L'implementazione del bus di eventi con RabbitMQ consente ai microservizi di sottoscrivere eventi, pubblicare eventi e ricevere eventi, come illustrato nella figura 6-21.
Figura 6-21. Implementazione RabbitMQ di un bus di eventi
RabbitMQ funge da intermediario tra server di pubblicazione messaggi e sottoscrittori, per gestire la distribuzione. Nel codice la classe EventBusRabbitMQ implementa l'interfaccia IEventBus generica. Questa implementazione è basata sull'Iniezione di Dipendenze in modo da poter passare da questa versione di sviluppo/test a una versione per la produzione.
public class EventBusRabbitMQ : IEventBus, IDisposable
{
// Implementation using RabbitMQ API
//...
}
L'implementazione RabbitMQ di un bus di eventi di sviluppo/test di esempio è il codice boilerplate. Deve gestire la connessione al server RabbitMQ e fornire il codice per la pubblicazione di un evento di messaggistica nelle code. Deve inoltre implementare un dizionario di raccolte di gestori di eventi di integrazione per ogni tipo di evento. Questi tipi di evento possono avere un'istanza differente e sottoscrizioni diverse per ogni microservizio ricevitore, come illustrato nella Figura 6-21.
Implementazione di un metodo di pubblicazione semplice con RabbitMQ
Il codice seguente è una versione semplificata di un'implementazione del bus di eventi per RabbitMQ, per illustrare l'intero scenario. La connessione non viene davvero gestita in questo modo. Per visualizzare l'implementazione completa, vedere il codice effettivo nel repository dotnet-architecture/eShopOnContainers .
public class EventBusRabbitMQ : IEventBus, IDisposable
{
// Member objects and other methods ...
// ...
public void Publish(IntegrationEvent @event)
{
var eventName = @event.GetType().Name;
var factory = new ConnectionFactory() { HostName = _connectionString };
using (var connection = factory.CreateConnection())
using (var channel = connection.CreateModel())
{
channel.ExchangeDeclare(exchange: _brokerName,
type: "direct");
string message = JsonConvert.SerializeObject(@event);
var body = Encoding.UTF8.GetBytes(message);
channel.BasicPublish(exchange: _brokerName,
routingKey: eventName,
basicProperties: null,
body: body);
}
}
}
Il codice sorgente del metodo Publish nell'applicazione eShopOnContainers viene migliorato usando un criterio di ripetizione Polly, che riprova l'attività più volte nel caso in cui il contenitore RabbitMQ non sia pronto. Questo scenario può verificarsi quando docker-compose avvia i contenitori; Ad esempio, il contenitore RabbitMQ potrebbe iniziare più lentamente rispetto agli altri contenitori.
Come accennato in precedenza, esistono molte configurazioni possibili in RabbitMQ, quindi questo codice deve essere usato solo per gli ambienti di sviluppo/test.
Implementazione del codice di sottoscrizione con l'API RabbitMQ
Come per il codice di pubblicazione, il codice seguente è una semplificazione della parte dell'implementazione del bus di eventi per RabbitMQ. Di solito non è necessario modificarlo a meno che non si stia cercando di migliorarlo.
public class EventBusRabbitMQ : IEventBus, IDisposable
{
// Member objects and other methods ...
// ...
public void Subscribe<T, TH>()
where T : IntegrationEvent
where TH : IIntegrationEventHandler<T>
{
var eventName = _subsManager.GetEventKey<T>();
var containsKey = _subsManager.HasSubscriptionsForEvent(eventName);
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>();
}
}
Ogni tipo di evento ha un canale correlato per ottenere eventi da RabbitMQ. È quindi possibile avere tutti i gestori eventi per canale e tipo di evento in base alle esigenze.
Il metodo Subscribe accetta un oggetto IIntegrationEventHandler, simile a un metodo di callback nel microservizio corrente, oltre al relativo oggetto IntegrationEvent correlato. Il codice aggiunge quindi il gestore eventi all'elenco di gestori eventi che ogni tipo di evento di integrazione può avere per ogni microservizio client. Se il codice client non è già stato sottoscritto all'evento, il codice crea un canale per il tipo di evento in modo che possa ricevere eventi in uno stile push da RabbitMQ quando tale evento viene pubblicato da qualsiasi altro servizio.
Come accennato in precedenza, il bus di eventi implementato in eShopOnContainers ha solo uno scopo educativo, poiché gestisce solo gli scenari principali, quindi non è pronto per la produzione.
Per gli scenari di produzione, controllare le risorse aggiuntive seguenti, specifiche per RabbitMQ e la sezione Implementazione della comunicazione basata su eventi tra microservizi .
Risorse aggiuntive
Soluzione pronta per la produzione con supporto per RabbitMQ.
Peregrine Connect - Semplificare l'integrazione con progettazione, distribuzione e gestione efficienti di app, API e flussi di lavoro
https://www.peregrineconnect.com/why-peregrine/rabbitmq-integrationNServiceBus - Bus di servizio commerciale completamente supportato con strumenti avanzati di gestione e monitoraggio per .NET
https://particular.net/EasyNetQ - API client .NET open source per RabbitMQ
https://easynetq.com/MassTransit - Framework applicativo distribuito open source gratuito per .NET
https://masstransit-project.com/Rebus - Bus di servizio .NET open source
https://github.com/rebus-org/Rebus