Spring Cloud Bus

1. Panoramica

In questo articolo, esamineremo il nuovo progetto Spring Cloud Bus. Spring Cloud Bus utilizza un broker di messaggi leggero per collegare i nodi del sistema distribuito. L'utilizzo principale è trasmettere le modifiche alla configurazione o altre informazioni di gestione. Possiamo pensarlo come un attuatore distribuito.

Il progetto utilizza il broker AMQP come trasporto, ma è possibile utilizzare Apache Kafka o Redis al posto di RabbitMQ. Altri trasporti non sono ancora supportati.

Nel corso di questo tutorial, utilizzeremo RabbitMQ come mezzo di trasporto principale, che naturalmente sarà già in esecuzione.

2. Prerequisiti

Prima di iniziare, si consiglia di aver già completato "Introduzione rapida alla configurazione di Spring Cloud". Prenderemo un client e un server di configurazione cloud esistente per estenderli e aggiungere notifiche automatiche sulle modifiche alla configurazione.

2.1. RabbitMQ

Cominciamo con RabbitMQ, che consigliamo di eseguire come RabbitMQ come immagine finestra mobile. È abbastanza semplice da configurare: per far funzionare RabbitMQ localmente, dobbiamo installare Docker ed eseguire i seguenti comandi una volta che Docker è stato installato correttamente:

docker pull rabbitmq:3-management

Questo comando estrae l'immagine docker RabbitMQ insieme al plug-in di gestione installato e abilitato per impostazione predefinita.

Successivamente, possiamo eseguire RabbitMQ:

docker run -d --hostname my-rabbit --name some-rabbit -p 15672:15672 -p 5672:5672 rabbitmq:3-management

Una volta eseguito il comando, possiamo andare al browser web e aprire // localhost: 15672, che mostrerà il modulo di accesso alla console di gestione. Il nome utente predefinito è: "guest" ; password: "ospite" . RabbitMQ ascolterà anche sulla porta 5672.

3. Aggiunta dell'attuatore al client Cloud Config

Dovremmo avere il server di configurazione cloud e il client di configurazione cloud entrambi in esecuzione. Per aggiornare le modifiche alla configurazione è necessario riavviare ogni volta il client, il che non è l'ideale.

Fermiamo il client di configurazione e annotiamo la classe del controller ConfigClient con @RefreshScope :

@SpringBootApplication @RestController @RefreshScope public class SpringCloudConfigClientApplication { // Code here... }

Infine, aggiorniamo il file pom.xml e aggiungiamo Actuator:

 org.springframework.boot spring-boot-actuator 2.2.6.RELEASE 

L'ultima versione può essere trovata qui.

Per impostazione predefinita, tutti gli endpoint sensibili aggiunti dall'attuatore sono protetti. Ciò include l' endpoint "/ refresh" . Per semplicità, disattiveremo la sicurezza aggiornando bootstrap.properties :

management.security.enabled=false

Inoltre, a partire da Spring Boot 2, gli endpoint dell'attuatore non sono esposti per impostazione predefinita. Per renderli disponibili per l'accesso, dobbiamo aggiungerlo in un application.yml :

management: endpoints: web: exposure: include: "*"

Avviamo prima il client e aggiorniamo il ruolo utente da "Sviluppatore" esistente a "Programmatore" nel file delle proprietà su GitHub. Il server di configurazione mostrerà immediatamente i valori aggiornati; tuttavia, il cliente non lo farà. Per fare in modo che il client veda nuovi file, è sufficiente inviare una richiesta POST vuota all'endpoint '/ refresh' , che è stata aggiunta dall'attuatore:

$> curl -X POST //localhost:8080/actuator/refresh

Recupereremo il file JSON che mostra le proprietà aggiornate:

[ "user.role" ]

Infine, possiamo verificare se il ruolo utente è stato aggiornato:

$> curl //localhost:8080/whoami/Mr_Pink Hello Mr_Pink! You are a(n) Programmer and your password is 'd3v3L'.

Il ruolo utente è stato aggiornato correttamente e chiamando l' endpoint "/ refresh" . Configurazione aggiornata del client senza riavviare.

4. Spring Cloud Bus

Utilizzando Actuator, possiamo aggiornare i client. Tuttavia, nell'ambiente cloud, dovremmo andare su ogni singolo client e ricaricare la configurazione accedendo all'endpoint dell'attuatore.

Per risolvere questo problema, possiamo utilizzare Spring Cloud Bus.

4.1. Cliente

Dobbiamo aggiornare il client di configurazione cloud in modo che possa iscriversi allo scambio RabbitMQ:

 org.springframework.cloud spring-cloud-starter-bus-amqp 2.2.1.RELEASE 

L'ultima versione può essere trovata qui.

Per completare le modifiche al client di configurazione, dobbiamo aggiungere i dettagli di RabbitMQ e abilitare il bus cloud in un file application.yml :

--- spring: rabbitmq: host: localhost port: 5672 username: guest password: guest cloud:   bus:       enabled: true refresh:         enabled: true 

Si prega di notare che stiamo utilizzando nome utente e password predefiniti. Questo deve essere aggiornato per la vita reale, le applicazioni di produzione. Per questo tutorial va bene.

Ora, il client avrà un altro endpoint "/ bus-refresh" . La chiamata a questo endpoint provocherà:

  • ottenere l'ultima configurazione dal server di configurazione e aggiornare la sua configurazione annotata da @RefreshScope
  • invia un messaggio allo scambio AMQP informando sull'evento di aggiornamento
  • tutti i nodi sottoscritti aggiorneranno anche la loro configurazione

In questo modo, non è necessario accedere ai singoli nodi e attivare l'aggiornamento della configurazione.

4.2. server

Infine, aggiungiamo due dipendenze al server di configurazione per automatizzare completamente le modifiche alla configurazione.

 org.springframework.cloud spring-cloud-config-monitor 2.2.2.RELEASE 

L'ultima versione può essere trovata qui.

 org.springframework.cloud spring-cloud-starter-stream-rabbit 3.0.4.RELEASE 

La versione più recente può essere trovata qui.

Useremo spring-cloud-config-monitor per monitorare le modifiche alla configurazione e trasmettere eventi utilizzando RabbitMQ come trasporto.

Dobbiamo solo aggiornare application.properties e fornire i dettagli a RabbitMQ:

spring.rabbitmq.host=localhost spring.rabbitmq.port=5672 spring.rabbitmq.username=guest spring.rabbitmq.password=guest

4.3. GitHub Webhook

Everything is set now. Once the server gets notified about configuration changes, it will broadcast this as a message to RabbitMQ. The client will listen to messages and update its configuration when configuration change event is transmitted. However, how a server will now about the modification?

We need to configure a GitHub Webhook. Let's go to GitHub and open our repository holding configuration properties. Now, let's select Settings and Webhook. Let's click on Add webhook button.

Payload URL is the URL for our config server ‘/monitor' endpoint. In our case the URL will be something like this:

//root: [email protected] _IP:8888/monitor

We just need to change Content type in the drop-down menu to application/json. Next, please leave Secret empty and click on Add webhook button – after that, we are all set.

5. Testing

Let's make sure all applications are running. If we go back and check client it will show user.role as ‘Programmer' and user.password as ‘d3v3L‘:

$> curl //localhost:8080/whoami/Mr_Pink Hello Mr_Pink! You are a(n) Programmer and your password is 'd3v3L'.

Previously, we had to use ‘/refresh' endpoint to reload configuration changes. Let's open properties file, change user.role back to Developer and push the changes:

user.role=Programmer

If we check the client now, we will see:

$> curl //localhost:8080/whoami/Mr_Pink Hello Mr_Pink! You are a(n) Developer and your password is 'd3v3L'.

Il client Config ha aggiornato la sua configurazione senza riavviare e senza un aggiornamento esplicito quasi contemporaneamente. Possiamo tornare a GitHub e aprire il webhook creato di recente. In fondo, ci sono le consegne recenti. Possiamo selezionarne uno in cima all'elenco (supponendo che questa fosse la prima modifica - ce ne sarà comunque solo una) ed esaminare il JSON che è stato inviato al server di configurazione.

Possiamo anche controllare i log di configurazione e del server e vedremo le voci:

o.s.cloud.bus.event.RefreshListener: Received remote refresh request. Keys refreshed []

6. Conclusione

In questo articolo, abbiamo preso il server e il client di configurazione Spring Cloud esistenti e abbiamo aggiunto l'endpoint dell'attuatore per aggiornare la configurazione del client. Successivamente, abbiamo utilizzato Spring Cloud Bus per trasmettere le modifiche alla configurazione e automatizzare gli aggiornamenti del client. Abbiamo anche configurato GitHub Webhook e testato l'intera configurazione.

Come sempre, il codice utilizzato durante la discussione può essere trovato su GitHub.