Quarkus ๋ฐ AMQ Online์„ ์‚ฌ์šฉํ•˜๋Š” Red Hat OpenShift ํ”Œ๋žซํผ์˜ ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”์‹œ์ง•

์•ˆ๋…•ํ•˜์„ธ์š” ์—ฌ๋Ÿฌ๋ถ„! ์—ฌ๊ธฐ ์žˆ์Šต๋‹ˆ๋‹ค - Quarkus ์‹œ๋ฆฌ์ฆˆ์˜ ๋งˆ์ง€๋ง‰ ๊ฒŒ์‹œ๋ฌผ์ž…๋‹ˆ๋‹ค! (๊ทธ๋‚˜์ €๋‚˜ ์›น ์„ธ๋ฏธ๋‚˜๋ฅผ ์‹œ์ฒญํ•ด ๋ณด์„ธ์š”. "์ด๊ฒƒ์ด Quarkus์ž…๋‹ˆ๋‹ค. Kubernetes ๋„ค์ดํ‹ฐ๋ธŒ Java ํ”„๋ ˆ์ž„์›Œํฌ์ž…๋‹ˆ๋‹ค.". ์ฒ˜์Œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜๊ฑฐ๋‚˜ ๊ธฐ์„ฑ ์†”๋ฃจ์…˜์„ ์ „์†กํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ๋ ค ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค)

Quarkus ๋ฐ AMQ Online์„ ์‚ฌ์šฉํ•˜๋Š” Red Hat OpenShift ํ”Œ๋žซํผ์˜ ํด๋ผ์šฐ๋“œ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”์‹œ์ง•

ะ’ ์ด์ „ ์ด ๊ฒŒ์‹œ๋ฌผ์—์„œ๋Š” Java ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํ˜„๋Œ€ํ™”์˜ ๊ฒฐ๊ณผ๋กœ ์–ป์€ ๊ฐœ์„  ์‚ฌํ•ญ์„ ์ •๋Ÿ‰ํ™”ํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ด€๋ จ ๋„๊ตฌ๋ฅผ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค.

๋ฒ„์ „ 0.17.0๋ถ€ํ„ฐ, ์ฟผ์ฟ ์Šค Advanced Message Queuing Protocol(AMQP)์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ์กฐ์ง ๊ฐ„์— ๋น„์ฆˆ๋‹ˆ์Šค ๋ฉ”์‹œ์ง€๋ฅผ ์ „์†กํ•˜๊ธฐ ์œ„ํ•œ ๊ฐœ๋ฐฉํ˜• ํ‘œ์ค€์ž…๋‹ˆ๋‹ค.

๋ ˆ๋“œํ–‡ AMQ ์˜จ๋ผ์ธ ์˜คํ”ˆ์†Œ์Šค ํ”„๋กœ์ ํŠธ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ตฌ์ถ•๋œ ์„œ๋น„์Šค์ž…๋‹ˆ๋‹ค. ์—”๋งˆ์„ธ ํ”Œ๋žซํผ ๊ธฐ๋ฐ˜ ๋ฉ”์‹œ์ง• ๋ฉ”์ปค๋‹ˆ์ฆ˜ ๊ตฌํ˜„ Red Hat OpenShift. ์ž‘๋™ ๋ฐฉ์‹์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”. ์—ฌ๊ธฐ (EN). ์˜ค๋Š˜์€ AMQ Online๊ณผ Quarkus๋ฅผ ๊ฒฐํ•ฉํ•˜์—ฌ ๋‘ ๊ฐ€์ง€ ์ƒˆ๋กœ์šด ๋ฉ”์‹œ์ง• ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ตœ์‹  OpenShift ๊ธฐ๋ฐ˜ ๋ฉ”์‹œ์ง• ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

OpenShift ํ”Œ๋žซํผ์— AMQ Online์„ ์ด๋ฏธ ๋ฐฐํฌํ–ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค(๊ทธ๋ ‡์ง€ ์•Š์€ ๊ฒฝ์šฐ ๋‹ค์Œ์„ ์ฐธ์กฐํ•˜์„ธ์š”). ์„ค์น˜ ์„ค๋ช…์„œ).

๋จผ์ € ๋ฐ˜์‘ํ˜• ๋ฉ”์‹œ์ง•์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ„๋‹จํ•œ ์ฃผ๋ฌธ ์ฒ˜๋ฆฌ ์‹œ์Šคํ…œ์ด ๋  Quarkus ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” ๊ณ ์ •๋œ ๊ฐ„๊ฒฉ์œผ๋กœ ๋ฉ”์‹œ์ง€ ๋Œ€๊ธฐ์—ด์— ์ฃผ๋ฌธ์„ ๋ณด๋‚ด๋Š” ์ฃผ๋ฌธ ์ƒ์„ฑ๊ธฐ์™€ ๋Œ€๊ธฐ์—ด์˜ ๋ฉ”์‹œ์ง€๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋ณผ ์ˆ˜ ์žˆ๋Š” ํ™•์ธ ๋ฉ”์‹œ์ง€๋ฅผ ์ƒ์„ฑํ•˜๋Š” ์ฃผ๋ฌธ ํ”„๋กœ์„ธ์„œ๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋งŒ๋“  ํ›„์—๋Š” ๋ฉ”์‹œ์ง• ์‹œ์Šคํ…œ ๊ตฌ์„ฑ์„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ํฌํ•จํ•˜๊ณ  AMQ Online์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹œ์Šคํ…œ์— ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ํ”„๋กœ๋น„์ €๋‹ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด์—ฌ ๋“œ๋ฆฌ๊ฒ ์Šต๋‹ˆ๋‹ค.

Quarkus ์•ฑ

Quarkus ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ OpenShift์—์„œ ์‹คํ–‰๋˜๋ฉฐ ํ”„๋กœ๊ทธ๋žจ์˜ ์ˆ˜์ •๋œ ๋ฒ„์ „์ž…๋‹ˆ๋‹ค. amqp-๋น ๋ฅธ ์‹œ์ž‘. ํด๋ผ์ด์–ธํŠธ ์ธก์˜ ์ „์ฒด ์˜ˆ๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์—.

์ฃผ๋ฌธ ์ƒ์„ฑ๊ธฐ

์ƒ์„ฑ๊ธฐ๋Š” 5์ดˆ๋งˆ๋‹ค ์ฆ๊ฐ€ํ•˜๋Š” ์ฃผ๋ฌธ ID๋ฅผ "์ฃผ๋ฌธ" ์ฃผ์†Œ๋กœ ๋‹จ์กฐ๋กญ๊ฒŒ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

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

์ฃผ๋ฌธ ์ฒ˜๋ฆฌ์ž

์ฃผ๋ฌธ ์ฒ˜๋ฆฌ๊ธฐ๋Š” ํ›จ์”ฌ ๋” ๊ฐ„๋‹จํ•ฉ๋‹ˆ๋‹ค. ํ™•์ธ ID๋ฅผ "ํ™•์ธ" ์ฃผ์†Œ๋กœ ๋ฐ˜ํ™˜ํ•˜๊ธฐ๋งŒ ํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

@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

์ผ์„ ๋‹จ์ˆœํ•˜๊ฒŒ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด "์ฃผ๋ฌธ" ์ฃผ์†Œ์— ๋Œ€ํ•ด์„œ๋งŒ ๋ฉ”์‹œ์ง€ ๋Œ€๊ธฐ์—ด์„ ์‚ฌ์šฉํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์šฐ๋ฆฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ "ํ™•์ธ" ์ฃผ์†Œ๋Š” ๋ฉ”๋ชจ๋ฆฌ์˜ ๋Œ€๊ธฐ์—ด์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

AMQP ์—”๋“œํฌ์ธํŠธ

์ปดํŒŒ์ผ ํƒ€์ž„์—๋Š” AMQP ์—”๋“œํฌ์ธํŠธ์˜ ํ˜ธ์ŠคํŠธ ์ด๋ฆ„๊ณผ ํฌํŠธ ๋ฒˆํ˜ธ๋ฅผ ์•Œ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์‚ฝ์ž…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—”๋“œํฌ์ธํŠธ๋Š” AMQ Online์—์„œ ์ƒ์„ฑ๋œ configmap์—์„œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋งค๋‹ˆํŽ˜์ŠคํŠธ์˜ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ํ†ตํ•ด ์—”๋“œํฌ์ธํŠธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.

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๋ฅผ ์ƒ์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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 ๊ฐ€์ƒ ๋จธ์‹ ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ํ™˜๊ฒฝ์„ ์„ค์ •ํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ํ•ด๋‹น ์ง€์นจ์„ ์ฐธ์กฐํ•˜์„ธ์š”. ์ฟผ์ปค์Šค ๊ฐ€์ด๋“œ.

๊ทธ๋Ÿฐ ๋‹ค์Œ ๊ฑฐ๊ธฐ์— ์ œ๊ณต๋œ ์ง€์นจ์— ๋”ฐ๋ผ ์†Œ์Šค๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œ ๋ฐ ๋ฐฐํฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

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) ์‚ฌ์šฉ์ž์—๊ฒŒ ํด๋ผ์ด์–ธํŠธ ์ž๊ฒฉ ์ฆ๋ช…์„ ์„ค์ •ํ•˜๋ผ๋Š” ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋ƒ…๋‹ˆ๋‹ค.

์ฃผ์†Œ ๊ณต๊ฐ„

AMQ Online์˜ AddressSpace ๊ฐœ์ฒด๋Š” ์—ฐ๊ฒฐ ๋์ ๊ณผ ์ธ์ฆ ๋ฐ ๊ถŒํ•œ ๋ถ€์—ฌ ์ •์ฑ…์„ ๊ณต์œ ํ•˜๋Š” ์ฃผ์†Œ ๊ทธ๋ฃน์ž…๋‹ˆ๋‹ค. ์ฃผ์†Œ ๊ณต๊ฐ„์„ ๋งŒ๋“ค ๋•Œ ๋ฉ”์‹œ์ง• ๋์ ์ด ๋…ธ์ถœ๋˜๋Š” ๋ฐฉ๋ฒ•์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

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์—์„œ AMQP ์—”๋“œํฌ์ธํŠธ ์ •๋ณด๋ฅผ ํฌํ•จํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•œ configmap์„ ์ƒ์„ฑํ•˜๋ ค๋ฉด 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์—์„œ ๋ฉ”์‹œ์ง€๋ฅผ ๋ณด๋‚ด๊ณ  ๋ฐ›์„ ๋•Œ ํ‹ฐ์ผ“์ด ์ฃผ๊ธฐ์ ์œผ๋กœ ์—…๋ฐ์ดํŠธ๋œ๋‹ค๋Š” ๊ฒƒ์„ ํ‘œ์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ•ฉ์‚ฐ

๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ๋ฉ”์‹œ์ง•์— AMQP๋ฅผ ์‚ฌ์šฉํ•˜๋Š” Quarkus ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์ž‘์„ฑํ•˜๊ณ , Red Hat OpenShift ํ”Œ๋žซํผ์—์„œ ์‹คํ–‰๋˜๋„๋ก ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ตฌ์„ฑํ•˜๊ณ , AMQ Online ๊ตฌ์„ฑ์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•ด๋‹น ๊ตฌ์„ฑ์„ ๊ตฌํ˜„ํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฐ ๋‹ค์Œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ฉ”์‹œ์ง• ์‹œ์Šคํ…œ์„ ์ดˆ๊ธฐํ™”ํ•˜๋Š” ๋ฐ ํ•„์š”ํ•œ ๋งค๋‹ˆํŽ˜์ŠคํŠธ๋ฅผ ๋งŒ๋“ค์—ˆ์Šต๋‹ˆ๋‹ค.

์ด๊ฒƒ์œผ๋กœ Quarkus์— ๋Œ€ํ•œ ์‹œ๋ฆฌ์ฆˆ๊ฐ€ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค. ์•ž์œผ๋กœ ์ƒˆ๋กญ๊ณ  ํฅ๋ฏธ๋กœ์šด ์ผ์ด ๋งŽ์ด ์žˆ์„ ๊ฒƒ์ด๋ฏ€๋กœ ๊ณ„์† ์ง€์ผœ๋ด ์ฃผ์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค!

์ถœ์ฒ˜ : habr.com

์ฝ”๋ฉ˜ํŠธ๋ฅผ ์ถ”๊ฐ€