Воблачна-арыентаваны абмен паведамленнямі на платформе Red Hat OpenShift з выкарыстаннем Quarkus і AMQ Online

Ўсім прывітанне! Вось і ён наш заключны пост з серыі пра Quarkus! (Дарэчы, глядзіце наш вэбінар «Гэта Quarkus – Kubernetes native Java фрэймворк». Пакажам, як пачаць "з нуля" або перанесці гатовыя рашэнні)

Воблачна-арыентаваны абмен паведамленнямі на платформе Red Hat OpenShift з выкарыстаннем Quarkus і AMQ Online

В папярэднім пасце мы разгледзелі адпаведныя прылады, з дапамогай якіх можна колькасна ацаніць паляпшэнні, атрыманыя ў выніку мадэрнізацыі Java-прыкладанняў.

Пачынаючы з версіі 0.17.0, Кваркус падтрымлівае выкарыстанне Advanced Message Queuing Protocol (AMQP), які з'яўляецца адкрытым стандартам перадачы бізнес-паведамленняў паміж праграмамі або арганізацыямі.

Red Hat AMQ Online – гэта сэрвіс, пабудаваны на аснове адкрытага праекту EnMasse і які рэалізуе механізм абмену паведамленняў на базе платформы Red Hat OpenShift. Больш падрабязна аб тым, як ён уладкованы, гл. тут (EN). Сёння мы пакажам, як аб'яднаць AMQ Online і Quarkus, каб пабудаваць сучасную сістэму абмену паведамленнямі на базе OpenShift з выкарыстаннем дзвюх новых тэхналогій, звязаных з апрацоўкай паведамленняў.

Мяркуецца, што вы ўжо разгарнулі AMQ Online на платформе OpenShift (калі не, то гл. кіраўніцтва па ўстаноўцы).

Для пачатку мы створым прыкладанні Quarkus, якое будзе ўяўляць сабой простую сістэму апрацоўкі заказаў з выкарыстаннем рэактыўнага абмену паведамленнямі. Гэта дадатак будзе ўключаць у сябе генератар заказаў, які адпраўляе заказы ў чаргу паведамленняў з фіксаваным інтэрвалам, а таксама апрацоўшчык заказаў, які будзе апрацоўваць паведамленні з чаргі і фармаваць пацверджання, даступныя для прагляду ў браўзэры.

Пасля стварэння прыкладання мы пакажам, як укараняць у яго канфігурацыю сістэмы абмену паведамленнямі і задзейнічаем AMQ Online, каб ініцыялізаваць на гэтай сістэме патрэбныя нам рэсурсы.

Дадатак Quarkus

Наша Quarkus-дадатак выконваецца на OpenShift і ўяўляе сабой мадыфікаваную версію праграмы amqp-quickstart. Поўны прыклад кліенцкай часткі можна знайсці тут.

Генератар заказаў

Генератар кожныя 5 секунд проста манатонна адпраўляе якія растуць ідэнтыфікатары заказаў на адрас "orders".

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

Апрацоўшчык заказаў

Апрацоўшчык заказаў яшчэ прасцей, ён усяго толькі вяртае ідэнтыфікатар пацверджання на адрас "confirmations".

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

Рэсурсы пацверджання

Рэсурс пацверджання - гэта канчатковая кропка HTTP для лістынга сфарміраваных у выніку працы нашага прыкладання пацверджанняў.

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

Настройка

Для падлучэння да AMQ Online нашаму з дадаткам спатрэбіцца некаторыя канфігурацыйныя дадзеныя, а менавіта: канфігурацыя Quarkus-канектара, звесткі аб канчатковай кропцы AMQP і кліенцкія ўліковыя дадзеныя. Лепш, вядома, трымаць усе канфігурацыйныя дадзеныя ў адным месцы, але мы спецыяльна падзелім іх, каб паказаць магчымыя варыянты налады прыкладання Quarkus.

Канектары

Канфігурацыю канектара можна падаць на этапе кампіляцыі з дапамогай файла ўласцівасцяў прыкладання:

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

Каб не ўскладняць, мы будзем выкарыстоўваць чаргу паведамленняў толькі для адрасу "orders". А адрас "confirmations" у нашым дадатку будзе выкарыстоўваць чаргу ў памяці.

Канчатковая кропка AMQP

На этапе кампіляцыі імя хаста і нумар порта для канчатковай кропкі AMQP невядомыя, таму іх трэба ўкараніць. Канчатковую кропку можна задаць у configmap, які ствараецца AMQ Online, таму мы вызначым іх праз зменныя асяроддзі ў маніфесце прыкладання:

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

Уліковыя дадзеныя

Маркер уліковага запісу сэрвісу можна выкарыстоўваць для аўтэнтыфікацыі нашага прыкладання ў OpenShift. Для гэтага трэба спачатку стварыць карыстацкі ConfigSource, які будзе чытаць маркер аўтэнтыфікацыі з файлавай сістэмы 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);
    }
}

Зборка і разгортванне прыкладання

Паколькі прыкладанне трэба скампіляваць у выкананы файл, запатрабуецца віртуальная машына GraalVM. Больш падрабязна аб тым, як наладзіць для гэтага асяроддзе, гл. адпаведныя інструкцыі ў Quarkus Guide.

Затым, прытрымліваючыся прыведзеных там інструкцый, трэба спампаваць зыходнік, правесці зборку і выканаць разгортванне нашага прыкладання:

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

Пасля гэтых каманд прыкладанне будзе разгорнута, але не запусціцца да таго часу, пакуль мы не наладзім у AMQ Online неабходныя нам рэсурсы абмену паведамленнямі.

Настройка сістэмы абмену паведамленнямі

Цяпер засталося задаць у сістэме абмену паведамленнямі рэсурсы, якія патрэбны нашаму з дадаткам. Для гэтага трэба стварыць: 1) адрасную прастору, каб ініцыялізаваць канчатковы пункт сістэмы абмену паведамленнямі; 2) адрас, каб наладзіць адрасы, якія мы выкарыстоўваем у дадатку; 3) карыстальніка сістэмы абмену паведамленнямі, каб задаць уліковыя дадзеныя кліента.

Прастора адрасоў

Аб'ект AddressSpace у AMQ Online - гэта група адрасоў, якія сумесна выкарыстоўваюць канчатковыя кропкі падлучэння, а таксама палітыкі аўтэнтыфікацыі і аўтарызацыі. Пры стварэнні прасторы адрасоў можна задаць, як менавіта будуць падавацца канчатковыя кропкі сістэмы абмену паведамленнямі:

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

Адрасы

Адрасы выкарыстоўваюцца для адпраўкі і прыёму паведамленняў. У кожнага адраса ёсць тып, які вызначае яго семантыку, а таксама план, які задае колькасць рэсурсаў, якія рэзервуюцца. Адрас можна вызначыць, напрыклад, вось так:

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

Карыстальнік сістэмы абмену паведамленнямі

Каб адпраўляць і атрымліваць паведамленні на вашыя адрасы маглі толькі давераныя прыкладанні, у сістэме абмену паведамленнямі неабходна стварыць карыстача. Для прыкладанняў, якія працуюць на кластары, кліентаў можна аўтэнтыфікаваць з дапамогай уліковага запісу сэрвісу OpenShift. Карыстальніка "serviceaccount" можна вызначыць, напрыклад, так:

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

Дазволы для наладкі прыкладання

Каб AMQ Online мог стварыць configmap, які мы выкарыстоўвалі для ўкаранення звестак аб канчатковай кропцы AMQP, неабходна задаць ролю і прывязку ролі (Role і 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

Як прымяніць канфігурацыі

Ужыць канфігурацыю сістэмы абмену паведамленнямі можна вось так:

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

Верыфікацыя прыкладання

Каб пераканацца, што прыкладанне запусцілася, перш за ўсё праверым, ці стварыліся і ці актыўныя адпаведныя адрасы:

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

Затым праверым URL маршруту прыкладання (проста адкрыем гэты адрас у браўзэры):

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

У браўзэры павінна быць бачна, што цікеты перыядычна абнаўляюцца па меры таго, як паведамленні адпраўляюцца і прымаюцца AMQ Online.

Падводзім вынікі

Такім чынам, мы напісалі прыкладанне Quarkus, якое выкарыстоўвае AMQP для абмену паведамленнямі, настроілі гэта дадатак для працы на платформе Red Hat OpenShift, а таксама ўкаранілі яго канфігурацыю на аснове канфігурацыі AMQ Online. Затым мы стварылі маніфесты, неабходныя для ініцыялізацыі сістэмы абмену паведамленнямі пад наша дадатак.

На гэтым мы завяршаем серыю пра Quarkus, але наперадзе шмат новага і цікавага, заставайцеся з намі!

Крыніца: habr.com

Дадаць каментар