Skybaseret messaging på Red Hat OpenShift-platformen ved hjælp af Quarkus og AMQ Online

Hej alle sammen! Her er vores sidste indlæg i serien om Quarkus! (Forresten, se vores webinar «Dette er Quarkus – et Kubernetes-native Java-framework». Vi vil vise, hvordan man kommer i gang «fra bunden» eller migrerer eksisterende løsninger)

Skybaseret messaging på Red Hat OpenShift-platformen ved hjælp af Quarkus og AMQ Online

I forrige I dette indlæg vil vi se på de relevante værktøjer, som kan bruges til kvantitativt at vurdere forbedringerne opnået ved moderniseringen af Java-applikationer.

Fra version 0.17.0 Quarkus støtter brugen af Advanced Message Queuing Protocol (AMQP), som er en åben standard til overførelse af forretningsbeskeder mellem applikationer eller organisationer.

Red Hat AMQ Online – er en service bygget på det åbne projekt EnMasse og implementerer en beskedudvekslingsmekanisme baseret på platformen Red Hat OpenShift. Læs mere om, hvordan det fungerer, se her (EN). I dag vil vi vise, hvordan man kombinerer AMQ Online og Quarkus for at bygge et moderne beskedudvekslingssystem baseret på OpenShift ved hjælp af to nye teknologier relateret til behandlingen af beskeder.

Det forudsættes, at du allerede har implementeret AMQ Online på OpenShift-platformen (hvis ikke, så se installationsvejledningen).

For at starte skal vi skabe Quarkus-applikationer, som vil udgøre et simpelt bestillingsbehandlingssystem ved brug af reaktiv beskedudveksling. Denne applikation vil inkludere en bestillingsgenerator, der sender ordrer til en beskedkø med faste intervaller, samt en ordrehåndterer, der behandler beskederne fra køen og genererer bekræftelser, som er tilgængelige for visning i browseren.

Efter oprettelsen af applikationen vil vi vise, hvordan man implementerer konfigurationen af systemet til beskedudveksling og inddrager AMQ Online for at initialisere de nødvendige ressourcer på dette system.

Quarkus-applikationen

Vores Quarkus-applikation kører på OpenShift og er en modificeret version af programmet amqp-quickstart. Den fulde klientdel kan findes her.

Bestillingsgenerator

Generatoren sender hver 5. sekund monotont stigende bestillings-id'er til adressen «orders».

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

Ordrehåndterer

Ordrehåndtereren er endnu enklere, den returnerer blot bekræftelses-id'et til adressen «confirmations».

@ApplicationScoped
public class OrderProcessor {
    @Incoming("orders")
    @Outgoing("confirmations")
    public Integer process(Integer order) {
        // Bekræftelses-id'et svarer til det dobbelte af ordrenummeret <img draggable="false" class="emoji" alt=":-)" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f642.svg">
        return order * 2;
    }
}

Bekræftelsesressourcer

En bekræftelsesressource er et HTTP-endepunkt til liste over de bekræftelser, der er dannet som et resultat af vores applikations arbejde.

@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;
    }
}

Indstillinger

For at oprette forbindelse til AMQ Online vil vores applikation have brug for nogle konfigurationsdata, nemlig: Quarkus-connector konfiguration, oplysninger om AMQP-endepunktet og klientlegitimationsoplysninger. Det er bedst at holde alle konfigurationsdata på ét sted, men vi opdeler dem med vilje for at vise de mulige konfigurationsmuligheder for Quarkus-applikationen.

Connectors

Connector konfigurationen kan gives på kompileringstidspunktet ved hjælp af en applikations egenskabsfil:

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

For ikke at gøre det kompliceret vil vi kun bruge meddelelseskøen til adressen "orders". Adressen "confirmations" i vores applikation vil bruge en hukommelseskø.

AMQP-endepunkt

På kompileringstidspunktet er værtsnavn og portnummer for AMQP-endepunktet ukendte, så de skal injiceres. Endepunktet kan defineres i configmap, som oprettes af AMQ Online, så vi vil definere dem gennem miljøvariabler i applikationsmanifestet:

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

Loginoplysninger

Service account token kan bruges til at godkende vores applikation i OpenShift. For dette skal vi først oprette en brugerdefineret ConfigSource, der læser autentificeringstoken fra podens filsystem:

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);
    }
}

Bygning og implementering af applikationen

Da applikationen skal kompileres til en eksekverbar fil, kræves der en GraalVM-virtualmaskine. For nærmere oplysninger om, hvordan du konfigurerer miljøet til dette, se de relevante instruktioner i Quarkus Guide.

Følg derefter instruktionerne der, for at downloade kilden, bygge og implementere vores applikation:

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

Efter disse kommandoer vil applikationen være implementeret, men den vil ikke starte, før vi har konfigureret de nødvendige resourcer til messaging i AMQ Online.

Konfiguration af messaging-systemet

Det er nu tilbage at definere de resourcer i messaging-systemet, som vores applikation har brug for. Dette kræver at vi opretter: 1) et adresseområde for at initialisere messaging-systemets endpoint; 2) en adresse for at konfigurere de adresser, vi bruger i applikationen; 3) en bruger for messaging-systemet for at angive klientoplysninger.

Adresseområde

Et AddressSpace-objekt i AMQ Online er en gruppe af adresser, der deler tilslutningspunkter og autentificerings- og autorisationspolitikker. Når du opretter et adresseområde, kan du specificere, hvordan tilslutningspunkterne for messaging-systemet vil blive leveret:

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

Adresser bruges til at sende og modtage beskeder. Hver adresse har en type, der bestemmer dens semantik, samt en plan, der angiver mængden af reserverede ressourcer. En adresse kan eksempelvis defineres således:

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

Bruger af meddelelsessystemet

For at kun betroede applikationer kan sende og modtage beskeder til dine adresser, skal der oprettes en bruger i meddelelsessystemet. For applikationer, der kører på klyngen, kan klienter godkendes ved hjælp af en OpenShift-tjenestekonto. En bruger "serviceaccount" kan eksempelvis defineres således:

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"]

Tilladelser til at konfigurere applikationen

For at AMQ Online kan oprette configmap'en, som vi brugte til at implementere oplysningerne om AMQP-endepunktet, skal der angives en rolle og rollebinding (Role og RoleBinding):

---
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

Hvordan man anvender konfigurationer

Konfigurationen af meddelelsessystemet kan anvendes således:

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

Verifikation af applikationen

For at bekræfte, at applikationen er startet, skal vi først kontrollere, om de relevante adresser er blevet oprettet og er aktive:

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

Derefter tjekker vi URL'en for applikationens rute (bare åbn denne adresse i browseren):

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

I browseren skulle det være synligt, at billetterne opdateres regelmæssigt, efterhånden som beskeder sendes og modtages af AMQ Online.

Sammenfatning

Så vi har skrevet en Quarkus-applikation, der bruger AMQP til beskedudveksling, konfigureret denne applikation til at køre på Red Hat OpenShift-platformen, og implementeret dens konfiguration baseret på AMQ Online-konfigurationen. Derefter har vi oprettet de manifester, der er nødvendige for at indlede beskedudvekslingssystemet til vores applikation.

Hermed afslutter vi serien om Quarkus, men der kommer mange nye og interessante ting, så hold dig opdateret!

Kilde: habr.com

Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere 🔥 Køb pålidelig webhosting med DDoS-beskyttelse, VPS VDS-servere | ProHoster