【勉強会】JJUG CCC Fall 2016その1
JJUG CCC Fall 2016
これに行ってきたその1、聞いた編
資料はここ
実録Blue-Green Deployment導入記
グロースエクスパートナーズ 大中浩行さん
日中でのサービス無停止リリース実現の現実解
www.slideshare.net
Blue-Green Deploymentとは
「継続的デリバリー」より引用
本番環境と全く同じ環境を2組用意するという考え方で、それぞれをブルーおよびグリーンと呼ぶ
Blue-Greenの実現方法
環境面
切替方式
- All at once
- 全台を一斉に新しいリビジョンでデプロイ
- One by one
- 1台ずつ新しいリビジョンをデプロイ
- Batch
- 数台ずつ新しいリビジョンをデプロイ
今日の話は、InPlaceのBatch方式(半分ずつアプリ入替)
Blue-Greenに取り組んだ背景
- 当初は夜間にサービス停止でリリース作業
- 海外に顧客が増えて、「夜間」ていつ?となる
- サービス停止を伴うリリースは頻繁にできない
→ BlueGreenに取り組むことに
※最初からBrue-Greenを想定できるなら、最初から設計しておいた方が絶対いい
実現にあたっての課題
課題1.多数の切替ポイント
BlueGreenは、準備さえできれば環境の「切替のみ」でよい←ホント?
- 最小構成ならLB+Blue/Greenにサーバ1台ずつ
- そこに、Blue/Green共用のDBサーバ
- さらに、静的用Webサーバ、認可用リバプロサーバ、外部連携用バッチサーバ、、、
→切り替えポイントがいっぱい、、、
解決策
- 現実解(2016年現在):サーバ群毎に切替
- 本来(MSA本曰く):独立したサービスがそれぞれルーティングを切替
課題2.切替時の動確判定ライン
デプロイ後、プロセス起動確認のみじゃなくて、システムテストもするでしょ
- システムテストに2時間くらい
- つまり、一時的に本番環境に2バージョンが存在する、という状態に
課題3.データベースの存在
サービスインしたままでデータ構造の変更って、どうするの?
GSLB導入(Global Site Load Balancing)
GSLBとは
現実には問題点あり、、
対策
DBマイグレーションツール
原則
- DBスキーマはDBマイグレーションツールでアプリのリリース時に更新
- 新verアプリの作成データを、旧verアプリが参照してもエラーが出ないようにする
- データ構造の互換性を失うようなマイグレーションをしない
- データ構造を変更する場合、新規カラム追加、次回リリースで不要なカラムを削除
問題発生
- で、うまくいくと思ったが、、、
- データ構造を変更しない仕様変更でマスタ更新などあると、旧バージョンがエラーに
対策
- 仕様変更があり得るマスタは、アプリで設定ファイルで持つ
- 「データベースよりファイルでで持つほうが変更がはるかに簡単」(MSA本)
構築第三弾、BlueGreen実現
ロードバランサのルーティング * GlobalIPを主副用意する * 主系がユーザアクセス用、副系が動作確認用
非同期処理の連携 * DBに主副フラグ持たせる * O/RマッパーにInterceptorで、投入するレコードが主か副かわかるようにする
Blue-Greenを支える技術
自動ツール
- LB切替やアプリ切替は自動化しておく
自動テスト
- Gebによる自動E2Eテストを、インフラ観点のシステムテストとして実施
プルリクのレビュー
- インフラ担当がプロダクションコードの修正をレビュー
- 開発担当がデプロイスクリプトをレビュー
- ※現実的には、影響があるところを出し合って補完しあう形
まとめ
- 素早くリリースがDevOpsではない
- Opsの役割はビジネスを実現することである
Event Driven Microservices
Pvotal 槇俊明さん
www.slideshare.net
OrchestrationStyle
HTTP/RESTもシンプルでいいんだけど サービス増えてくると指揮者の負荷が高くなって、メンテも大変 スピードあげたいからMSAなのに、指揮者がボトルネックに Read失敗→HTTPならCircuitBreakerが一般的 Write失敗→HTTPだと対処が限界
ChoreographyStyle
Pub/Subで実装がいい
Spring Cloud Stream
- Event-drivenなMSAフレームワーク
- マイクロサービス間のメッセージングを簡単に実現するためのプロジェクト
- Spring Integrationのマイクロサービス版
- Source|Processor|Sinkモデル(送り元、送り元兼受け皿、受け皿)
- キューにはRabbitMQかkafkaが選べる
Stream Core Features
Persistent Pub-Sub
- パーシステントがつくのは、MessageBorkerがPersistentって話
- 単純にSinkを増やすと、全Sinkに同じデータを投げることになってしまう
- ConsumerGroupの概念
- 複数のSinkをGroupとして扱える、1つ送ってGroup内で分散できる
- Durability
- 相手がダウンしていても溜めておいて、復帰してから渡せる
Partitioning Support(StatefulStream)
- メッセージにIDを付けて、同じIDは同じ送り先に送れる
- Sinkは分散したいけどID毎に集計がしたい、など
Test Support
- 通信先をインメモリ実装にして、独立してテストできる。
Advanced Topics
Multi Binding
メッセージの種類が違う場合、違うキューを用意して別々に送れる Genericに実装してもいいけど。
Spring Cloud Sleuth
- サービスが増えてくると、どこで何が起きているかわからなくなる
- Sleuthを入れると、TraceID/SpanIDで、始点から終点までを追える
- Zipkinに送ってくれる
- タイムラインでいつどこで何が起きたか見れる
- 送られた情報をもとに連携図も自動生成可能
Error Handling
- Dead-Letter Queue Processing
- エラーの(死んだ)メッセージはエラー用のキューに
- リトライしたり、破棄したり
ConsumerDriven Contracts
- マイクロサービスでは、送る側が受ける側を意識しなくなる
- 送る側の変更が、受ける側に思わぬ影響を出すことも
- 受ける側が、受取可能なデータの規約を提示
- 送る側は、各Contractに従うことで、不用意なエラーを防ぐ
- 受ける側からテストコードを送る側に。AcceptanceTestに利用。
- 送る側のテストコードを受ける側に。UnitTestに利用。
- Spring Cloud Contract
その他キーワード
- CQRS
- Event Sourcing
- Spring Cloud Data Flow
- http://bit.ly/making_ccc_a3(サンプルソース)
DDD & Spring Cloud
楽天 椎葉光行さん
境界づけられたコンテキスト
- いろんなコンテキストを1つのモデルに集約しすぎると手に負えなくなる
- モデルを小さく保つことでシステムの複雑さを抑える
- 同じ「商品」データも、「注文」「在庫」「決済」、、それぞれで違う
ユビキタス言語
会話-モデル-コードまで、同じ言葉にできる
リポジトリ
Domain Logicは凝縮させて、できるだけRepositoryに寄せる