7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Apache Camelによるマイクロサービスの開発方法

Last updated at Posted at 2021-03-03
1 / 50

概要


マイクロサービスプロジェクトの作成


Camelアプリケーション例

  • 5秒おきにHello from <hostname>を出力するだけのルート
HelloRoute.java
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.util.InetAddressUtil;

public class HelloRoute extends RouteBuilder {

    @Override
    public void configure() throws Exception {
        from("timer:hello?period={{timer.period}}")
            .setBody().constant("Hello from " + InetAddressUtil.getLocalHostName())
            .log("${body}");
    }
}
application.properties
timer.period=5000

Spring Boot

  • Apache Camelのdependencyを追加してプロジェクト生成
start-spring-io.png

サンプルプロジェクト

camel-springboot-hello/
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src/
    ├── main/
    │   ├── java/
    │   │   └── io/github/tadayosi/sample/camel/springboot/hello/
    │   │       ├── HelloApplication.java
    │   │       └── HelloRoute.java
    │   └── resources/
    │       └── application.properties
    └── test
        └── java
            └── io/github/tadayosi/sample/camel/springboot/hello/
                └── HelloApplicationTests.java

Spring Bootを使う場合の注意点

  • HTTPエンドポイント(spring-boot-starter-webなど)がない場合、デフォルトで起動後すぐにJVMがシャットダウンしてしまう
  • CamelContextを実行し続けるには以下をtrueに設定する
application.properties
camel.springboot.main-run-controller=true

ローカルで実行

コマンド
$ mvn spring-boot:run
実行結果
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.2)

2021-02-15 16:28:04.233  INFO 19962 --- [           main] i.g.t.s.c.s.hello.HelloApplication       : Starting HelloApplication using Java 11.0.10 on racine with PID 19962 (/home/tasato/projects/samples/camel-springboot-hello/target/classes started by tasato in /home/tasato/projects/samples/camel-springboot-hello)
2021-02-15 16:28:04.235  INFO 19962 --- [           main] i.g.t.s.c.s.hello.HelloApplication       : No active profile set, falling back to default profiles: default
2021-02-15 16:28:04.988  INFO 19962 --- [           main] o.apache.camel.support.LRUCacheFactory   : Detected and using LRUCacheFactory: camel-caffeine-lrucache
2021-02-15 16:28:05.309  INFO 19962 --- [           main] o.a.c.s.boot.SpringBootRoutesCollector   : Loading additional Camel XML routes from: classpath:camel/*.xml
2021-02-15 16:28:05.310  INFO 19962 --- [           main] o.a.c.s.boot.SpringBootRoutesCollector   : Loading additional Camel XML route templates from: classpath:camel-template/*.xml
2021-02-15 16:28:05.310  INFO 19962 --- [           main] o.a.c.s.boot.SpringBootRoutesCollector   : Loading additional Camel XML rests from: classpath:camel-rest/*.xml
2021-02-15 16:28:05.418  INFO 19962 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 3.7.2 (camel-1) is starting
2021-02-15 16:28:05.419  INFO 19962 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : StreamCaching is not in use. If using streams then it's recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
2021-02-15 16:28:05.420  INFO 19962 --- [           main] c.s.b.CamelSpringBootApplicationListener : Starting CamelMainRunController to ensure the main thread keeps running
2021-02-15 16:28:05.422  INFO 19962 --- [           main] o.a.c.i.e.InternalRouteStartupManager    : Route: route1 started and consuming from: timer://hello
2021-02-15 16:28:05.426  INFO 19962 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Total 1 routes, of which 1 are started
2021-02-15 16:28:05.426  INFO 19962 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 3.7.2 (camel-1) started in 8ms
2021-02-15 16:28:05.435  INFO 19962 --- [           main] i.g.t.s.c.s.hello.HelloApplication       : Started HelloApplication in 1.761 seconds (JVM running for 2.168)
2021-02-15 16:28:06.431  INFO 19962 --- [- timer://hello] route1                                   : Hello from racine
2021-02-15 16:28:11.423  INFO 19962 --- [- timer://hello] route1                                   : Hello from racine
2021-02-15 16:28:16.424  INFO 19962 --- [- timer://hello] route1                                   : Hello from racine

Quarkus

  • 必要なCamel *エクステンションを追加してプロジェクト生成
code-quarkus-io.png

サンプルプロジェクト

camel-quarkus-hello/
├── mvnw
├── mvnw.cmd
├── pom.xml
├── README.md
└── src/
    ├── main/
    │   ├── docker/
    │   │   ├── Dockerfile.fast-jar
    │   │   ├── Dockerfile.jvm
    │   │   └── Dockerfile.native
    │   ├── java/
    │   │   └── io/github/tadayosi/sample/
    │   │       ├── camel/quarkus/hello/
    │   │       │   └── HelloRoute.java
    │   │       └── GreetingResource.java
    │   └── resources/
    │       ├── application.properties
    │       └── META-INF/resources/
    │           └── index.html
    └── test
        └── java
            └── io/github/tadayosi/sample/
                ├── GreetingResourceTest.java
                └── NativeGreetingResourceIT.java

ローカルで実行

コマンド
$ mvn compile quarkus:dev
実行結果
__  ____  __  _____   ___  __ ____  ______ 
 --/ __ \/ / / / _ | / _ \/ //_/ / / / __/ 
 -/ /_/ / /_/ / __ |/ , _/ ,< / /_/ /\ \   
--\___\_\____/_/ |_/_/|_/_/|_|\____/___/   
            Powered by Quarkus 1.11.2.Final
2021-02-15 16:31:49,076 INFO  [org.apa.cam.qua.cor.CamelBootstrapRecorder] (Quarkus Main Thread) bootstrap runtime: org.apache.camel.quarkus.core.CamelContextRuntime
2021-02-15 16:31:49,149 INFO  [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Apache Camel 3.7.0 (camel-1) is starting
2021-02-15 16:31:49,151 INFO  [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) StreamCaching is not in use. If using streams then it's recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
2021-02-15 16:31:49,154 INFO  [org.apa.cam.imp.eng.InternalRouteStartupManager] (Quarkus Main Thread) Route: route1 started and consuming from: timer://hello
2021-02-15 16:31:49,156 INFO  [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Total 1 routes, of which 1 are started
2021-02-15 16:31:49,156 INFO  [org.apa.cam.imp.eng.AbstractCamelContext] (Quarkus Main Thread) Apache Camel 3.7.0 (camel-1) started in 6ms
2021-02-15 16:31:49,251 INFO  [io.quarkus] (Quarkus Main Thread) camel-quarkus-hello 1.0.0-SNAPSHOT on JVM (powered by Quarkus 1.11.2.Final) started in 3.927s. Listening on: http://localhost:8080
2021-02-15 16:31:49,251 INFO  [io.quarkus] (Quarkus Main Thread) Profile dev activated. Live Coding activated.
2021-02-15 16:31:49,252 INFO  [io.quarkus] (Quarkus Main Thread) Installed features: [camel-core, camel-support-common, camel-timer, cdi, kubernetes, resteasy]
2021-02-15 16:31:50,162 INFO  [route1] (Camel (camel-1) thread #0 - timer://hello) Hello from racine
2021-02-15 16:31:55,157 INFO  [route1] (Camel (camel-1) thread #0 - timer://hello) Hello from racine
2021-02-15 16:32:00,156 INFO  [route1] (Camel (camel-1) thread #0 - timer://hello) Hello from racine

Dockerイメージのビルド


JavaプロジェクトのDockerイメージ作成方法


docker-maven-plugin

  • Fabric8プロジェクトの長らくデファクトだったDocker Mavenプラグイン
  • Docker単体で使うなら今でも現役だが、今ならJKubeかフレームワーク固有の機能を使った方がよい

使い方

  • pom.xmlにMavenプラグイン設定を追加する
pom.xml
      <plugin>
        <groupId>io.fabric8</groupId>
        <artifactId>docker-maven-plugin</artifactId>
        <version>0.34.1</version>
        <configuration>
          <images>
            <image>
              <name>tadayosi/${project.artifactId}:${project.version}</name>
              <build>
                <from>adoptopenjdk/openjdk11:ubi-minimal</from>
                <assembly>
                  <descriptorRef>artifact</descriptorRef>
                </assembly>
                <cmd>java -jar maven/${project.artifactId}-${project.version}.jar</cmd>
              </build>
            </image>
          </images>
        </configuration>
      </plugin>

ビルド方法

コマンド
$ mvn package docker:build
確認
$ docker images
REPOSITORY                                                                TAG                 IMAGE ID       CREATED         SIZE
tadayosi/camel-springboot-hello                                           0.0.1-SNAPSHOT      457115bcda7e   3 minutes ago   471MB
...

Eclipse JKube

  • Fabric8 Mavenプラグインの後継
  • Dockerイメージ作成からKubernetes、OpenShiftへのデプロイまでカバーされる

使い方

  • pom.xmlにMavenプラグイン設定を追加する
pom.xml
      <plugin>
        <groupId>org.eclipse.jkube</groupId>
        <artifactId>kubernetes-maven-plugin</artifactId>
        <version>1.1.0</version>
      </plugin>
      <!-- OpenShiftを使いたい場合は以下も入れる -->
      <plugin>
        <groupId>org.eclipse.jkube</groupId>
        <artifactId>openshift-maven-plugin</artifactId>
        <version>1.1.0</version>
      </plugin>
  • Dockerイメージ名を設定したい場合はjkube.generator.nameプロパティを使う
pom.xml
  <properties>
    <jkube.generator.name>tadayosi/%a:%v</jkube.generator.name>
  </properties>

ビルド方法

$ mvn k8s:build
  • ビルドしたイメージをDocker Hubなどのコンテナレジストリーにプッシュする場合
$ mvn k8s:push

OpenShiftの場合

  • oc:buildを使うとローカルでなくOpenShift上に直接ImageStreamがビルドされる
$ mvn oc:build

Spring Bootプラグイン

$ mvn spring-boot:build-image

Quarkus Container Imageエクステンション

$ mvn quarkus:add-extension -Dextensions="container-image-docker"
  • Dockerイメージ名やコンテナレジストリーをカスタマイズしたい場合はapplication.propertiesに書く
application.properties
quarkus.container-image.group=...
quarkus.container-image.name=...
quarkus.container-image.tag=...
quarkus.container-image.registry=docker.io

ビルド方法

$ mvn package -Dquarkus.container-image.build=true
  • コンテナレジストリーにプッシュする場合
$ mvn package -Dquarkus.container-image.push=true

Dockerコンテナの実行

camel-springboot-hello
$ docker run -it tadayosi/camel-springboot-hello:0.0.1-SNAPSHOT
camel-quarkus-hello
$ docker run -it tadayosi/camel-quarkus-hello:1.0.0-SNAPSHOT

Kubernetesへのデプロイと実行


JavaプロジェクトのKubernetesへのデプロイ方法


コンテナイメージを直接実行する

  • あくまでお試し用の方法
    • Podしか作られない
  • 事前にイメージをdocker.ioにプッシュしておく
$ docker push tadayosi/camel-springboot-hello:0.0.1-SNAPSHOT
  • イメージの実行
$ kubectl run camel-springboot-hello --labels="app=camel" \
    --image=tadayosi/camel-springboot-hello:0.0.1-SNAPSHOT
  • 削除
$ kubectl delete pods -l app=camel

JKube kubernetes-maven-plugin

  • Dockerビルドのところでも使ったMavenプラグイン
    • target/classes/META-INF/jkube/以下にマニフェストファイル(*.yml)を生成
    • DeploymentServiceも作ってくれる
  • インストール方法はそちらを参照

使い方

デプロイ
$ mvn k8s:resource k8s:deploy
アンデプロイ
$ mvn k8s:undeploy
  • sternを使って実行結果を確認
$ stern camel-springboot-hello -o raw
+ camel-springboot-hello-6fdc989599-wzlff › spring-boot
Starting the Java application using /opt/jboss/container/java/run/run-java.sh ...
INFO exec  java -javaagent:/usr/share/java/jolokia-jvm-agent/jolokia-jvm.jar=config=/opt/jboss/container/jolokia/etc/jolokia.properties -javaagent:/usr/share/java/prometheus-jmx-exporter/jmx_prometheus_javaagent.jar=9779:/opt/jboss/container/prometheus/etc/jmx-exporter-config.yaml -XX:+UseParallelOldGC -XX:MinHeapFreeRatio=10 -XX:MaxHeapFreeRatio=20 -XX:GCTimeRatio=4 -XX:AdaptiveSizePolicyWeight=90 -XX:MaxMetaspaceSize=100m -XX:+ExitOnOutOfMemoryError -cp "." -jar /deployments/camel-springboot-hello-0.0.1-SNAPSHOT.jar  
[...]
I> No access restrictor found, access to any MBean is allowed
Jolokia: Agent started with URL https://10.131.0.28:8778/jolokia/

  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.4.2)

2021-02-15 12:01:50.337  INFO 1 --- [           main] i.g.t.s.c.s.hello.HelloApplication       : Starting HelloApplication v0.0.1-SNAPSHOT using Java 11.0.9.1 on camel-springboot-hello-6fdc989599-wzlff with PID 1 (/deployments/camel-springboot-hello-0.0.1-SNAPSHOT.jar started by jboss in /deployments)
2021-02-15 12:01:50.340  INFO 1 --- [           main] i.g.t.s.c.s.hello.HelloApplication       : No active profile set, falling back to default profiles: default
2021-02-15 12:01:51.396  INFO 1 --- [           main] o.apache.camel.support.LRUCacheFactory   : Detected and using LRUCacheFactory: camel-caffeine-lrucache
2021-02-15 12:01:51.715  INFO 1 --- [           main] o.a.c.s.boot.SpringBootRoutesCollector   : Loading additional Camel XML routes from: classpath:camel/*.xml
2021-02-15 12:01:51.715  INFO 1 --- [           main] o.a.c.s.boot.SpringBootRoutesCollector   : Loading additional Camel XML route templates from: classpath:camel-template/*.xml
2021-02-15 12:01:51.716  INFO 1 --- [           main] o.a.c.s.boot.SpringBootRoutesCollector   : Loading additional Camel XML rests from: classpath:camel-rest/*.xml
2021-02-15 12:01:51.850  INFO 1 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 3.7.2 (camel-1) is starting
2021-02-15 12:01:51.852  INFO 1 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : StreamCaching is not in use. If using streams then it's recommended to enable stream caching. See more details at http://camel.apache.org/stream-caching.html
2021-02-15 12:01:51.855  INFO 1 --- [           main] c.s.b.CamelSpringBootApplicationListener : Starting CamelMainRunController to ensure the main thread keeps running
2021-02-15 12:01:51.856  INFO 1 --- [           main] o.a.c.i.e.InternalRouteStartupManager    : Route: route1 started and consuming from: timer://hello
2021-02-15 12:01:51.861  INFO 1 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Total 1 routes, of which 1 are started
2021-02-15 12:01:51.861  INFO 1 --- [           main] o.a.c.impl.engine.AbstractCamelContext   : Apache Camel 3.7.2 (camel-1) started in 10ms
2021-02-15 12:01:51.869  INFO 1 --- [           main] i.g.t.s.c.s.hello.HelloApplication       : Started HelloApplication in 2.014 seconds (JVM running for 2.836)
2021-02-15 12:01:52.867  INFO 1 --- [- timer://hello] route1                                   : Hello from camel-springboot-hello-6fdc989599-wzlff
2021-02-15 12:01:57.857  INFO 1 --- [- timer://hello] route1                                   : Hello from camel-springboot-hello-6fdc989599-wzlff
2021-02-15 12:02:02.858  INFO 1 --- [- timer://hello] route1                                   : Hello from camel-springboot-hello-6fdc989599-wzlff
...

Quarkus Kubernetesエクステンション

  • 最初にインストールしていなければ追加
    • quarkus-container-image-*エクステンションが既に1つ追加されている必要あり
$ mvn quarkus:add-extension -Dextensions="kubernetes"

使い方

$ mvn package -Dquarkus.kubernetes.deploy=true \
              -Dquarkus.kubernetes-client.trust-certs=true
  • quarkus.kubernetes-client.trust-certs=trueは本当は良くないがこれがないと動かなかったので…
    • 後で正しいやり方を調査

ラベルを付ける

  • application.propertiesquarkus.kubernetes.labels.*を定義する
application.properties
quarkus.kubernetes.labels.app=camel

マイクロサービス間の呼び出し

  • KubernetesのDNS
    • 推奨の方法
  • 以下はDNS以前の古い方法(オススメしない)
    • Propertiesコンポーネントの{{service:xxxxx}}表記
    • Service Call EIP

KubernetesのDNS

  • another-camel-serviceサービスが定義されていたらそのままDNSでルックアップできる
    • Kubernetes 1.9以前はサポートされていなかった
from("timer:hello?period=5000")
    .to("http://another-camel-service:8080")
    .log("${body}");

{{service:xxxxx}}

  • Propertiesコンポーネントのビルトイン関数
  • 環境変数に定義された以下のxxx-yyy-zzzサービスを自動的に参照できる
    • XXX_YYY_ZZZ_SERVICE_HOST
    • XXX_YYY_ZZZ_SERVICE_PORT
from("timer:hello?period=5000")
    .to("http://{{service:another-camel-service}}")
    .log("${body}");

参考

  • k8sにデプロイしたPodには以下のような環境変数が提供されている
$ kubectl exec camel-quarkus-hello-867767dbf8-62h48 -- env | grep _SERVICE_ | sort -n
CAMEL_QUARKUS_HELLO_SERVICE_HOST=172.30.110.100
CAMEL_QUARKUS_HELLO_SERVICE_PORT=8080
CAMEL_QUARKUS_HELLO_SERVICE_PORT_HTTP=8080
CAMEL_SPRINGBOOT_HELLO_SERVICE_HOST=172.30.200.231
CAMEL_SPRINGBOOT_HELLO_SERVICE_PORT=8080
CAMEL_SPRINGBOOT_HELLO_SERVICE_PORT_HTTP=8080
KUBERNETES_SERVICE_HOST=172.30.0.1
KUBERNETES_SERVICE_PORT=443
KUBERNETES_SERVICE_PORT_HTTPS=443

Service Call EIP

  • Camelのサービスレジストリーに登録された外部サービスを呼び出すためのEIP
    • Kubernetes, Consul, Etcd, Zookeeper, DNS
from("timer:hello?period=5000")
    .serviceCall("another-camel-service")
    .log("${body}");
  • Kubernetesのサービスを呼び出すには以下の依存が必要

Spring Boot

pom.xml
    <dependency>
      <groupId>org.apache.camel</groupId>
      <artifactId>camel-kubernetes-starter</artifactId>
    </dependency>

Quarkus

$ mvn quarkus:add-extension \
      -Dextensions="org.apache.camel.quarkus:camel-quarkus-kubernetes"

マイクロサービスのリモートデバッグ

JKube

  • デフォルト5005ポートでリモートデバッグできる
$ mvn k8s:debug
  • ポートを変えたい場合
$ mvn k8s:debug -Djkube.debug.port=12345

Quarkus

  • quarkus:remote-devを使えばできそう
    • 要調査
$ mvn quarkus:remote-dev ...

マイクロサービスのレジリエンス


ReplicaSet

  • K8Sに元々備わっている冗長化の機能
  • Podが落ちても自動で復旧してくれる
$ kubectl scale deployment camel-springboot-hello --replicas=2
Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: camel
    group: io.github.tadayosi.sample
    provider: jkube
  name: camel-springboot-hello
  ...
spec:
  replicas: 2
  selector:
    matchLabels:
      app: camel
      group: io.github.tadayosi.sample
      provider: jkube
  ...

JKube

src/main/jkube/deployment.yml
spec:
  replicas: 2

Quarkusエクステンション

src/main/resources/application.properties
quarkus.kubernetes.replicas=2

Readiness/Liveness Probe

  • Podのヘルスチェック
    • サービス可能(Ready)になったか
    • 生存しているか
    • ReplicaSetだけではPodの中身の死活監視まではできない
  • Readiness/Liveness Probeの方法
    1. コマンド実行
    2. HTTPリクエスト
    3. TCPソケット
  • SB、QuarkusアプリではHTTPを使うのが一般的
Deployment
spec:
  template:
    spec:
      containers:
        - livenessProbe:
            failureThreshold: 3
            httpGet:
              path: /actuator/health
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 180
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1
          readinessProbe:
            failureThreshold: 3
            httpGet:
              path: /actuator/health
              port: 8080
              scheme: HTTP
            initialDelaySeconds: 10
            periodSeconds: 10
            successThreshold: 1
            timeoutSeconds: 1

JKube

  • POMにspring-boot-starter-actuatorがあれば自動でReadiness/Liveness Probeを設定してくれる
pom.xml
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
application.properties
management.endpoints.web.exposure.include=health

ヘルスチェック

$ kubectl port-forward camel-springboot-hello-ff7d6fc84-djw4l 8080:8080 9779:9779 &
$ curl -s localhost:8080/actuator/health | jq 
{
  "status": "UP",
  "groups": [
    "liveness",
    "readiness"
  ]
}

Prometheus

  • Prometheusもデフォルトでアタッチしてくれている(ポート:9779
$ curl localhost:9779/metrics
# HELP org_xnio_xnio_coreworkerpoolsize CoreWorkerPoolSize (org.xnio<type=Xnio, provider="nio", worker="XNIO-1"><>CoreWorkerPoolSize)
# TYPE org_xnio_xnio_coreworkerpoolsize untyped
org_xnio_xnio_coreworkerpoolsize{provider="\"nio\"",worker="\"XNIO-1\"",} 16.0
# HELP org_xnio_xnio_maxworkerpoolsize MaxWorkerPoolSize (org.xnio<type=Xnio, provider="nio", worker="XNIO-1"><>MaxWorkerPoolSize)
# TYPE org_xnio_xnio_maxworkerpoolsize untyped
org_xnio_xnio_maxworkerpoolsize{provider="\"nio\"",worker="\"XNIO-1\"",} 16.0
...

Quarkusエクステンション

$ mvn quarkus:add-extension -Dextensions="smallrye-health"
Deployment
        livenessProbe:
          failureThreshold: 3
          httpGet:
            path: /q/health/live
            port: 8080
            scheme: HTTP
          periodSeconds: 30
          successThreshold: 1
          timeoutSeconds: 10
        readinessProbe:
          failureThreshold: 3
          httpGet:
            path: /q/health/ready
            port: 8080
            scheme: HTTP
          periodSeconds: 30
          successThreshold: 1
          timeoutSeconds: 10

ヘルスチェック

$ kubectl port-forward camel-quarkus-hello-77f8464467-d9t8t 8080:8080 &
$ curl -s localhost:8080/q/health/live | jq
{
  "status": "UP",
  "checks": []
}

Circuit Breaker EIP

from("timer:hello?period={{timer.period}}")
    .circuitBreaker()
        .to("http://another-camel-service:8080")
    .onFallback()
        .transform().constant("Remote service is down!")
    .end()
    .log("${body}");

使い方

Spring Boot

  • POMにcamel-resilience4j-starterを追加
    • Hystrixはdeprecatedなので使わない
pom.xml
    <dependency>
      <groupId>org.apache.camel.springboot</groupId>
      <artifactId>camel-resilience4j-starter</artifactId>
    </dependency>

Quarkus

  • camel-quarkus-microprofile-fault-toleranceエクステンションを追加
$ mvn quarkus:add-extension -Dextensions="camel-quarkus-microprofile-fault-tolerance"

Kubernetes上でのテスト


Fabric8 Kubernetes Client


使い方

Spring Boot

  • POMにkubernetes-clientを追加
pom.xml
    <dependency>
      <groupId>io.fabric8</groupId>
      <artifactId>kubernetes-client</artifactId>
      <version>5.1.1</version>
      <scope>test</scope>
    </dependency>

Quarkus

  • kubernetes-clientエクステンションを追加
    • quarkus-kubernetes-clientのスコープはtestにしておく
$ mvn quarkus:add-extension -Dextensions="kubernetes-client"

OpenShift


統合テストの書き方

import io.fabric8.kubernetes.api.model.PodList;
import io.fabric8.kubernetes.client.DefaultKubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.assertEquals;

class HelloApplicationIT {
    private KubernetesClient client;

    @BeforeEach
    void setUp() {
        client = new DefaultKubernetesClient();
    }

    @Test
    void testPodsReady() {
        PodList podList = client.pods()
                .withLabel("app", "camel")
                .withLabel("group", "io.github.tadayosi.sample")
                .withLabel("provider", "jkube")
                .list();
        assertEquals(2, podList.getItems().size());
        podList.getItems().forEach(pod -> {
            pod.getStatus().getConditions().stream()
                    .filter(c -> "Ready".equals(c.getType()))
                    .forEach(c -> {
                        assertEquals("True", c.getStatus());
                    });
        });
    }
}

統合テストの実行

  • maven-failsafe-pluginを使う
pom.xml
  <profiles>
    <profile>
      <id>itests</id>
      <build>
        <plugins>
          <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-failsafe-plugin</artifactId>
            <version>3.0.0-M5</version>
          </plugin>
        </plugins>
      </build>
    </profile>
  </profiles>
実行
$ mvn verify -P itests

その他の選択肢


その他のツールセット


Fabric8


Helm


JKubeのHelmサポート

$ mvn k8s:helm
  • target/jkube/helm/camel-springboot-hello/kubernetesにHelm chartが生成される
target/jkube/helm/camel-springboot-hello/kubernetes/
├── Chart.yaml
├── templates
│   ├── camel-springboot-hello-deployment.yaml
│   └── camel-springboot-hello-service.yaml
└── values.yaml
  • Helmを使ったアプリのインストール
$ helm install camel-springboot-hello target/jkube/helm/camel-springboot-hello/kubernetes
$ helm list
NAME                  	NAMESPACE	REVISION	UPDATED                                	STATUS  	CHART                                	APP VERSION
camel-springboot-hello	test     	1       	2021-03-01 15:05:24.784538587 +0900 JST	deployed	camel-springboot-hello-0.0.1-SNAPSHOT	           

Camel K

  • Operatorベースでさらにクラウドネイティブに突き詰めたサブプロジェクト
    • CamelルートをIntegrationカスタムリソースとしてデプロイできる
    • Java、XML、YAML、Groovy、Kotlin、JSをサポート

Camel-Kアーキテクチャ 1
post-camel-k-architecture-detail.png


参考文献


END

  1. https://www.nicolaferraro.me/2018/10/15/introducing-camel-k/

7
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?