Apache Camelのルートをhawtioを使って可視化する - 導入編


皆さんこんにちは。しうへいと申します。
今回は、Apache Camelのルートをhawtioを使って可視化する方法について書きたいと思います。

hawtioとは?

公式 http://hawt.io/
ざっくり書くと、Apache CamelやJBoss Fuse、その他のJavaアプリケーションにダッシュボードを追加するモジュールです。
Apache CamelやJBoss FuseはRed Hatのエンジニアが中心となって開発されていますが、
hawtioもまた彼らが中心となって開発されています。

基本的な使用手順

  • hawtioのwarファイルをダウンロードして、Javaプロジェクト内にwarファイルを含める
  • Javaプロジェクトにhawtioドライバークラスの依存性を含める
  • プログラム本体でhawtio warファイルをロードし、ポートにマップ

以上でダッシュボードが使えるようになります。
Apache Camelルートのhawtioへのマッピング等は特に必要ありません。
以下で、手順の詳細を説明していきます。

今回のサンプルコードはこちらにあります。
https://github.com/Cuhey3/hawtiosample

hawtioのwarファイルを取得

hawtio本体には、ダッシュボード用のフロントエンド(htmlやJS)が含まれており、warファイル形式でMavenリポジトリに登録されています。
warファイルにもhawtio-defaultやhawtio-jbossなど色々種類があるようですが、今回はhawtio-web-2.0.0.warを使用することにします。

pom.xml
<dependency>
    <groupId>io.hawt</groupId>
    <artifactId>hawtio-web</artifactId>
    <version>2.0.0</version>
    <type>war</type>
</dependency>

一度依存性を宣言すると、ローカルのMavenリポジトリにhawtio-web.2.0.0.warがダウンロードされるので、これをプロジェクトのトップレベルへコピーしておきます。
もう宣言は不要なのでこの部分は削除しておきます。(この辺の手順がちょっと無駄なので、自然な手順をご存知の方は教えていただけるとうれしいです。。)

hawtioドライバークラスの依存性を含める

ここではhawtio-embedded-2.0.0.jarを使用します。

pom.xml
<dependency>
    <groupId>io.hawt</groupId>
    <artifactId>hawtio-embedded</artifactId>
    <version>2.0.0</version>
</dependency>

プログラム本体から起動する

HawtioMain.java
package com.heroku.myapp.hawtiosample;

import io.hawt.embedded.Main;
import java.util.Optional;
import org.springframework.stereotype.Component;

@Component
public class HatwioMain {

    public HatwioMain() throws Exception {
        Main main = new Main();
        System.setProperty("hawtio.authenticationEnabled", "false");
        String port = Optional.ofNullable(System.getenv("PORT")).orElse("2525");
        main.setPort(Integer.parseInt(port));
        main.setContextPath("/foo");
        main.setWarLocation("./");
        main.run();
    }
}

Spring Bootを使っている場合はこの例のように@Componentアノテーションを付けてシングルトンの中で起動すればよいですし、
DIを使わない場合は、メインクラス内でhawtioをrun()するよりも先に、Camelルートを記述する必要があります。
どちらの場合でも、前述のようにhawtioは自動でCamelルートを収集しますので、バインディング等は必要ありません。

Main main = new Main(); main.run();という書き方はCamel Riderにはお馴染みだと思いますが、
これはorg.apache.camel.main.Mainとは全く別のクラスで、RouteBuilderを追加したりはできないので注意。

ダッシュボードを見てみよう

プログラムを実行し、
http://localhost:2525/foo/
にアクセスすると、ウェルカムページが表示されます。

同じものをherokuにもデプロイしていますのでご覧ください。
http://hawtiosample.herokuapp.com/foo/

左上のタブ「Camel」を押してCamelルートの画面に切り替えます。
ルート全体の統計を見ることができます。
今回のサンプルルートは10回に1回の確率で例外を投げるようになっており、「Failed Handled」の項目にカウントがたまっているのが見て取れます。

さらにRoutes > hawtioSampleRoute > Route Diagramを選択します。
可視化された巨大なCamelルートが出現します。

こちらのルート定義は以下で参照できます。
https://github.com/Cuhey3/hawtiosample/blob/master/src/main/java/com/heroku/myapp/hawtiosample/MyRoute.java
可視化のサンプルになるように、複雑だけども意味のないルート定義をしています。
内容をかいつまんで説明すると、

  • はじめに、min=1からmax=10までの中でランダムに選ばれた整数をBodyにセットする(コード上で自由にmin,maxを設定可能)
  • 偶数か奇数かで最初の分岐をする
  • 分岐した先で、取りうる整数を列挙し、二度目の分岐をする
  • 二度目の分岐に続けて、それぞれの整数が持つ約数を示すmockエンドポイントを付加する
  • 分岐を集約してルートを完了

次回の記事では、さらに詳細な説明と、
hawtioで可視化する際に敢えて冗長にルート定義をする場合のtipsについて書きたいと思います。

最後は、ダッシュボードです。メモリ使用量やCPUロードなど、なんだかそれっぽいものが一覧できます。

以上がhawtio導入までの説明になります。

Apache Camelアプリケーションに対してモニタリングが必要な場合は、
Camelルートに対して独自にモニタリング用のエンドポイントを追加したり、それを表示するためのフロントエンドを作ったりするのはかなりの手間ですから、
支障がない限りはhawtioをどんどん使っていくのが良いと思います。