Spring Cloudを使ったマイクロサービスシステム構築（多重構成編）

# 概要

前回投稿した[Spring Cloudを使ったマイクロサービスシステム構築（シングル構成編）](https://qiita.com/nkoseki/items/928a83608d83a49215d7)の構成もとに、多重構成化する。

##　マイクロサービスの多重化
シングル構成だと、一つのマイクロサービスが停止した場合、そのサービスが利用できなくなる。またある特定のサービスへのアクセスが多い場合、多重化することでサービスを負荷分散できるようになる。

![スクリーンショット 2020-11-28 15.11.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/3202e22f-db65-a38e-a34b-548de736a21d.png)

マイクロサービスのポートが同じなので、異なるサーバにマイクロサービスを構築する。`ms01`と`ms02`のサーバを用意し、それにマイクロサービスを配置する。各サーバで動作するマイクロサービスと受信ポートのイメージは以下のようなもの。

`Service1-#3`はポートを変えるので後で設定する。


![スクリーンショット 2020-11-28 15.13.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/c7c0dacb-7f06-4684-62e3-86e10b97e9d1.png)



### Eurekaの多重化
[Spring Cloudの本家の記事](https://cloud.spring.io/spring-cloud-static/spring-cloud.html)を参考にEurekaを`Peer Awareness`構成にする。
やっていることは、profilesを２つ用意して、それぞれがお互いのEurekaをサーバとして認識することっぽい。

```yml:application.yml
server:
  port: 8761
eureka:
  client:
    registerWithEureka: false
    fetchRegistry: false

spring:
  cloud:
    inetutils:
      preferredNetworks:
        - 10.10.10
---
spring:
  profiles: peer1
eureka:
  instance:
    hostname: ms01
  client:
    serviceUrl:
      defaultZone: http://ms02:8761/eureka/

---
spring:
  profiles: peer2
eureka:
  instance:
    hostname: ms02
  client:
    serviceUrl:
      defaultZone: http://ms01:8761/eureka/
```

Javaのソースコードは前回から変更なしのため必要なら昔の記事を参照。これで`ms01`と`ms02`サーバにそれぞれ配置する。起動の際はどのような条件で起動するか、peerを指定して動作条件を決める。

```shell:ms01サーバで実行
[root@ms01 ~]# java -jar eureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1

```
```shell:ms02サーバで実行
[root@ms02 ~]# java -jar eureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2

```

正しく動作しているか確認。ms01のEureka管理コンソールを見ると、レプリカとしてms02のEurekaが登録されていて正常に登録されているようだ。

![スクリーンショット 2020-11-28 15.24.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/1802091c-6356-8efa-43ef-6781ff3823cf.png)

## Service-1/Service-2のマイクロサービス多重化

Eurekaとほぼ同じ構成になる。サーバ毎に条件を分けるpeer指定がないので記載してないが必要ならpeer指定してサーバ毎に動きを変えることも可能。
サンプルとしてService-1のapplication.ymlの設定を載せるがService-2も読み替えて設定。

```yaml:application.yml
spring:
  application:
    name: app1-service

server:
  port: 8081
  
eureka:
  client:
    serviceUrl:
      defaultZone: http://ms01:8761/eureka/, http://ms02:8761/eureka/
```

## Gatewayの多重化
Gatewayも一緒。

```yaml:application.yml
server:
  port: 8080

eureka:
  client:
    serviceUrl:
      defaultZone: http://ms01:8761/eureka/, http://ms02:8761/eureka/

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
      - id: app1Module
#        uri: http://ms01:8081/ #単体で動かす場合はこれでもOK
        uri: lb://APP1-SERVICE # application:name を指定する
        predicates:
        - Path=/hello/**
      - id: app2Module
#        uri: http://ms01:8082/
        uri: lb://APP2-SERVICE 
        predicates:
        - Path=/goodbye/**
```
## サービスの登録と起動

Service-1/Service-2とGatewayをそれぞれms01,ms02両方のサーバで起動してみる。Eurekaに二重登録されているっぽい。

![スクリーンショット 2020-11-29 16.51.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/9ef94920-95a2-6f3a-1c2c-0f85435473d4.png)

シングル構成の時と同様、マイクロサービスのURLにアクセスすると正常応答が返ってくる。
今回は二重起動しているので、下記それぞれで応答が返ってくる。

```
http://ms01:8080/hello
http://ms02:8080/hello
http://ms01:8080/goodbye
http://ms02:8080/goodbye
```

## ２台のサーバで３多重サービスをする

サーバがms01,ms02の２台でサービスを３多重にしたい場合、ポートを分けて起動する。
例えばService-1をms01で２つ起動する場合、既に8081ポートが利用済みなので、8083ポートで起動できるようにする。

```yaml:application.xml
spring:
  application:
    name: app1-service
server:
  port: 8081  # デフォルトだと8081ポートで起動する
  
eureka:
  client:
    serviceUrl:
      defaultZone: http://ms01:8761/eureka/, http://ms02:8761/eureka/

---
spring:
  profiles: peer1  # peer1のプロファイルを指定して起動すると、8083ポートで起動する
server:
  port: 8083
```

あとは、これを起動するとよい。

```shell
[root@ms01 ~]# java -jar app1-service-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
```

Eurekaの管理コンソールで見てみると、APP1-SERVICEのサービスがms01サーバの8081と8083ポートで動いているのがわかる。他にもms02サーバの8081ポートで動いているので、合計３多重で動いているのがわかる。

![スクリーンショット 2020-11-29 17.57.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/ccf0c3a7-fca1-c2ac-8734-57dfcd091fd6.png)


確認のため、ms01,ms02サーバの8081で動いているAPP1-SERVICEを停止し、ms01サーバの8083ポートでサービスが状態にしても、従来通りのアクセス方法で（つまりポートを意識することなく）アクセス可能。

![スクリーンショット 2020-11-29 18.03.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/218194/ac8af229-fe13-d04f-50a6-ebdcf6d4e1e9.png)

この状態でも従来同様、http://ms01:8080/hello にアクセスすることでAPP1-SERVICEを呼び出せる。

他にも、ms01のサーバ自体を停止させてもシングル構成で動く。