1. Übersicht
Spring Integration bietet einen Messaging-Mechanismus zum Austausch von Messages über MessageChannels. Kanaladapter werden verwendet, um mit externen Systemen zu kommunizieren.
In dieser Übung erstellen wir zwei Apps, die über die von Spring Cloud GCP bereitgestellten Spring Integration-Kanaladapter kommunizieren. Mit diesen Adaptern verwendet Spring Integration Google Cloud Pub/Sub als Backend für den Nachrichtenaustausch.
Außerdem lernen Sie, wie Sie Cloud Shell und den Cloud SDK-Befehl `gcloud` verwenden.
In dieser Anleitung wird Beispielcode aus dem Startleitfaden zu Spring Boot verwendet.
Lerninhalte
- Nachrichten zwischen Apps mit Google Cloud Pub/Sub über Spring Integration und Spring Cloud GCP austauschen
Voraussetzungen
- Google Cloud Platform-Projekt
- Browser, z. B. Chrome oder Firefox
- Erfahrung mit standardmäßigen Linux-Texteditoren wie Vim, EMACs oder Nano
Wie möchten Sie diese Anleitung verwenden?
Wie würden Sie Ihre Erfahrung mit der Entwicklung von HTML/CSS-Webanwendungen bewerten?
Wie würden Sie Ihre Erfahrung mit der Verwendung von Google Cloud Platform-Diensten bewerten?
2. Einrichtung und Anforderungen
Umgebung zum selbstbestimmten Lernen einrichten
- Melden Sie sich in der Google Cloud Console an und erstellen Sie ein neues Projekt oder verwenden Sie ein vorhandenes. Wenn Sie noch kein Gmail- oder Google Workspace-Konto haben, müssen Sie eines erstellen.



- Der Projektname ist der Anzeigename für die Teilnehmer dieses Projekts. Er ist ein String, der von Google APIs nicht verwendet wird. Sie können ihn jederzeit aktualisieren.
- Die Projekt-ID ist für alle Google Cloud-Projekte eindeutig und unveränderlich. Sie kann also nicht geändert werden, nachdem sie festgelegt wurde. Die Cloud Console generiert automatisch einen eindeutigen String. In der Regel ist es nicht wichtig, wie dieser String aussieht. In den meisten Codelabs müssen Sie auf Ihre Projekt-ID verweisen (in der Regel als
PROJECT_IDangegeben). Wenn Ihnen die generierte ID nicht gefällt, können Sie eine andere zufällige ID generieren. Alternativ können Sie eine eigene ID verwenden und prüfen, ob sie verfügbar ist. Sie kann nach diesem Schritt nicht mehr geändert werden und bleibt für die Dauer des Projekts bestehen. - Zur Information: Es gibt einen dritten Wert, die Projektnummer, die von einigen APIs verwendet wird. Weitere Informationen zu diesen drei Werten finden Sie in der Dokumentation.
- Als Nächstes müssen Sie die Abrechnung in der Cloud Console aktivieren, um Cloud-Ressourcen/APIs zu verwenden. Die Ausführung dieses Codelabs kostet wenig oder gar nichts. Wenn Sie Ressourcen herunterfahren möchten, um zu vermeiden, dass Ihnen nach Abschluss dieser Anleitung Kosten in Rechnung gestellt werden, können Sie die erstellten Ressourcen oder das Projekt löschen. Neue Google Cloud-Nutzer können das kostenlose Testprogramm im Wert von 300 $ nutzen.
Google Cloud Shell
Google Cloud kann zwar von Ihrem Laptop aus per Fernzugriff genutzt werden, in diesem Codelab verwenden wir jedoch Google Cloud Shell, eine Befehlszeilenumgebung, die in der Cloud ausgeführt wird.
Cloud Shell aktivieren
- Klicken Sie in der Cloud Console auf Cloud Shell aktivieren
.

Wenn Sie Cloud Shell zum ersten Mal starten, wird ein Fenster mit einer Beschreibung eingeblendet. Klicken Sie in diesem Fall einfach auf Weiter.

Das Herstellen der Verbindung mit der Cloud Shell sollte nur wenige Augenblicke dauern.

Auf dieser virtuellen Maschine sind alle erforderlichen Entwicklungstools installiert. Sie bietet ein Basisverzeichnis mit 5 GB nichtflüchtigem Speicher und wird in Google Cloud ausgeführt, was die Netzwerkleistung und Authentifizierung erheblich verbessert. Die meisten, wenn nicht alle Aufgaben in diesem Codelab können mit einem Browser ausgeführt werden.
Sobald die Verbindung mit der Cloud Shell hergestellt ist, sehen Sie, dass Sie authentifiziert sind und für das Projekt schon Ihre Projekt-ID eingestellt ist.
- Führen Sie in der Cloud Shell den folgenden Befehl aus, um zu prüfen, ob Sie authentifiziert sind:
gcloud auth list
Befehlsausgabe
Credentialed Accounts
ACTIVE ACCOUNT
* <my_account>@<my_domain.com>
To set the active account, run:
$ gcloud config set account `ACCOUNT`
- Führen Sie in der Cloud Shell den folgenden Befehl aus, um zu prüfen, ob der Befehl `gcloud` Ihr Projekt kennt:
gcloud config list project
Befehlsausgabe
[core] project = <PROJECT_ID>
Ist dies nicht der Fall, können Sie die Einstellung mit diesem Befehl vornehmen:
gcloud config set project <PROJECT_ID>
Befehlsausgabe
Updated property [core/project].
3. Pub/Sub-Ressourcen bereitstellen
Rufen Sie die Seite „Google Cloud Pub/Sub-Themen“ auf.
Klicken Sie auf Thema erstellen.

Geben Sie exampleTopic als Namen des Themas ein und klicken Sie dann auf Erstellen.

Bleiben Sie nach dem Erstellen des Themas auf der Seite „Themen“. Suchen Sie das gerade erstellte Thema, klicken Sie auf die drei vertikalen Punkte am Ende der Zeile und dann auf Neues Abo.

Geben Sie exampleSubscription in das Textfeld für den Abo-Namen ein und klicken Sie auf Erstellen.

4. Spring Boot-Anwendungen initialisieren
Nachdem Cloud Shell gestartet wurde, können Sie über die Befehlszeile mit Spring Initializr zwei neue Spring Boot-Anwendungen generieren:
$ curl https://start.spring.io/starter.tgz \
-d bootVersion=3.0.5 \
-d dependencies=web,integration,cloud-gcp-pubsub \
-d type=maven-project \
-d baseDir=spring-integration-sender | tar -xzvf -
$ curl https://start.spring.io/starter.tgz \
-d bootVersion=3.0.5 \
-d dependencies=web,integration,cloud-gcp-pubsub \
-d type=maven-project \
-d baseDir=spring-integration-receiver | tar -xzvf -
5. Anwendung zum Senden von Nachrichten erstellen
Erstellen wir nun unsere App zum Senden von Nachrichten. Wechseln Sie zum Verzeichnis der Sende-App.
$ cd spring-integration-sender
Wir möchten, dass unsere App Nachrichten in einen Kanal schreibt. Sobald sich eine Nachricht im Kanal befindet, wird sie vom Ausgangskanaladapter abgerufen, der sie von einer generischen Spring-Nachricht in eine Google Cloud Pub/Sub-Nachricht konvertiert und in einem Google Cloud Pub/Sub-Thema veröffentlicht.
Damit unsere App in einen Kanal schreiben kann, können wir ein Spring Integration-Messaging-Gateway verwenden. Deklarieren Sie mit einem Texteditor wie vim, emacs oder nano eine PubsubOutboundGateway-Schnittstelle in der Klasse DemoApplication.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.integration.annotation.MessagingGateway;
@SpringBootApplication
public class DemoApplication {
...
@MessagingGateway(defaultRequestChannel = "pubsubOutputChannel")
public interface PubsubOutboundGateway {
void sendToPubsub(String text);
}
}
Wir haben jetzt einen Mechanismus zum Senden von Nachrichten an einen Kanal. Aber wohin werden diese Nachrichten gesendet, nachdem sie sich im Kanal befinden?
Wir benötigen einen Ausgangskanaladapter, um neue Nachrichten im Kanal zu verarbeiten und in einem Google Cloud Pub/Sub-Thema zu veröffentlichen.
src/main/java/com/example/demo/DemoApplication.java
...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.outbound.PubSubMessageHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.integration.annotation.ServiceActivator;
import org.springframework.messaging.MessageHandler;
@SpringBootApplication
public class DemoApplication {
...
@Bean
@ServiceActivator(inputChannel = "pubsubOutputChannel")
public MessageHandler messageSender(PubSubTemplate pubsubTemplate) {
return new PubSubMessageHandler(pubsubTemplate, "exampleTopic");
}
}
Die Annotation @ServiceActivator bewirkt, dass dieser MessageHandler auf alle neuen Nachrichten in inputChannel angewendet wird. In diesem Fall rufen wir unseren Ausgangskanaladapter PubSubMessageHandler auf, um die Nachricht im Thema exampleTopic von Google Cloud Pub/Sub zu veröffentlichen.
Nachdem der Kanaladapter eingerichtet ist, können wir jetzt ein PubsubOutboundGateway-Objekt automatisch verknüpfen und damit eine Nachricht in einen Kanal schreiben.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.view.RedirectView;
@SpringBootApplication
public class DemoApplication {
...
@Autowired
private PubsubOutboundGateway messagingGateway;
@PostMapping("/postMessage")
public RedirectView postMessage(@RequestParam("message") String message) {
this.messagingGateway.sendToPubsub(message);
return new RedirectView("/");
}
}
Aufgrund der Annotation @PostMapping haben wir jetzt einen Endpunkt, der auf HTTP-POST-Anfragen wartet. Dazu müssen wir jedoch auch der Klasse DemoApplication die Annotation @RestController hinzufügen, um sie als REST-Controller zu kennzeichnen.
src/main/java/com/example/demo/DemoApplication.java
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
@RestController
public class DemoApplication {
...
}
Prüfen Sie, ob JAVA_HOME auf die richtige Version festgelegt ist.
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
Führen Sie die Sende-App aus.
# Set the Project ID in environmental variable
$ export GOOGLE_CLOUD_PROJECT=`gcloud config list --format 'value(core.project)'`
$ ./mvnw spring-boot:run
Die App wartet auf POST-Anfragen mit einer Nachricht auf Port 8080 und Endpunkt /postMessage. Darauf kommen wir später zurück.
6. Anwendung zum Empfangen von Nachrichten erstellen
Wir haben gerade eine App erstellt, die Nachrichten über Google Cloud Pub/Sub sendet. Jetzt erstellen wir eine weitere App, die diese Nachrichten empfängt und verarbeitet.
Klicken Sie auf + , um eine neue Cloud Shell-Sitzung zu öffnen.

Wechseln Sie dann in der neuen Cloud Shell-Sitzung zum Verzeichnis der Empfänger-App:
$ cd spring-integration-receiver
In der vorherigen App wurde durch die Deklaration des Messaging-Gateways der Ausgangskanal für uns erstellt. Da wir kein Messaging-Gateway zum Empfangen von Nachrichten verwenden, müssen wir einen eigenen MessageChannel deklarieren, in dem eingehende Nachrichten ankommen.
src/main/java/com/example/demo/DemoApplication.java
...
import org.springframework.context.annotation.Bean;
import org.springframework.integration.channel.DirectChannel;
import org.springframework.messaging.MessageChannel;
@SpringBootApplication
public class DemoApplication {
...
@Bean
public MessageChannel pubsubInputChannel() {
return new DirectChannel();
}
}
Wir benötigen den Eingangskanaladapter, um Nachrichten von Google Cloud Pub/Sub zu empfangen und an pubsubInputChannel weiterzuleiten.
src/main/java/com/example/demo/DemoApplication.java
...
import com.google.cloud.spring.pubsub.core.PubSubTemplate;
import com.google.cloud.spring.pubsub.integration.inbound.PubSubInboundChannelAdapter;
import org.springframework.beans.factory.annotation.Qualifier;
@SpringBootApplication
public class DemoApplication {
...
@Bean
public PubSubInboundChannelAdapter messageChannelAdapter(
@Qualifier("pubsubInputChannel") MessageChannel inputChannel,
PubSubTemplate pubSubTemplate) {
PubSubInboundChannelAdapter adapter =
new PubSubInboundChannelAdapter(pubSubTemplate, "exampleSubscription");
adapter.setOutputChannel(inputChannel);
return adapter;
}
}
Dieser Adapter wird an pubsubInputChannel gebunden und wartet auf neue Nachrichten aus dem Google Cloud Pub/Sub-Abo exampleSubscription.
Wir haben einen Kanal, in dem eingehende Nachrichten veröffentlicht werden. Aber was sollen wir mit diesen Nachrichten tun?
Wir verarbeiten sie mit einem @ServiceActivator, der ausgelöst wird, wenn neue Nachrichten in pubsubInputChannel eingehen. In diesem Fall protokollieren wir nur die Nutzlast der Nachricht.
src/main/java/com/example/demo/DemoApplication.java
...
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.integration.annotation.ServiceActivator;
@SpringBootApplication
public class DemoApplication {
...
private static final Log LOGGER = LogFactory.getLog(DemoApplication.class);
@ServiceActivator(inputChannel = "pubsubInputChannel")
public void messageReceiver(String payload) {
LOGGER.info("Message arrived! Payload: " + payload);
}
}
Prüfen Sie, ob JAVA_HOME auf die richtige Version festgelegt ist.
export JAVA_HOME=/usr/lib/jvm/java-1.17.0-openjdk-amd64
Führen Sie die Empfänger-App aus.
$ ./mvnw spring-boot:run -Dspring-boot.run.jvmArguments="-Dserver.port=8081"
Alle Nachrichten, die Sie an die Sende-App senden, werden jetzt in der Empfänger-App protokolliert. Öffnen Sie dazu eine neue Cloud Shell-Sitzung und senden Sie eine HTTP-POST-Anfrage an die Sende-App.
$ curl --data "message=Hello world!" localhost:8080/postMessage
Prüfen Sie dann, ob die Empfänger-App die von Ihnen gesendete Nachricht protokolliert hat.
INFO: Message arrived! Payload: Hello world!
7. Bereinigen
Löschen Sie das Abo und das Thema, die im Rahmen dieser Übung erstellt wurden.
$ gcloud pubsub subscriptions delete exampleSubscription
$ gcloud pubsub topics delete exampleTopic
8. Zusammenfassung
Sie haben zwei Spring Boot-Apps eingerichtet, die die Spring Integration-Kanaladapter für Google Cloud Pub/Sub verwenden. Sie tauschen Nachrichten untereinander aus, ohne jemals mit der Google Cloud Pub/Sub API zu interagieren.
9. Glückwunsch!
Sie haben gelernt, wie Sie die Spring Integration-Kanaladapter für Google Cloud Pub/Sub verwenden.
Weitere Informationen
- Google Cloud Pub/Sub: https://cloud.google.com/pubsub/
- Spring on GCP-Projekt: http://cloud.spring.io/spring-cloud-gcp/
- Spring on GCP-GitHub-Repository: https://github.com/GoogleCloudPlatform/spring-cloud-gcp
- Java in der Google Cloud Platform: https://cloud.google.com/java/
Lizenz
Dieser Text ist mit einer Creative Commons Attribution 2.0 Generic License lizenziert.