Upload
yahoo
View
1.860
Download
0
Embed Size (px)
Citation preview
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
2017年11月24日
ヤフー株式会社 鴨志田 智弥
Yahoo! JAPANのコンテンツプラットフォームを支える
Spring Cloud Streamによるマイクロサービスアーキテクチャ
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
自己紹介
• 鴨志田 智弥
• ヤフー株式会社 メディアグループ
メディアカンパニー プラットフォーム開発本部
• 経歴
• 2009年 新卒入社
• 2009年〜 Yahoo!ニュース
• 2016年9月〜 コンテンツプラットフォーム
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
アジェンダ
• Yahoo! JAPANとコンテンツ
• コンテンツプラットフォームでのSpringの採用事例
• 既存システムの課題と新システムの設計
• システム概要と詳細
• 良かったこと、悪かったこと
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Yahoo! JAPANとコンテンツ
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Yahoo! JAPANとコンテンツ
天気
試合情報
路線の遅延情報
ニュース
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
提供コンテンツ
• ニュース記事、コラム
• 天気、地震情報
• 株価
• 試合情報、試合のスコア
• 動画
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
コンテンツプラットフォームでの
Springの採用事例の紹介
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
アジェンダ
• Yahoo! JAPANとコンテンツ
• コンテンツプラットフォームでのSpringの採用事例
• 既存システムの課題と新システムの設計
• システム概要と詳細
• 良かったこと、悪かったこと
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
コンテンツプラットフォーム
• 提供コンテンツの入稿・配信のプラットフォーム
• 1stリリースは記事コンテンツがターゲット
• 開発に至った背景
• 旧記事入稿プラットフォームがレガシーなためリニューアル
• 2009年から稼働
• PHP、Perl、C
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
旧システムの辛い所
• 巨大なモノリシックなアプリケーション
• 大きすぎてリファクタリングできない
• さらにテストコードが無い&書きづらい
• その結果レガシーなコードのまま
• 環境や依存のバージョンアップの時はひたすらエラーを潰す
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
旧システムの辛い所2
• 実機&VMで動いている
• マスタ/スタンバイ構成で冗長性有り
• 簡単にスケールアウトできないので常にリソースは確保している
常に確保
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
旧システムの辛い所3
• アーキテクチャが古いのでPaaSなどへの移行は難しい
• IPアドレスに依存していたり
• 処理自体はテキスト処理などで非常にシンプル
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
新システムの設計
• マイクロサービスアーキテクチャ
• システムを細分化して柔軟に対応できるようにしたい
• 同期的に処理しなくて良い部分は非同期で処理したい
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
新システムの設計2
• Java
• プラットフォームなのでなるべく不具合無くリリースしたい
• 静的型付け、コンパイラで検知
PHP Java
インタープリタ型言語動的型付け
コンパイラ型言語静的型付け
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
新システムの設計3
• PaaS
• 運用コストを下げたい
• リソースを有効活用したい
• 重大ニュースなどで負荷が大きく上昇するため素早くスケールアウトした
い
PaaS
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
新システムの設計4
• Spring Boot
• Javaでマイクロサービスするなら鉄板
• フルスタックで機能も豊富
• 社内PaaS環境のPivotal Cloud Foundryとの相性も良い
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
アジェンダ
• Yahoo! JAPANとコンテンツ
• コンテンツプラットフォームでのSpringの採用事例
• 既存システムの課題と新システムの設計
• システム概要と詳細
• 良かったこと、悪かったこと
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
システム構成
レガシーアダプタ旧PF
入稿API
入稿データ(MySQL)
解析処理入稿サービス
ストレージHadoop
処理済みデータ(Cassandra)
バッチ処理用データ保存
データ保存参照サービス
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
システム構成
入稿API
入稿データ(MySQL)
入稿サービス
データ受付確認
データ保存
非同期
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
システム構成
処理済みデータ(Cassandra)
データ保存参照サービス
データ保存更新通知
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
システム構成
ストレージHadoop
バッチ処理用データ保存
ストレージに保存
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
システム構成補足
• 現在約20サービスほど
• オンプレ環境に構築したPivotal Cloud Foundry上で稼働
• Spring Bootと一部Node.js
• 非同期部分はPulsarとSpring Cloud Stream
• MySQL、Cassandra、内製のS3互換ストレージ
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Pivotal Cloud Foundry
• Pivotal社製のCloud Foundry
• PaaS
• コマンド1つでアプリケーションが立ち上がる
$ cf push -p build/libs/hoge-1.0.0.jar
https://hoge.XXXX.yahoo.co.jp/
数分後
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Pivotal Cloud Foundry
Spring Boot Actuator連携
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Apache Pulsar
• Pub-Subメッセージングシステム
• Yahoo! Inc.製で今はApache Incubator
• 特徴
• 高パフォーマンス、高スケーラビリティ
• マルチテナント
• 複数DC間でのレプリケーション
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Spring Cloud Stream
• Springでメッセージングシステムを使うフレームワーク
• 公式ではRabbitMQとKafkaをサポート
• Pulsarは公式ではサポートされていないので内製対応
Producer ConsumerMessage Broker
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Source / Processor / Sink
Source Sink
binder
Processor
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Source / Processor / Sink
レガシーアダプタ旧PF
入稿API
入稿データ(MySQL)
解析処理入稿サービス
ストレージHadoop
処理済みデータ(Cassandra)
バッチ処理用データ保存
データ保存参照サービス
SourceProcessor
Sink
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
依存の追加
ext {
springCloudVersion = 'Dalston.SR4'
}
dependencies {
compile('org.springframework.cloud:spring-cloud-starter-stream-rabbit')
compile('org.springframework.boot:spring-boot-starter-web')
compile('org.springframework.boot:spring-boot-starter-actuator')
testCompile('org.springframework.boot:spring-boot-starter-test')
}
dependencyManagement {
imports {
mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}"
}
}
使うbrokerのものを指定
その他はお好みで
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
依存の追加
RabbitMQの場合org.springframework.cloud:spring-cloud-starter-stream-rabbit
Kafkaの場合org.springframework.cloud:spring-cloud-starter-stream-kafka
Pulsarの場合(自作)com.example:spring-cloud-starter-stream-pulsar
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sourceの実装
@SpringBootApplication@RestControllerpublic class SourceDemoApplication {
@PostMappingpublic void send(@RequestBody Map<String, String> message) {
// ここに送信する処理を書く}
public static void main(String[] args) { 〜略〜 }}
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sourceの実装
@SpringBootApplication@RestController@EnableBinding(Source.class)public class SourceDemoApplication {
@PostMappingpublic void send(@RequestBody Map<String, String> message) {
// ここに送信する処理を書く}
public static void main(String[] args) { 〜略〜 }}
アノテーションを追加
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sourceの実装
@SpringBootApplication@RestController@EnableBinding(Source.class)public class SourceDemoApplication {
@Autowiredprivate Source source;
@PostMappingpublic void send(@RequestBody Map<String, String> message) {
// ここに送信する処理を書く}
public static void main(String[] args) { 〜略〜 }}
インジェクション
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sourceの実装
@SpringBootApplication@RestController@EnableBinding(Source.class)public class SourceDemoApplication {
@Autowiredprivate Source source;
@PostMappingpublic void send(@RequestBody Map<String, String> message) {
source.output().send(MessageBuilder.withPayload(message).build());}
public static void main(String[] args) { 〜略〜 }}
送信処理
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sourceの設定
spring.rabbitmq.addresses=localhost:5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.cloud.stream.bindings.output.destination=foo_topic
spring.cloud.stream.bindings.output.contentType=application/json
broker固有の設定
binderの設定
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
broker固有の設定
spring.rabbitmq.addresses=localhost:5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.cloud.stream.kafka.binder.brokers=localhost
spring.cloud.stream.kafka.binder.defaultBrokerPort=9092
spring.cloud.stream.kafka.binder.zkNodes=localhost
spring.cloud.stream.kafka.binder.defaultZkPort=2181
spring.cloud.stream.pulsar.binder.clusterUrl=pulsar://localhost:6650
RabbitMQの例
Kafkaの例
Pulsarの例(イメージ)
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Source側のbinderの設定
送信先トピックspring.cloud.stream.bindings.output.destination=foo_topic
メッセージのシリアライズ方法spring.cloud.stream.bindings.output.contentType=application/json
JSONがオススメ
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sinkの実装
@SpringBootApplicationpublic class SinkDemoApplication {
public void receive(Map<String, String> data) {// ここに受信したメッセージの処理を書く
}
public static void main(String[] args) { 〜略〜 }}
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sinkの実装
@SpringBootApplication@EnableBinding(Sink.class)public class SinkDemoApplication {
public void receive(Map<String, String> data) {// ここに受信したメッセージの処理を書く
}
public static void main(String[] args) { 〜略〜 }}
アノテーションを追加
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sinkの実装
@SpringBootApplication@EnableBinding(Sink.class)public class SinkDemoApplication {
@StreamListener(Sink.INPUT)public void receive(Map<String, String> data) {
// ここに受信したメッセージの処理を書く}
public static void main(String[] args) { 〜略〜 }}
アノテーションを追加
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sinkの実装
@SpringBootApplication@EnableBinding(Sink.class)public class SinkDemoApplication {
@StreamListener(Sink.INPUT)public void receive(Map<String, String> data) {
System.out.println("Received : " + data.toString());}
public static void main(String[] args) { 〜略〜 }}
処理を書く
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sinkの設定
spring.rabbitmq.addresses=localhost:5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.cloud.stream.bindings.input.destination=foo_topic
spring.cloud.stream.bindings.input.group=bar_group
broker固有の設定
binderの設定
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Sink側のbinderの設定
受信トピックspring.cloud.stream.bindings.input.destination=foo_topic
ConsumerGroup名spring.cloud.stream.bindings.input.group=bar_group
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
ConsumerGroup
設定しない場合はそれぞれに同じメッセージが届く
AAABBBCCC
AAABBBCCC
AAABBBCCC
AAABBBCCC
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
ConsumerGroup
設定した場合はグループ内のどれか1つにだけメッセージが届く
AAABBBCCC
AAA
BBB
CCC
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
メリット
• 抽象化されているのでロジックに集中できる
• 違うbrokerに乗り換える場合は設定の差し替え程度で済む
• Springの他の機能との連携
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Spring Boot Actuator連携
接続先のbrokerのヘルスチェック{
"status": "UP",
〜中略〜"rabbit": {
"status": "UP",
"version": "3.6.12"
},
"binders": {
"status": "UP",
"rabbit": {
"status": "UP",
"binderHealthIndicator": {
"status": "UP",
"version": "3.6.12"
}
}
}
}
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Spring Cloud Streamのテスト
• テストツールが提供されている
• spring-cloud-stream-test-support
Sourceテストコード Sinkテストコード
assert assertモックモック
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
実装後に出てきた課題
• 処理の流れがわかりにくい
• 想定よりスループットが出ない
• エラー時の処理
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
処理の流れがわかりにくい
• マイクロサービスの処理の流れはわかりにくい
• どこでエラーが起きたのか?
• どこがボトルネックになっているのか?
エラー!?
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Spring Cloud Sleuth
リクエストにトレース用のユニークなIDを付与する
ID発行 abc abc abc
X-B3-TraceId: abc
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Spring Cloud Sleuth
• 自動で追跡用のIDが発行・付与
• 自動でログにも出力
• トラブル時はTraceIDで検索すればOK
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Zipkin
レガシーアダプタ旧PF
入稿API
入稿データ(MySQL)
解析処理入稿サービス
ストレージHadoop
処理済みデータ(Cassandra)
バッチ処理用データ保存
データ保存参照サービス
Zipkin
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Zipkin
レガシーアダプタ旧PF
入稿API
入稿データ(MySQL)
解析処理入稿サービス
ストレージHadoop
処理済みデータ(Cassandra)
バッチ処理用データ保存
データ保存参照サービス
①
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Zipkin
レガシーアダプタ旧PF
入稿API
入稿データ(MySQL)
解析処理入稿サービス
ストレージHadoop
処理済みデータ(Cassandra)
バッチ処理用データ保存
データ保存参照サービス
①
②
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Zipkin
レガシーアダプタ旧PF
入稿API
入稿データ(MySQL)
解析処理入稿サービス
ストレージHadoop
処理済みデータ(Cassandra)
バッチ処理用データ保存
データ保存参照サービス
①
②③
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Zipkin
レガシーアダプタ旧PF
入稿API
入稿データ(MySQL)
解析処理入稿サービス
ストレージHadoop
処理済みデータ(Cassandra)
バッチ処理用データ保存
データ保存参照サービス
①
②③
④
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Zipkin
レガシーアダプタ旧PF
入稿API
入稿データ(MySQL)
解析処理入稿サービス
ストレージHadoop
処理済みデータ(Cassandra)
バッチ処理用データ保存
データ保存参照サービス
①
②③
④ ⑤
⑥
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
想定よりスループットが出ない
• 負荷テストしてみたら非同期部分が遅い
• Sinkの同時処理数が1だった・・・
spring.cloud.stream.bindings.input.consumer.concurrency=10
デフォルトは1 適度に増やす
必ず設定する
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
エラー時の処理
• 処理の途中でエラーになったメッセージが行方不明に
• Pulsarは再送までの時間を設定しないと再送してくれな
かった・・・
• brokerの仕様は把握しておくことが大事
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
BCP(事業継続計画)
• 非常災害時でもサービスを継続する必要がある
• 西日本と東日本のDCに分散構築
東日本クラスタ西日本クラスタ
GSLB
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
BCP(事業継続計画)
仮に片方のDCが停止しても問題ないように設計
MySQL
西日本
東日本
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
BCP(事業継続計画)
仮に片方のDCが停止しても問題ないように設計
GSLB
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
BCP(事業継続計画)
仮に片方のDCが停止しても問題ないように設計
MySQL
GSLB
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
BCP(事業継続計画)
仮に片方のDCが停止しても問題ないように設計
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
BCP(事業継続計画)
仮に片方のDCが停止しても問題ないように設計
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
BCP(事業継続計画)
仮に片方のDCが停止しても問題ないように設計
MySQL
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
BCP(事業継続計画)
仮に片方のDCが停止しても問題ないように設計
MySQL
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
利用サービス例
• Yahoo! JAPANアプリ
• ニュースフィード部分などで利用
• Vespaでコンテンツのレコメンデーション
コンテンツ
更新処理Index
アプリBE
更新通知
更新検知&データ取得
インデックス更新
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
アジェンダ
• Yahoo! JAPANとコンテンツ
• コンテンツプラットフォームでのSpringの採用事例
• 既存システムの課題と新システムの設計
• システム概要と詳細
• 良かったこと、悪かったこと
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
Java/Springで良かったこと
• フルスタックで機能も豊富なのでロジックに集中できる
• マイクロサービスに必要なものが揃っている
• テストコードが書きやすい
• Mockito
• MockRestServiceServer
• REST Assured
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
非同期部分は機能拡張が簡単
購読を増やすだけなので既存システムへの影響は少ない
既存アプリケーション
追加アプリケーションこの線を増やせばOK
・・・
・・・
・・・
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
非同期部分は機能拡張が簡単
レガシーアダプタ旧PF
入稿API
入稿データ(MySQL)
解析処理入稿サービス
ストレージHadoop
処理済みデータ(Cassandra)
バッチ処理用データ保存
データ保存参照サービス
実は後から追加
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
1つの機能がシンプル
• 機能が小分けになっているので実装がシンプルに
• APIやメッセージを挟んでいるので疎結合
• 修正やレビューは見る範囲が狭い方が良い
数万行🔥 数百〜数千行☀️
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
1つの機能がシンプル
• 複数人での並行開発も容易
• コンフリクトも起こりにくい
コンフリクト地獄
☀️
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
新たな課題
• メモリの使用量が他の言語に比べ多め
• マイクロサービスの管理が大変
• 便利なソリューションも提供されているが・・・
• 依存ライブラリのバージョンを上げるのも一苦労
• 開発メンバーが少ないのも要因の1つ
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
今後の展望
• Kotlinの検討
• マイクロサービス系のツールのさらなる導入
• 検証が追いつかず導入を見送ったものがいくつかある
• 新しく増えたものも随時検討
• Spring Cloud Skipperなど
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
まとめ
Copyrig ht © 2017 Yahoo Japan Corporation. All Rig hts Reserved .
まとめ
• 既存システムの課題がSpringとマイクロサービスで大きく
改善できた
• マイクロサービスをやるならSpring Cloud Streamが便利