Cloud-native na pagmemensahe sa platform ng Red Hat OpenShift gamit ang Quarkus at AMQ Online

Kamusta kayong lahat! Narito na - ang aming huling post sa serye ng Quarkus! (Siya nga pala, panoorin ang aming webinar β€œIto ang Quarkus – Kubernetes native Java framework”. Ipapakita namin sa iyo kung paano magsimula sa simula o maglipat ng mga handa na solusyon)

Cloud-native na pagmemensahe sa platform ng Red Hat OpenShift gamit ang Quarkus at AMQ Online

Π’ dati Sa post na ito, tiningnan namin ang mga kaugnay na tool na maaaring magamit upang mabilang ang mga pagpapabuti na nakuha bilang resulta ng pag-modernize ng mga application ng Java.

Mula noong bersyon 0.17.0, quarkus sumusuporta sa paggamit ng Advanced Message Qeuing Protocol (AMQP), na isang bukas na pamantayan para sa paglilipat ng mga mensahe ng negosyo sa pagitan ng mga application o organisasyon.

Red Hat AMQ Online ay isang serbisyong binuo batay sa isang open source na proyekto EnMasse at pagpapatupad ng isang platform-based na mekanismo ng pagmemensahe Red Hat OpenShift. Para sa higit pang mga detalye sa kung paano ito gumagana, tingnan dito (EN). Ngayon ay ipapakita namin sa iyo kung paano pagsamahin ang AMQ Online at Quarkus upang bumuo ng isang modernong OpenShift-based na sistema ng pagmemensahe gamit ang dalawang bagong teknolohiya sa pagmemensahe.

Ipinapalagay na nai-deploy mo na ang AMQ Online sa OpenShift platform (kung hindi pa, tingnan ang gabay sa pag-install).

Upang magsimula, gagawa kami ng Quarkus application na magiging isang simpleng sistema ng pagpoproseso ng order gamit ang reaktibong pagmemensahe. Ang application na ito ay magsasama ng isang generator ng order na nagpapadala ng mga order sa isang queue ng mensahe sa isang nakapirming agwat, pati na rin ang isang processor ng order na magpoproseso ng mga mensahe mula sa queue at bubuo ng mga kumpirmasyon na makikita sa browser.

Kapag nagawa na namin ang application, ipapakita namin sa iyo kung paano i-embed ang configuration ng system ng pagmemensahe sa application at gamitin ang AMQ Online para ibigay ang mga mapagkukunang kailangan namin sa system.

Quarkus app

Ang aming Quarkus application ay tumatakbo sa OpenShift at isang binagong bersyon ng programa amqp-quickstart. Ang isang kumpletong halimbawa ng panig ng kliyente ay matatagpuan dito.

Order generator

Ang generator ay monotonically na nagpapadala ng lumalaking order ID sa "mga order" na address bawat 5 segundo.

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

Processor ng Order

Mas simple pa ang handler ng order, nagbabalik lang ito ng confirmation ID sa "confirmations" address.

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

Mga Mapagkukunan ng Kumpirmasyon

Ang mapagkukunan ng kumpirmasyon ay isang HTTP endpoint para sa paglilista ng mga kumpirmasyon na nabuo ng aming application.

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

pag-aayos

Upang kumonekta sa AMQ Online, ang aming application ay mangangailangan ng ilang data ng pagsasaayos, katulad ng: Quarkus connector configuration, AMQP endpoint information at mga kredensyal ng kliyente. Siyempre, mas mahusay na panatilihin ang lahat ng data ng pagsasaayos sa isang lugar, ngunit sadyang ihihiwalay namin ang mga ito upang ipakita ang mga posibleng opsyon para sa pag-configure ng application ng Quarkus.

Mga konektor

Maaaring ibigay ang configuration ng connector sa oras ng pag-compile gamit ang isang application properties file:

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

Upang panatilihing simple ang mga bagay, gagamit lang kami ng pila ng mensahe para sa address na "mga order." At ang address ng "pagkumpirma" sa aming aplikasyon ay gagamit ng isang pila sa memorya.

AMQP endpoint

Sa oras ng pag-compile, ang hostname at port number para sa AMQP endpoint ay hindi alam, kaya dapat silang mai-inject. Maaaring itakda ang endpoint sa configmap na nilikha ng AMQ Online, kaya tutukuyin namin ang mga ito sa pamamagitan ng mga variable ng kapaligiran sa application manifest:

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

Mga kredensyal

Maaaring gamitin ang token ng account ng serbisyo upang patotohanan ang aming aplikasyon sa OpenShift. Upang gawin ito, kailangan mo munang lumikha ng custom na ConfigSource na magbabasa ng token ng pagpapatunay mula sa file system ng pod:

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

Buuin at I-deploy ang Application

Dahil ang application ay dapat na i-compile sa isang executable file, isang GraalVM virtual machine ay kinakailangan. Para sa mga detalye kung paano mag-set up ng environment para dito, tingnan ang kaukulang mga tagubilin sa Gabay sa Quarkus.

Pagkatapos, kasunod ng mga tagubiling ibinigay doon, kailangan mong i-download ang pinagmulan, buuin at i-deploy ang aming application:

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

Pagkatapos ng mga utos na ito, ide-deploy ang application, ngunit hindi magsisimula hanggang sa i-configure namin ang mga mapagkukunan ng pagmemensahe na kailangan namin sa AMQ Online.

Pagse-set up ng sistema ng pagmemensahe

Ngayon ang natitira na lang ay itakda ang mga mapagkukunan na kailangan ng aming application sa system ng pagmemensahe. Para magawa ito, kailangan mong gumawa ng: 1) isang address space para masimulan ang endpoint ng messaging system; 2) address para i-configure ang mga address na ginagamit namin sa application; 3) Gumagamit ng pagmemensahe upang magtakda ng mga kredensyal ng kliyente.

Puwang ng address

Ang isang AddressSpace object sa AMQ Online ay isang pangkat ng mga address na nagbabahagi ng mga endpoint ng koneksyon at mga patakaran sa pagpapatunay at pagpapahintulot. Kapag gumawa ka ng address space, maaari mong tukuyin kung paano malalantad ang mga endpoint ng pagmemensahe:

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

Mga Address

Ang mga address ay ginagamit upang magpadala at tumanggap ng mga mensahe. Ang bawat address ay may isang uri, na tumutukoy sa mga semantika nito, pati na rin ang isang plano, na tumutukoy sa bilang ng mga mapagkukunang irereserba. Maaaring matukoy ang address, halimbawa, tulad nito:

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

Gumagamit ng pagmemensahe

Upang matiyak na ang mga pinagkakatiwalaang application lamang ang makakapagpadala at makakatanggap ng mga mensahe sa iyong mga address, dapat kang lumikha ng isang user sa system ng pagmemensahe. Para sa mga application na tumatakbo sa isang cluster, ang mga kliyente ay maaaring mapatotohanan gamit ang isang OpenShift service account. Maaaring tukuyin ang "serviceaccount" ng user, halimbawa, tulad nito:

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

Mga pahintulot upang i-configure ang application

Upang magawa ng AMQ Online ang configmap na ginamit namin upang i-embed ang impormasyon ng endpoint ng AMQP, dapat itakda ang Role at 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

Paano mag-apply ng mga configuration

Maaari mong ilapat ang configuration ng system ng pagmemensahe tulad nito:

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

Pag-verify ng aplikasyon

Upang matiyak na nagsimula na ang application, una sa lahat, suriin natin kung ang mga kaukulang address ay nagawa at aktibo:

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

Pagkatapos ay suriin natin ang URL ng ruta ng aplikasyon (buksan lamang ang address na ito sa browser):

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

Dapat ipakita ng browser na pana-panahong ina-update ang mga tiket habang ipinapadala at natatanggap ng AMQ Online ang mga mensahe.

Lagom

Kaya nagsulat kami ng Quarkus application na gumagamit ng AMQP para sa pagmemensahe, na-configure ang application na tumakbo sa Red Hat OpenShift platform, at ipinatupad ang configuration nito batay sa AMQ Online configuration. Pagkatapos ay ginawa namin ang mga manifest na kailangan para masimulan ang sistema ng pagmemensahe para sa aming aplikasyon.

Ito ay nagtatapos sa serye tungkol sa Quarkus, ngunit maraming bago at kawili-wiling mga bagay sa hinaharap, manatiling nakatutok!

Pinagmulan: www.habr.com

Magdagdag ng komento