ぱぱっと理解する
Spring Cloudの基本
2017/01/23 JJUGナイトセミナー
はじめに
2
数百件のプロジェクトの基盤を支える社内APフレームワーク
の整備・普及展開をやっています
・熊谷 一生
社内APフレームワークのグローバル展開担当
・JIA XIAOZHOU
社内APフレームワークのクラウド対応担当
自己紹介
3
SIerでAPフレームワークの整備・展開を
やっています
• Spring Cloud傘下の主なプロジェクト
• 最新の動向
• 2017年1月12日 Spring Cloud Camden.SR4 リリース
Spring Cloudとは
4
クラウドネイティブなアプリを作るための
便利なツールの集合体
 Spring Cloud Config
 Spring Cloud Netflix
 Spring Cloud Data Flow
 Spring Cloud Consul
 Spring Cloud Zookeeper
などなど…
参加のプロジェクトがどんどん増え
活発に成長しています
•変化に強いこと
•性能のスケールアウト
•障害に強い
などなど語りだすと奥が深くきりがありません・・・・・・
クラウドネイティブなメリット
5
各メリットごとに奥が深すぎて語り切れない
すべての概念・機能を使いこなすのは時間がかかる
Spring Cloudで・・・
•おさえておきたい基本技術
•使ってみると感じる疑問
を初心者向けに解説していきます
本日のアジェンダ
6
これからクラウドネイティブなアプリを
作りたい人向けに基礎に絞って解説
Spring Cloud
おさえておきたい基本技術
7
8
このパートでは、Spring Cloudの
基本技術を用いたアプリ作成を
ステップ・バイ・ステップで解説します
9
そもそも、Spring Cloudでできることは・・・
10
クラウドネイティブなアプリケーションの作成
クラウドネイティブアプリの特徴
11
小さな単位にアプリに分かれている
(マイクロサービスアーキテクチャ)
Service A
Service B
クライアント
Service C
クラウドネイティブアプリのメリット(1/2)
12
疎結合で変化・機能追加に強い
Service A´
Service B
クライアント
Service C
Service D
Service Dを追加しても
影響箇所が限定される
クラウドネイティブアプリのメリット(2/2)
13
サービスの多重化による
処理性能向上・対障害性向上
Service A
Service B
クライアント
Service C
Service AService AService AService A
処理性能:多数サービスで負荷分散
対障害性:障害時、別サービスが代替
14
今回は最大限簡素化したテーマに沿って
Spring Cloudの基本技術を使ったアプリを作成
今回説明に用いる題材
15
説明のため要素を簡素化した題材で
基本技術を説明します
今回説明に用いる題材
16
説明のため要素を簡素化した題材で
基本技術を説明します
結合した文字列を返す
サービスの作成
題材のサービス構成 (1/3)
17
構成要素①
単純な文字列を返すサービス
りんご
ペン
題材のサービス構成(2/3)
18
構成要素②
ほかのサービスの出力を結合するサービス
りんご
ペン
Uh
他のサービスの出力を結合
題材のサービス構成(3/3)
19
結合した文字列をクライアントに返す
りんご
ペン
Uhクライアント
今回のシナリオ
20
もし爆発的な人気が出て、
世界中から数億のアクセスがあったら・・・
Service Discovery、
Client-side Load Balancing
でサービスの多重化
21
発生しうる問題
22
急激なリクエスト増加によるアクセスの集中
Uh
クライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアント
りんご
ペン
発生しうる問題
23
機能追加による負荷の偏り
Uh
クライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアントクライアント
パイナップル
Uh②
ペン
りんご
24
解決策の一つとしてサービスの多重化
Spring Cloudは容易に多重化出来る
枠組みを提供
Spring Cloudによる負荷分散
25
Eurekaサービスの導入
DNSの様な働き
りんご
ペンUhクライアント
Eureka
サービス
負荷分散の仕組み(1/4)
26
負荷分散のための別のサービスを起動
りんご
ペンUhクライアント
Eureka
サービス
サービスのリスト
ペン-1 ⇒ 192.168.X.Y:80
・・・
・・・
・・・
ペン-2
負荷分散の仕組み(2/4)
27
起動後、自分の情報をEurekaサービスに登録
(Service Registration)
りんご
ペンUhクライアント
Eureka
サービス
ペン-2
サービスのリスト
ペン-1 ⇒ 192.168.X.Y:80
ペン-2 ⇒ 192.168.A.B:80
・・・
・・・
自分の情報
・アプリ名
・IPアドレス
・ポート番号
を登録
負荷分散の仕組み(3/4)
28
要求元はEurekaからサービス一覧を取得
(Service Discovery)
りんご
ペンクライアント ペン-2
Eureka
サービス
サービスのリスト
ペン-1 ⇒ 192.168.X.Y:80
ペン-2 ⇒ 192.168.A.B:80
・・・
・・・
サービスの
一覧リストを返す
Uhサービスのリスト
ペン-1 ⇒ 192.168.X.Y:80
ペン-2 ⇒ 192.168.A.B:80
・・・
・・・
サービスのリスト
ペン-1 ⇒ 192.168.X.Y:80
ペン-2 ⇒ 192.168.A.B:80
・・・
・・・
クライアント
負荷分散の仕組み(4/4)
29
アクセスサーバーを要求元が決定する
(Client-side Load Balancing)
りんご
ペン
Eureka
サービス
ペン-2Uhサービスのリスト
ペン-1 ⇒ 192.168.X.Y:80
ペン-2 ⇒ 192.168.A.B:80
・・・
・・・
決められたロジックで
アクセス先サーバーを分散
負荷に応じた柔軟な多重化が可能
30
「ペン」サービス以外にも
他のサービスも負荷に応じて多重化可能
りんご
ペンUhクライアント
Eureka
サービス りんごりんご
ペンペンペンペン
実際のコーディング
31
1. @EnableEurekaServiceでEurekaサービス作成
2. @EnableEurekaClientでサービス登録
3. @LoadBalancedで負荷分散
多重化を実現する3ステップ
32
りんご
ペンUhクライアント
Eureka
サービス
1. @EnableEurekaServiceでEurekaサービス作成
2. @EnableEurekaClientでサービス登録
3. @LoadBalancedで負荷分散
多重化を実現する3ステップ
33
りんご
ペンUhクライアント
Eureka
サービス
Eurekaサービスプロジェクトの作成
34
①start.spring.io
暗記しましょう!!!
②依存関係に
Eureka Serverを追加
③作成
Eurekaサービスの設定
35
server.port=8761
Application.propertiesの編集
@EnableEurekaServerを追記
Eurekaのデフォルト
のポート番号
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication
{
//…
Eurekaサービスの起動
36
STSのBashboardからSpring Bootアプリ起動
Eurekaサービスの起動確認
37
ブラウザでhttp://localshot:8761にアクセス
Eurekaのダッシュボード
登録されているサービスを確認できる
1. @EnableEurekaServiceでEurekaサービス作成
2. @EnableEurekaClientでサービス登録
3. @LoadBalancedで負荷分散
多重化を実現する3ステップ
38
りんご
ペンUhクライアント
Eureka
サービス
Eurekaクライアントの作成
39
Eureka Discoveryを選択
ソースファイルの編集
40
@SpringBootApplication
@EnableEurekaClient
@RestController
public class AppleApplication {
{
//…
@EnableEurekaClientを追記
設定ファイルの編集
41
server.port=8002
spring.application.name=apple
eureka.client.serviceUrl.defaultZone=
http://localhost:8761/eureka/
①起動ポート
③登録先のEurekaサービス
②アプリ名
application.propertiesの編集
Eurekaクライアントの起動
42
起動するとダッシュボードに
登録されている
サーバー名とポート番号
Eurekaクライアントの複数起動
43
同じアプリ名で複数起動すると
多重度が上がる
1. @EnableEurekaServiceでEurekaサービス作成
2. @EnableEurekaClientでサービス登録
3. @LoadBalancedで負荷分散
多重化を実現する3ステップ
44
りんご
ペンUhクライアント
Eureka
サービス りんご
「Uh」サービスの作成
45
Ribbonを追加
ロードバランシングの有効化
46
@LoadBalanced
@Bean
RestTemplate restTemplate() {
return new RestTemplate();
}
このRestTemplateを介して
負荷分散される
@LoadBlancedを追記
「Uh」の処理の実装
47
@GetMapping("/")
public String getValue() {
return restTemplate.
getForObject(
"http://apple", String.class)
+ " "+ restTemplate.
getForObject(
"http://pen", String.class);
アプリ名で名前解決
1. @EnableEurekaServiceでEurekaサービス作成
2. @EnableEurekaClientでサービス登録
3. @LoadBalancedで負荷分散
多重化を実現する3ステップ
48
りんご
ペンUhクライアント
Eureka
サービス
Circuit Breakerで
障害検知・対応
49
発生しうる問題
50
一か所の障害でサービス全体が
応答しなくなる可能性
りんご
ペン
クライアント
Eureka
サービス
りんご
りんご
ペンペンペン
UhUh
障害発生
応答しない
他サービスへ
影響
51
解決策の一つとして
障害時の既定の動作を定義
障害時は既定の動作を呼び出し
サービス全体としては継続する枠組みを提供
Circuit Breakerの仕組み(1/2)
52
他のサービスの障害を検知
ペン
クライアント
Eureka
サービス
りんご
りんご
ペンペンペン
りんご
UhUh
応答しない
エラーを応答する
りんご
りんご
Circuit Breakerの仕組み(2/2)
53
障害を検知した場合
事前に定義した既定の応答を返す
ペン
クライアント
Eureka
サービス
ペンペンペン
りんご
UhUh
既定の応答
を返す
実際のコーディング
54
1. @EnableCircuitBreakerでCircuitBreakerの有効化
2. @HystrixCommandで障害時の既定動作を定義
Circuit Breakerを実現する2ステップ
55
りんご
ペンUhクライアント
Eureka
サービス
既定の応答
を返す
1. @EnableCircuitBreakerでCircuitBreakerの有効化
2. @HystrixCommandで障害時の既定動作を定義
Circuit Breakerを実現する2ステップ
56
りんご
ペンUhクライアント
Eureka
サービス
Hystrixへの依存性を追加
57
Hystrixを追加
CircuitBreakerの有効化
58
@EnableCircuitBreaker
@EnableEurekaClient
@RestController
@SpringBootApplication
public class UhApplication {
@EnableCircuitBreakerを追記
1. @EnableCircuitBreakerでCircuitBreakerの有効化
2. @HystrixCommandで障害時の既定動作を定義
Circuit Breakerを実現する2ステップ
59
りんご
ペンUhクライアント
Eureka
サービス
既定の応答
を返す
障害時の既定の動作の指定
60
@GetMapping("/")
@HystrixCommand(
fallbackMethod =
"returnDefaultValue")
public String getValue() {
@ HystrixCommandの
fallbackMethod属性に
障害時の呼ばれるメソッドを指定
1. @EnableCircuitBreakerでCircuitBreakerの有効化
2. @HystrixCommandで障害時の既定動作を定義
Circuit Breakerを実現する2ステップ
61
りんご
ペンUhクライアント
Eureka
サービス
既定の応答
を返す
Config Serverで
設定情報の集中管理
62
りんご
発生しうる問題
63
サービスの数だけ設定ファイルが存在
設定変更が大変、不整合の恐れあり
ペンUhクライアント
Eureka
サービス りんごりんご
Uh ペンペンペンペン
64
解決策の一つとして
設定ファイルの集中管理
設定ファイルを集中管理して
各サービスの設定値を更新する仕組みを提供
Config
サービス
設定情報の集中管理
65
gitで設定ファイルの保管
Configサービスで設定ファイルの取次
りんご
ペン
Uhクライアント
Eureka
サービス
りんごりんご
ペンペンペンペンUh
設定情報集中管理の仕組み(1/2)
66
各サービスは起動すると
Configサービスにアクセス
りんご
ペン
Uhクライアント
Eureka
サービス
りんご
ペンペンペンペンUh
りんごConfig
サービス パラメータとして、
・自分のアプリ名
・profile名 (デプロイ環境指定のため)
を渡す
設定情報集中管理の仕組み(2/2)
67
Configサービスはgitから設定情報取得
要求元に返して適用
りんご
ペン
Uhクライアント
Eureka
サービス
りんご
ペンペンペンペンUh
りんごConfig
サービス
①設定情報の取得
③適用
②送付
設定情報の更新
68
設定の更新時でも再デプロイせずに
サービス断続最小限で設定更新することも可能
りんご
ペン
Uhクライアント
Eureka
サービス
りんご
ペンペンペンペンUh
りんご
管理者
Config
サービス
①更新 ②Refresh要求
③設定の再取得
実際のコーディング
69
1. @EnableConfigServiceでConfigサービス作成
2. @EnableConfigClientでConfigクライアント作成
設定集中管理を実現する2ステップ
70
Config
サービス りんご
Uhクライアント
Eureka
サービス
ペン
Config
サービス
1. @EnableConfigServiceでConfigサービス作成
2. @EnableConfigClientでConfigクライアント作成
設定集中管理を実現する2ステップ
71
りんご
Uhクライアント
Eureka
サービス
ペン
Configサービスプロジェクトの作成
72
Config Serverの追加
Gitレポジトリの指定
73
server.port=8888
spring.cloud.config.server.git.uri
=
http://localhost/git/root/config-
files.git
application.propertiesの編集
任意のGitのアドレスを指定
Gitレポジトリへ設定ファイルをPUSH
74
アプリ名.propertiesで
設定ファイルを登録
設定値例
message=apple
Configサービス経由で値取得
75
Configサービスから
設定値が取得可能
http://[ConfigサービスのURI]/アプリ名/default
1. @EnableConfigServiceでConfigサービス作成
2. @EnableConfigClientでConfigクライアント作成
設定集中管理を実現する2ステップ
76
りんご
Uhクライアント
Eureka
サービス
Config
サービス
ペン
Configクライアントの設定
77
Config Client
Actuator
の追加
Configサービスの指定
78
spring.cloud.config.uri=
http://localhost:8888
application.propertiesの編集
Actuator経由で環境変数の確認
79
http://[サービス名]/envにアクセスして
サービスの環境変数を取得する
Configサーバーから
設定値が反映され
messega=apple
となっている
サービス内で設定値の利用
80
@Value("${message}")
private String message;
@Valueアノテーションで値が注入される
@GetMapping("/")
public String getValue() {
return message;
}
1. @EnableConfigServiceでConfigサービス作成
2. @EnableConfigClientでConfigクライアント作成
設定集中管理を実現する2ステップ
81
Config
サービス りんご
Uhクライアント
Eureka
サービス
ペン
Spring Cloudを使ってみて
感じた疑問
82
83
このパートでは、Spring Cloudを使って
感じた疑問とその考えについて
4つを説明します
•問題
• Single point of failure
•実際には、LBの後に複数のConfigインス
タンスをおく場合が多い
1. 設定を集約管理して信頼性は大丈夫?
84
必要に応じて冗長化の必要がある
事象 対処
性能がたり
ない
冗長化
オペミス 運用ルール
•Eureka同士の間に、お互い登録し、常
に情報共有をしている
•障害時、Eureka同士が持ってる情報が
ずれている場合がある
2. Eureka冗長化の考え方
85
Availability > Consistency
(可用性) (整合性)
• Pattern1 Config First Bootstrap
• Pattern2 Discovery First Bootstrap
3. Config First or Discovery First?
86
Config Firstでしょう
Configを
起動
Configから
Eurekaの情報
を取得
Eurekaへ
登録
Eureka
を起動
Configを
Eureka
へ登録
Eurekaから
Configの
情報を取得
Configへ
問合せ
4. EurekaとDNSどう違う?
87
DNSより、Service Registryと負荷分散が
簡単にできること
初期手間 負荷分散
Eureka Annotation Annotation
DNS 事前登録 設定必要
疑問部のまとめ
88
Spring Cloudは入門は簡単だが
深く考えるといろいろな
パターンがあって奥が深く、興味深い
おわりに
89
90
本セッションでは
Spring Cloudの基礎に絞って解説しました
91
JSUGではSpring Cloudの
応用についてはもちろんのこと
様々なSpring技術の勉強会を行っています
• ほぼ毎月開催「Spring勉強会」
• 2016/07/06:Cloud Native Java
• 2016/06/22:Spring CloudとZipkinを利用した分散トレーシング
• 2016/03/09:Microservices /w Spring Security OAuth
• 2016/02/01:Spring Cloud Netflixを使おう
• Springの日本最大級イベント「Spring Day」
• 2016年は24セッションにも及ぶSpring関連技術の講演
Spring Cloudに興味をもたれた方へ
92
JSUGでSpringの勉強会やってます!
最近の
Spring Cloud
関連テーマ
今年もSpring Day やります!
93
Spring Day 2017は
10月中旬(平日)を予定しています
Thank you!

ぱぱっと理解するSpring Cloudの基本