Javaで使えそうなServiceDiscoveryを試す

# Service Discoveryとは
ここでは、マイクロサービスアーキテクチャなどで作成したサービスを登録するして検索出来るようにするようなミドルウェアを指す。

なぜ必要かであるが、

- 動的にサービス稼働しているノードが増えたり、減ったりするのにClient側が追従する
- 各ノードへのアクセスを負荷分散させるため

などが大きな理由として挙げられる

役割的なものを軽く図にまとめておく

![Network Diagram.png](https://qiita-image-store.s3.amazonaws.com/0/20943/cf589621-ce5d-bb09-dea3-7f96e28edf01.png)



# Javaで使えるもの

探せばたくさんあると思うが、メジャーなものとして

- Zookeeper
- etcd
- Consul
- Eureka

がある。このうちEurekaはJavaだけに向けた設計になっている。


今回はConsulとEurekaを見てみる。2つとも管理画面があるのと、Client向けライブラリが一応あったためという理由。

他の2つについては、

- etcdはKVSを拡張したような感じと見受けられたので、直接マイクロサービスの基盤として使うにはちょっと気が引けたので未着手
- Zookeeperは、Kafkaなどでも利用しているので見てみようかと思ったが、ServiceDiscoveryとしては少し古い的な話が多かったので、これも気が引けて未着手

という感触であった。


## Consul

https://www.consul.io/

Hashi Corp社が開発。
Go言語で作られているので、各プラットフォーム毎のバイナリをダウンロードして実行するだけで起動する。

機能としては、SerivceDiscoveryの他にKVS(Key/Value Storage)機能もある。

### Consulの起動

dockerで構築されている事例が多いようではあるが、通常のOS上でも稼働する


基本的には、コマンドライン一発

```
consul agent -server -bootstrap -client=127.0.0.1 -dc=local -data-dir=/tmp/consul -bind 127.0.0.1 -node agent-hoge -ui-dir /opt/consul/ui -config-dir /opt/consul/consul.d/
```

consulの設定はコマンドライン引数にて行う。
`-ui-dir`について触れてみるが、Consulクラスタの管理uiを起動するためのオプションになる。
Consulバイナリと同様にダウンロードして展開して出来たディレクトリを起動オプションとして指定するだけ。

(uiのデモはこちら)
http://demo.consul.io/ui/


## Javaによるサービスの登録

Javaからサービスを登録する場合には、OSSライブラリを利用するのが一般的。

https://github.com/OrbitzWorldwide/consul-client

https://github.com/Ecwid/consul-api


上記2つともドキュメントを読めば大体使い方が分かるはず。


### ヘルスチェック

https://www.consul.io/docs/agent/checks.html


consulのヘルスチェックとしては何種類か用意されている

- Script + Interval
− HTTP + Interval 
- TCP + Interval
- Docker + Interval
- TTL

このうちTTL以外は、Consulからサービス側に向けたヘルスチェックとなる。

コマンドラインで起動する時の `-config-dir`オプションにて指定したディレクトリにヘルスチェック向けの設定を記載する。もしくは、ConsulのHTTP APIにてヘルスチェック設定を登録出来る模様。

## Eureka

https://github.com/Netflix/eureka

Netflix社からOSSとして公開されているJavaベースのServiceDiscovery。
AWSでの動作を想定して作成されているが、オンプレのデータセンターでも動作させることは出来る。

![Eureka画像](https://github.com/Netflix/eureka/raw/master/images/eureka_architecture.png)


サンプルの動作させ方などは以下を見ると大体分かるはず。

https://github.com/Netflix/eureka/tree/master/eureka-examples


### Eureka Server起動

Eureka Serverはwarモジュールとして提供されているため、Tomcatなどで動かすのが手っ取り早い
サンプル動作のためには、warを自前でビルドするよりも

http://search.maven.org/#search%7Cga%7C1%7Ceureka-server

から取得するので良いのではないか。
Tomcatのwebapps配下にwarを置き、8080番ポートでHttpを起動すると管理コンソールが見れる

`http://localhost:8080/eureka`

![Untitled.png](https://qiita-image-store.s3.amazonaws.com/0/20943/408eccea-71b4-24f6-02a5-5c8ba9ad1afd.png)



## Javaによるサービスの登録

設定内容の詳細は、Exampleを見て確認するのが良い。また公式ドキュメントも役立つはず。

https://github.com/Netflix/eureka/blob/master/eureka-examples/src/main/java/com/netflix/eureka/ExampleEurekaService.java

サンプルサービスの起動は、githubをcloneしてJavaのパスが通っているなら、以下にて可能

```
./gradlew :eureka-examples:runExampleService
```


# Clientからのアクセスロードバランス機能

Consul, Eurekaともに対象サービスが登録されているホストのIPアドレス、ポート番号を取得出来る。

- consul-clientの例

```
Consul consul = Consul.builder().build(); // connect to Consul on localhost
HealthClient healthClient = consul.healthClient();
List<ServiceHealth> nodes = healthClient.getHealthyServiceInstances("DataService").getResponse(); 
```

- Eureka Clientの例

Eureka Clientでゴリゴリ記載しても出来そうではある。これはExampleを参照のこと。

```
nextServerInfo = DiscoveryManager.getInstance()
                    .getEurekaClient()
                    .getNextServerFromEureka(vipAddress, false);
```

またサンプルプログラムも以下にて起動出来る

```
./gradlew :eureka-examples:runExampleClient
```

どちらにしても、アクセスロードバランスについては、同じNetflix製OSSのribbonを利用したいところ

https://github.com/Netflix/ribbon

特に同じNetflix社製のEurekaとの連携はモジュールもあり導入しやすそう


# まとめ

Service Discoveryとして、ConsulとEurekaの単純なセットアップをまとめた。

- Consul
Javaでの利用に特化しているわけでもなく、かつService Discoveryだけでなく、KVSやDNS連携もあり広範囲な使い方を想定したミドルウェアのようだ

- Eureka
Javaでマイクロサービスを構築するためのService Discoveryに特化しており、他のNetflix製OSSと組み合わせることでJavaにおいては大幅な実装削減が期待できると感じた。


以上、2016年のGWに調べたことを忘れないうちにまとめてみた。