Usual Software Engineer

よくあるソフトウェアエンジニアのブログ

Java マイクロサービス用のライブラリ Helidon

最近 Helidon という Java のマイクロサービス用の OSS があるのを知って少し使ってみました。 例のごとく遅れた 11 月分のブログになります。

Helidon

さっそく Helidon についてですが、 OracleOSSJava でサクッとマイクロサービスを作るときに役立つライブラリ群になります。 軽く使っただけなのですが、基本は Netty 上に Web API を動かせるように用意されたライブラリで、あとは CDI とか JAX-RS とかを組み合わせて Java なのに少ないコードで REST API とか作れちゃうよってものでした。

Spring を知らない人にとっては Spring と依存なしでマイクロサービスをサクッと作れるところは良いなという印象でしたが、よく考えたら結局 CDI とかの Java EE 系ライブラリを知ってないといけないので、普段僕のように Spring でマイクロサービスを作っている人からすると、Helidon にさほど大きいメリットは無さそうかなと思っちゃいました。 ただサーバ設定を yaml でできるだけでなく、外部の git や etcd などから取得できるようになっているところなどはマイクロサービス用として頑張ってる感は垣間見えました。

今回のサンプルコードですが、ほぼコードは無くて、 prometheus 用のメトリクスが吐けるようなので Docker Compose で動かして取得してみました。リポジトリはこちらです。

github.com

Helidon のコードですが、ただ起動するだけならこれだけのコードでいけます。

https://github.com/innossh/helidon-example/blob/v0.0.1/metrics/src/main/java/innossh/helidon/example/metrics/Main.java

        WebServer.create(
                ServerConfiguration.builder().port(8080).build(),
                Routing.builder()
                        .register(MetricsSupport.create())
                        .get("/greet", (req, res)
                                -> res.send("Hello World!")))
                .start();

.register(MetricsSupport.create()) の部分で prometheus 用のメトリクス出力を有効にしています。他はほぼ公式の Getting started と同じです。ビルドの手順も公式と同じ感じで、 Gradle の assemble タスクなどでビルドした後さらに docker image をビルドします。 あとは Docker Compose で prometheus と一緒に起動します。

https://github.com/innossh/helidon-example/blob/v0.0.1/docker-compose.yml

version: '3'
services:
  helidon-example-metrics:
    image: helidon-example-metrics
    ports:
      - "8080:8080"
  prometheus:
    image: "prom/prometheus:v2.5.0"
    ports:
      - "9090:9090"
    volumes:
      - "./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml"
    depends_on:
      - helidon-example-metrics

起動したら /greet/metrics へのリクエストを確認してみましょう。

$ curl -s 127.0.0.1:8080/greet
Hello World!

$ curl -s 127.0.0.1:8080/metrics
# TYPE base:classloader_total_loaded_class_count counter
# HELP base:classloader_total_loaded_class_count Displays the total number of classes that have been loaded since the Java virtual machine has started execution.
base:classloader_total_loaded_class_count 2778
# TYPE base:cpu_system_load_average gauge
# HELP base:cpu_system_load_average Displays the system load average for the last minute. The system load average is the sum of the number of runnable entities queued to the available processors and the number of runnable entities running on the available processors averaged over a period of time. The way in which the load average is calculated is operating system specific but is typically a damped timedependent average. If the load average is not available, a negative value is displayed. This attribute is designed to provide a hint about the system load and may be queried frequently. The load average may be unavailable on some platforms where it is expensive to implement this method.
...

無事 Web API が動作していますね。あとは prometheus 側でメトリクスをみてみましょう。

f:id:innossh:20181202202946p:plain

例えば base:memory_used_heap_bytes のメトリクスはこのように取得できます。他にも下記のようなメトリクスが取得できるのでこれは便利ですね。

base:classloader_total_loaded_class_count 2778
base:cpu_system_load_average 0.0390625
base:thread_count 9
base:classloader_current_loaded_class_count 2778
base:jvm_uptime_seconds 6574.599
base:gc_ps_mark_sweep_count 1
base:memory_committed_heap_bytes 99614720
base:thread_max_count 9
base:gc_ps_scavenge_count 47
base:cpu_available_processors 2
base:thread_daemon_count 3
base:classloader_total_unloaded_class_count 0
base:memory_max_heap_bytes 466092032
base:memory_used_heap_bytes 89911976
base:gc_ps_mark_sweep_time_seconds 0.028
base:gc_ps_scavenge_time_seconds 0.264
vendor:requests_count 1317
vendor:requests_meter_total 1317
vendor:requests_meter_rate_per_second 0.20036203450397075
vendor:requests_meter_one_min_rate_per_second 0.19999999999999984
vendor:requests_meter_five_min_rate_per_second 0.19999999993943207
vendor:requests_meter_fifteen_min_rate_per_second 0.19986565753552663

以上、少しですが Helidon 情報でした。