Cloud-orientierter Nachrichtenverkehr auf der Red Hat OpenShift-Plattform unter Verwendung von Quarkus und AMQ Online

Hallo zusammen! Hier ist er – unser abschließender Beitrag aus der Serie über Quarkus! (Übrigens, schaut euch unser Webinar an, „Das ist Quarkus – ein Kubernetes-nativer Java-Framework“. Wir zeigen, wie man „von Grund auf“ startet oder bestehende Lösungen überträgt)

Cloud-orientierter Nachrichtenverkehr auf der Red Hat OpenShift-Plattform unter Verwendung von Quarkus und AMQ Online

Im Im vorherigen Beitrag haben wir die entsprechenden Werkzeuge betrachtet, mit denen man die Verbesserungen quantitativ bewerten kann, die durch die Modernisierung von Java-Anwendungen erreicht wurden.

Seit Version 0.17.0 unterstützt Quarkus 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 Mechanismus zum Nachrichtenaustausch auf der Basis der Red Hat OpenShift -Plattform bereitstellt. Weitere Informationen über die Funktionsweise finden Siehier (EN) . Heute zeigen wir, wie man AMQ Online und Quarkus kombiniert, um ein modernes Nachrichtenaustauschsystem auf Basis von OpenShift zu erstellen, das zwei neue Technologien zur Nachrichtenverarbeitung nutzt.Es wird vorausgesetzt, dass Sie AMQ Online bereits auf der OpenShift-Plattform bereitgestellt haben (wenn nicht, siehe

Installationshandbuch ). Zunächst erstellen wir eine Quarkus-Anwendung, die ein einfaches System zur Auftragsbearbeitung mit reaktivem Nachrichtenaustausch darstellt. Diese Anwendung wird einen Auftragsgenerator enthalten, der Aufträge in regelmäßigen Abständen in die Nachrichtenwarteschlange sendet, sowie einen Auftragsbearbeiter, der Nachrichten aus der Warteschlange verarbeitet und Bestätigungen erzeugt, die im Browser angezeigt werden können.).

Nach der Erstellung der Anwendung zeigen wir, wie Sie die Konfiguration des Nachrichtenaustauschsystems integrieren und AMQ Online nutzen, um die benötigten Ressourcen im System zu initialisieren.

Die Quarkus-Anwendung

Unsere Quarkus-Anwendung läuft auf OpenShift und ist eine modifizierte Version des Programms

amqp-quickstart. Ein vollständiges Beispiel der Client-Seite finden SieAuftragsgenerator hier.

Der Generator sendet alle 5 Sekunden einfach monoton steigende Auftragsidentifikatoren 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++); } }

Auftragsbearbeiter

Bestellabwickler

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

@ApplicationScoped
public class Bestellverarbeiter {
    @Incoming("bestellungen")
    @Outgoing("bestätigungen")
    public Integer verarbeiten(Integer bestellung) {
        // Die Bestätigungs-ID ist gleich 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 bestellung * 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;
    }
}

Einstellungen

Um eine Verbindung zu AMQ Online herzustellen, benötigt unsere Anwendung einige Konfigurationsdaten: die Konfiguration des Quarkus-Connectors, Informationen über den AMQP-Endpunkt und die Anmeldeinformationen des Clients. Es ist besser, alle Konfigurationsdaten an einem Ort zu halten, aber wir werden sie absichtlich trennen, um mögliche Konfigurationsvarianten der Quarkus-Anwendung zu zeigen.

Connectoren

Die Konfiguration des Connectors kann zur Kompilierungszeit über eine Anwendungsproperties-Datei bereitgestellt werden:

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

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

AMQP-Endpunkt

Zur Kompilierungszeit sind der Hostname und die Portnummer für den AMQP-Endpunkt unbekannt, daher müssen sie injiziert werden. Der Endpunkt kann in einer ConfigMap definiert werden, die von AMQ Online erstellt wird, daher werden wir sie über Umgebungsvariablen im Anwendungsmanifest festlegen:

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

Anmeldeinformationen

Das Service-Account-Token kann verwendet werden, um unsere Anwendung in OpenShift zu authentifizieren. Dazu muss zuerst eine benutzerdefinierte ConfigSource erstellt werden, die das Authentifizierungstoken aus dem Dateisystem des Pods liest:

öffentliche Klasse MessagingCredentialsConfigSource implementiert 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);
    }
}

Zusammenstellung und Bereitstellung der Anwendung

Da die Anwendung in eine ausführbare Datei kompiliert werden muss, ist eine GraalVM-virtuelle Maschine erforderlich. Einzelheiten zur Konfiguration dieser Umgebung finden Sie in den entsprechenden Anweisungen im Quarkus Handbuch.

Befolgen Sie dann die dort angegebenen Anweisungen, um den Quellcode herunterzuladen, die Erstellung 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, startet jedoch nicht, bis wir die erforderlichen Messaging-Ressourcen in AMQ Online konfiguriert haben.

Konfiguration des Messaging-Systems

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

Adressraum

Das AddressSpace-Objekt in AMQ Online ist eine Gruppe von Adressen, die sich gemeinsame Verbindungspunkte sowie Authentifizierungs- und Autorisierungspolitiken teilen. Bei der Erstellung eines Adressraums kann festgelegt werden, wie die Endpunkte des Messaging-Systems 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

Adresse

Adressen werden verwendet, um Nachrichten zu senden und zu empfangen. Jede Adresse hat einen Typ, der ihre Semantik bestimmt, sowie einen Plan, der die Anzahl 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 laufen, können Clients mit einem OpenShift-Servicekonto authentifiziert werden. Der 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 Konfiguration der Anwendung

Damit AMQ Online ein configmap erstellen kann, das wir zur Bereitstellung der Informationen zum AMQP-Endpunkt verwenden, müssen eine Rolle und eine Rollenzuweisung (Role und RoleBinding) festgelegt 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

Wie Konfigurationen angewendet werden

Die Konfiguration des Nachrichtenaustauschsystems kann folgendermaßen 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 wurde, überprüfen wir zunächst, 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 des Anwendungspfads (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 an AMQ Online gesendet und empfangen werden.

Zusammenfassung

Wir haben also eine Quarkus-Anwendung geschrieben, die AMQP für den Nachrichtenaustausch verwendet, diese Anwendung so konfiguriert, dass sie auf der Red Hat OpenShift-Plattform läuft, und ihre Konfiguration basierend auf der AMQ Online-Konfiguration implementiert. Anschließend haben wir die erforderlichen Manifeste erstellt, um das Nachrichtenaustauschsystem für unsere Anwendung zu initialisieren.

Damit schließen wir die Serie über Quarkus ab, aber es gibt noch viele neue und interessante Themen, bleibt dran!

Quelle: habr.com

60GB SSD 8Gb DDR4