Cloud-basierte Messaging auf der Red Hat OpenShift-Plattform mit Quarkus und AMQ Online

Hallo zusammen! Hier ist er – unser letzter Beitrag in der Serie über Quarkus! (Übrigens, sehen Sie sich unser Webinar an „Quarkus ist ein Kubernetes-nativer Java-Framework“. Wir zeigen, wie man „von Grund auf“ anfängt oder bestehende Lösungen migriert)

Cloud-basierte Messaging auf der Red Hat OpenShift-Plattform mit Quarkus und AMQ Online

In im vorherigen In diesem Beitrag haben wir die entsprechenden Werkzeuge diskutiert, mit denen die Verbesserungen, die durch die Modernisierung von Java-Anwendungen erzielt wurden, quantitativ bewertet werden können.

Seit Version 0.17.0 Quarkus unterstützt die Verwendung des Advanced Message Queuing Protocol (AMQP), das einen offenen Standard für den Austausch von Geschäftsnachrichten zwischen Anwendungen oder Organisationen darstellt.

Red Hat AMQ Online ist ein Dienst, der auf dem Open-Source-Projekt EnMasse basiert und einen Messaging-Mechanismus auf der Plattform implementiert Red Hat OpenShift. Weitere Informationen zur Funktionsweise finden Sie hier lesen (EN). Heute zeigen wir, wie man AMQ Online und Quarkus kombiniert, um ein modernes Messaging-System auf der OpenShift-Plattform mit zwei neuen Technologien im Bereich Messaging zu erstellen.

Es wird angenommen, dass Sie AMQ Online bereits auf der OpenShift-Plattform bereitgestellt haben (wenn nicht, siehe das Installationshandbuch).

Zu Beginn werden wir eine Quarkus-Anwendung erstellen, die ein einfaches System zur Bearbeitung von Bestellungen darstellt, das reaktive Nachrichtenübertragung nutzt. Diese Anwendung umfasst einen Bestellgenerator, der Bestellungen in eine Nachrichtenwarteschlange in festen Intervallen sendet, sowie einen Bestellverarbeiter, der Nachrichten aus der Warteschlange bearbeitet und Bestätigungen erstellt, die im Browser abgerufen werden können.

Nach der Erstellung der Anwendung zeigen wir, wie die Konfiguration des Nachrichtenübertragungssystems integriert wird und nutzen AMQ Online, um die erforderlichen Ressourcen auf diesem System zu initialisieren.

Quarkus-Anwendung

Unsere Quarkus-Anwendung läuft auf OpenShift und ist eine angepasste Version des Programms amqp-quickstart. Das vollständige Beispiel der Client-Seite ist verfügbar unter hier.

Bestellgenerator

Der Generator sendet alle 5 Sekunden einfach monoton wachsende Bestell-IDs an die Adresse "orders".

@ApplicationScoped
public class OrderGenerator {
 
    private int orderId = 1;
 
    @Outgoing("orders")
    public Flowable generate() {
        return Flowable.interval(5, TimeUnit.SECONDS)
        .map(tick -> orderId++);
    }
}

Bestellverarbeiter

Der Bestellverarbeiter ist noch einfacher, er gibt nur die Bestätigungs-ID an die Adresse „confirmations“ zurück.

@ApplicationScoped
public class OrderProcessor {
    @Incoming("orders")
    @Outgoing("confirmations")
    public Integer process(Integer order) {
        // Die Bestätigung-ID entspricht der doppelten Bestell-ID <img draggable="false" class="emoji" alt=":-)" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f642.svg">
        return order * 2;
    }
}

Bestätigungsressourcen

Eine Bestätigungsressource ist ein HTTP-Endpunkt zur Auflistung der durch unsere Anwendung generierten Bestätigungen.

@Path("/confirmations")
public class ConfirmationResource {
 
    @Inject
    @Stream("confirmations") Publisher orders;
 
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello() {
        return "hello";
    }
 
 
    @GET
    @Path("/stream")
    @Produces(MediaType.SERVER_SENT_EVENTS)
    public Publisher stream() {
        return orders;
    }
}

Konfiguration

Um eine Verbindung zu AMQ Online herzustellen, benötigt unsere Anwendung einige Konfigurationsdaten, nämlich: die Konfiguration des Quarkus-Connectors, Informationen zum AMQP-Endpunkt und die Client-Anmeldeinformationen. Am besten halten Sie alle Konfigurationsdaten an einem Ort, aber wir werden sie absichtlich aufteilen, um verschiedene Möglichkeiten zur Konfiguration der Quarkus-Anwendung zu zeigen.

Connectoren

Die Konfiguration des Connectors kann zur Compile-Zeit mit einer Anwendungsproperties-Datei bereitgestellt werden:

mp.messaging.outgoing.orders.connector=smallrye-amqp
mp.messaging.incoming.orders.connector=smallrye-amqp

Um es einfacher zu machen, verwenden wir die Nachrichtenwarteschlange nur für die Adresse „orders“. Die Adresse „confirmations“ in unserer Anwendung wird eine In-Memory-Warteschlange verwenden.

AMQP-Endpunkt

Während des Kompilierungsprozesses sind der Hostname und die Portnummer für den AMQP-Endpunkt unbekannt, daher müssen sie injiziert werden. Der Endpunkt kann in einem ConfigMap festgelegt werden, das von AMQ Online erstellt wird, deshalb definieren wir sie über Umgebungsvariablen im Anwendungsmanifest:

spec:
  template:
    spec:
      containers:
      - env:
        - name: AMQP_HOST
          valueFrom:
            configMapKeyRef:
              name: quarkus-config
              key: service.host
        - name: AMQP_PORT
          valueFrom:
            configMapKeyRef:
              name: quarkus-config
              key: service.port.amqp

Zugangsdaten

Das Token für den Dienstaccount kann zur Authentifizierung unserer Anwendung in OpenShift verwendet werden. Zunächst muss dazu eine benutzerdefinierte ConfigSource erstellt werden, die das Authentifizierungstoken aus dem Dateisystem des Pods liest:

public class MessagingCredentialsConfigSource implements ConfigSource {
    private static final Set propertyNames;
 
    static {
        propertyNames = new HashSet();
        propertyNames.add("amqp-username");
        propertyNames.add("amqp-password");
    }
 
    @Override
    public Set getPropertyNames() {
        return propertyNames;
    }
 
    @Override
    public Map getProperties() {
        try {
            Map properties = new HashMap();
            properties.put("amqp-username", "@@serviceaccount@@");
            properties.put("amqp-password", readTokenFromFile());
            return properties;
        } catch (IOException e) {
            throw new UncheckedIOException(e);
        }
    }
 
    @Override
    public String getValue(String key) {
        if ("amqp-username".equals(key)) {
            return "@@serviceaccount@@";
        }
        if ("amqp-password".equals(key)) {
            try {
                return readTokenFromFile();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }
        return null;
    }
 
    @Override
    public String getName() {
        return "messaging-credentials-config";
    }
 
    private static String readTokenFromFile() throws IOException {
        return new String(Files.readAllBytes(Paths.get("/var/run/secrets/kubernetes.io/serviceaccount/token")), StandardCharsets.UTF_8);
    }
}

Build und Bereitstellung der Anwendung

Da die Anwendung in eine ausführbare Datei kompiliert werden muss, benötigen Sie die GraalVM. Detaillierte Anweisungen zum Einrichten der Umgebung finden Sie in den entsprechenden Anleitungen in Quarkus Guide.

Befolgen Sie die dort angegebenen Anweisungen, um den Quellcode herunterzuladen, die Kompilierung durchzuführen und unsere Anwendung bereitzustellen:

git clone https://github.com/EnMasseProject/enmasse-example-clients
cd enmasse-example-clients/quarkus-example-client
oc new-project myapp
mvn -Pnative -Dfabric8.mode=openshift -Dfabric8.build.strategy=docker package fabric8:build fabric8:resource fabric8:apply

Nach diesen Befehlen wird die Anwendung bereitgestellt, aber sie wird nicht gestartet, bis wir die benötigten Messaging-Ressourcen in AMQ Online konfiguriert haben.

Konfiguration des Messaging-Systems

Nun müssen die Ressourcen im Messaging-System festgelegt werden, die unsere Anwendung benötigt. Dazu müssen wir erstellen: 1) einen Adressraum, um den Endpunkt des Messaging-Systems zu initialisieren; 2) eine Adresse, um die Adressen festzulegen, die wir in der Anwendung verwenden; 3) einen Benutzer im Messaging-System, um die Anmeldeinformationen des Clients festzulegen.

Adressraum

Das AddressSpace-Objekt in AMQ Online ist eine Gruppe von Adressen, die gemeinsame Verbindungspunkte sowie Authentifizierungs- und Autorisierungsrichtlinien nutzen. Beim Erstellen eines AddressSpaces können Sie angeben, wie die Verbindungspunkte des Nachrichtenaustauschsystems bereitgestellt werden:

apiVersion: enmasse.io/v1beta1
kind: AddressSpace
metadata:
  name: quarkus-example
spec:
  type: brokered
  plan: brokered-single-broker
  endpoints:
  - name: messaging
    service: messaging
    exports:
    - name: quarkus-config
      kind: configmap

Adressen

Adressen werden zum Senden und Empfangen von Nachrichten verwendet. Jede Adresse hat einen Typ, der ihre Semantik definiert, sowie einen Plan, der die Menge der reservierten Ressourcen festlegt. Eine Adresse kann beispielsweise so definiert werden:

apiVersion: enmasse.io/v1beta1
kind: Address
metadata:
  name: quarkus-example.orders
spec:
  address: orders
  type: queue
  plan: brokered-queue

Benutzer des Nachrichtenaustauschsystems

Um sicherzustellen, dass nur vertrauenswürdige Anwendungen Nachrichten an Ihre Adressen senden und von ihnen empfangen können, muss im Nachrichtenaustauschsystem ein Benutzer erstellt werden. Für Anwendungen, die im Cluster arbeiten, können Clients mit einem OpenShift-Dienstkonto authentifiziert werden. Ein Benutzer 'serviceaccount' kann beispielsweise so definiert werden:

apiVersion: user.enmasse.io/v1beta1
kind: MessagingUser
metadata:
  name: quarkus-example.app
spec:
  username: system:serviceaccount:myapp:default
  authentication:
    type: serviceaccount
  authorization:
  - operations: ["send", "recv"]
    addresses: ["orders"]

Berechtigungen zur Anwendungskonfiguration

Damit AMQ Online ein ConfigMap erstellen kann, das wir zur Implementierung der AMQP-Endpunktinformationen verwendet haben, müssen eine Rolle und eine Rollenbindung (Role und RoleBinding) definiert werden:

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  name: quarkus-config
spec:
  rules:
  - apiGroups: [ "" ]
    resources: [ "configmaps" ]
    verbs: [ "create" ]
  - apiGroups: [ "" ]
    resources: [ "configmaps" ]
    resourceNames: [ "quarkus-config" ]
    verbs: [ "get", "update", "patch" ]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: quarkus-config
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: quarkus-config
subjects:
- kind: ServiceAccount
  name: address-space-controller
  namespace: amq-online-infra

So wenden Sie Konfigurationen an

Die Konfiguration des Messaging-Systems kann wie folgt angewendet werden:

cd enmasse-example-clients/quarkus-example-client
oc project myapp
oc apply -f src/main/resources/k8s/addressspace
oc apply -f src/main/resources/k8s/address

Überprüfung der Anwendung

Um sicherzustellen, dass die Anwendung gestartet ist, überprüfen wir zuerst, ob die entsprechenden Adressen erstellt und aktiv sind:

until [[ `oc get address quarkus-example.prices -o jsonpath='{.status.phase}'` == "Active" ]]; do echo "Noch nicht bereit"; sleep 5; done

Dann überprüfen wir die URL der Anwendung (einfach diese Adresse im Browser öffnen):

echo "http://$(oc get route quarkus-example-client -o jsonpath='{.spec.host}')/prices.html"

Im Browser sollte zu sehen sein, dass die Tickets regelmäßig aktualisiert werden, während Nachrichten über AMQ Online gesendet und empfangen werden.

Zusammenfassung

Wir haben also eine Quarkus-Anwendung geschrieben, die AMQP für die Nachrichtenübermittlung nutzt, diese Anwendung auf der Red Hat OpenShift-Plattform eingerichtet und ihre Konfiguration basierend auf der AMQ Online-Konfiguration implementiert. Anschließend haben wir die erforderlichen Manifeste erstellt, um das Messaging-System für unsere Anwendung zu initialisieren.

Damit beenden wir die Serie über Quarkus, aber es gibt noch viele neue und interessante Inhalte – bleiben Sie dran!

Quelle: habr.com

Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen 🔥 Zuverlässiges Webhosting mit DDoS-Schutz, VPS- und VDS-Server kaufen | ProHoster