Cloud-native messaging op het Red Hat OpenShift-platform met behulp van Quarkus en AMQ Online

Dag Allemaal! Hier is hij dan: ons laatste bericht in de Quarkus-serie! (Bekijk trouwens ons webinar “Dit is Quarkus – het native Java-framework van Kubernetes”. We laten u zien hoe u helemaal opnieuw kunt beginnen of kant-en-klare oplossingen kunt overbrengen)

Cloud-native messaging op het Red Hat OpenShift-platform met behulp van Quarkus en AMQ Online

В vorig In dit bericht hebben we gekeken naar de relevante tools die kunnen worden gebruikt om de verbeteringen te kwantificeren die zijn verkregen als resultaat van de modernisering van Java-applicaties.

Sinds versie 0.17.0, kwark ondersteunt het gebruik van Advanced Message Queuing Protocol (AMQP), een open standaard voor het overbrengen van zakelijke berichten tussen applicaties of organisaties.

Red Hat AMQ Online is een dienst gebouwd op basis van een open source-project EnMasse en het implementeren van een platformgebaseerd berichtenmechanisme Red Hat OpenShift. Voor meer informatie over hoe het werkt, zie hier (EN). Vandaag laten we u zien hoe u AMQ Online en Quarkus kunt combineren om een ​​modern op OpenShift gebaseerd berichtensysteem te bouwen met behulp van twee nieuwe berichtentechnologieën.

Er wordt aangenomen dat u AMQ Online al op het OpenShift-platform hebt geïmplementeerd (zo niet, zie dan installatie gids).

Om te beginnen zullen we een Quarkus-applicatie maken, een eenvoudig orderverwerkingssysteem dat gebruikmaakt van reactieve berichtenuitwisseling. Deze applicatie omvat een ordergenerator die met een vast interval orders naar een berichtenwachtrij verzendt, evenals een orderprocessor die berichten uit de wachtrij verwerkt en bevestigingen genereert die in de browser kunnen worden bekeken.

Nadat we de applicatie hebben gemaakt, laten we u zien hoe u de configuratie van het berichtensysteem in de applicatie kunt insluiten en hoe u AMQ Online kunt gebruiken om de bronnen in te richten die we nodig hebben op het systeem.

Quarkus-app

Onze Quarkus-applicatie draait op OpenShift en is een aangepaste versie van het programma amqp-snelstart. Een compleet voorbeeld van de klantkant vindt u hier hier.

Bestelgenerator

De generator stuurt eenvoudigweg elke 5 seconden groeiende order-ID's naar het "bestellingen"-adres.

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

Orderverwerker

De orderafhandeling is nog eenvoudiger: hij stuurt alleen een bevestigings-ID terug naar het "bevestigings"-adres.

@ApplicationScoped
public class OrderProcessor {
    @Incoming("orders")
    @Outgoing("confirmations")
    public Integer process(Integer order) {
        // Идентификатор подтверждения равен удвоенному идентификатору заказа <img draggable="false" class="emoji" alt=":-)" src="https://s.w.org/images/core/emoji/11.2.0/svg/1f642.svg">
        return order * 2;
    }
}

Bevestigingsbronnen

De bevestigingsbron is een HTTP-eindpunt voor het weergeven van de bevestigingen die door onze applicatie zijn gegenereerd.

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

afstelling

Om verbinding te maken met AMQ Online heeft onze applicatie enkele configuratiegegevens nodig, namelijk: Quarkus-connectorconfiguratie, AMQP-eindpuntinformatie en clientreferenties. Het is natuurlijk beter om alle configuratiegegevens op één plek te bewaren, maar we zullen ze bewust scheiden om de mogelijke opties voor het configureren van de Quarkus-applicatie te tonen.

Connectoren

De connectorconfiguratie kan tijdens het compileren worden opgegeven met behulp van een applicatie-eigenschappenbestand:

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

Om het simpel te houden, gebruiken we alleen een berichtenwachtrij voor het adres 'bestellingen'. En het “bevestigings”-adres in onze applicatie zal een wachtrij in het geheugen gebruiken.

AMQP-eindpunt

Tijdens het compileren zijn de hostnaam en het poortnummer voor het AMQP-eindpunt onbekend, dus deze moeten worden geïnjecteerd. Het eindpunt kan worden ingesteld in de configuratiemap die is gemaakt door AMQ Online, dus we zullen ze definiëren via omgevingsvariabelen in het applicatiemanifest:

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

Referenties

Het serviceaccounttoken kan worden gebruikt om onze applicatie bij OpenShift te authenticeren. Om dit te doen, moet u eerst een aangepaste ConfigSource maken die het authenticatietoken uit het bestandssysteem van de pod leest:

public class MessagingCredentialsConfigSource implements ConfigSource {
    private static final Set<String> propertyNames;
 
    static {
        propertyNames = new HashSet<>();
        propertyNames.add("amqp-username");
        propertyNames.add("amqp-password");
    }
 
    @Override
    public Set<String> getPropertyNames() {
        return propertyNames;
    }
 
    @Override
    public Map<String, String> getProperties() {
        try {
            Map<String, String> 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);
    }
}

Bouw en implementeer de applicatie

Omdat de applicatie in een uitvoerbaar bestand moet worden gecompileerd, is een virtuele GraalVM-machine vereist. Voor details over hoe u hiervoor een omgeving inricht, zie de bijbehorende instructies in Quarkus-gids.

Vervolgens moet u, volgens de daar gegeven instructies, de broncode downloaden, onze applicatie bouwen en implementeren:

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

Na deze opdrachten wordt de applicatie geïmplementeerd, maar start deze pas nadat we de berichtenbronnen hebben geconfigureerd die we nodig hebben in AMQ Online.

Opzetten van het berichtensysteem

Nu hoeft u alleen nog maar de bronnen in te stellen die onze applicatie nodig heeft in het berichtensysteem. Om dit te doen, moet u het volgende creëren: 1) een adresruimte om het eindpunt van het berichtensysteem te initialiseren; 2) adres om de adressen te configureren die we in de applicatie gebruiken; 3) Berichtengebruiker om clientreferenties in te stellen.

Adresruimte

Een AddressSpace-object in AMQ Online is een groep adressen die verbindingseindpunten en authenticatie- en autorisatiebeleid delen. Wanneer u een adresruimte maakt, kunt u opgeven hoe berichteindpunten worden weergegeven:

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

Adres

Adressen worden gebruikt om berichten te verzenden en te ontvangen. Elk adres heeft een type dat de semantiek ervan bepaalt, evenals een plan dat het aantal te reserveren bronnen specificeert. Het adres kan bijvoorbeeld als volgt worden bepaald:

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

Berichtengebruiker

Om ervoor te zorgen dat alleen vertrouwde applicaties berichten naar uw adressen kunnen verzenden en ontvangen, moet u een gebruiker aanmaken in het berichtensysteem. Voor applicaties die op een cluster draaien, kunnen clients worden geverifieerd met behulp van een OpenShift-serviceaccount. De gebruiker "serviceaccount" kan bijvoorbeeld als volgt worden gedefinieerd:

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

Machtigingen om de applicatie te configureren

Om ervoor te zorgen dat AMQ Online de configuratiemap kan maken die we hebben gebruikt om de AMQP-eindpuntinformatie in te sluiten, moeten we de Role en RoleBinding instellen:

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

Configuraties toepassen

U kunt de configuratie van het berichtensysteem als volgt toepassen:

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

Applicatieverificatie

Om er zeker van te zijn dat de applicatie is gestart, gaan we eerst controleren of de bijbehorende adressen zijn aangemaakt en actief zijn:

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

Laten we vervolgens de URL van de applicatieroute controleren (open gewoon dit adres in de browser):

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

De browser moet laten zien dat tickets periodiek worden bijgewerkt naarmate berichten worden verzonden en ontvangen door AMQ Online.

Opsomming

Daarom hebben we een Quarkus-applicatie geschreven die AMQP gebruikt voor berichtenuitwisseling, de applicatie geconfigureerd om op het Red Hat OpenShift-platform te draaien en de configuratie ervan geïmplementeerd op basis van de AMQ Online-configuratie. Vervolgens hebben we de manifesten gemaakt die nodig zijn om het berichtensysteem voor onze applicatie te initialiseren.

Hiermee is de serie over Quarkus afgesloten, maar er staan ​​nog veel nieuwe en interessante dingen in het verschiet, houd het in de gaten!

Bron: www.habr.com

Voeg een reactie