楽天トラベルとSpring(Spring Day 2016)

135
楽天トラベルとSpring Nov/18/2016 Takahiro Fujii / Thomas Ludwig Travel Service Development Department, Rakuten Inc

Transcript of 楽天トラベルとSpring(Spring Day 2016)

Page 1: 楽天トラベルとSpring(Spring Day 2016)

楽天トラベルとSpring

Nov/18/2016Takahiro Fujii / Thomas LudwigTravel Service Development Department, Rakuten Inc

Page 2: 楽天トラベルとSpring(Spring Day 2016)

自己紹介 – Takahiro Fujii

藤井貴浩(@taka_ft)トラベルサービス開発・運用部

Hotel Booking チームAssistant manager

仕事・ 海外ホテル関連システム・ インバウンドサイトの開発・ コネクティビティ・ 予約システムの開発・ 最近はフロントエンド

趣味・ Design・ Web Design・ Basketball

Page 3: 楽天トラベルとSpring(Spring Day 2016)

自己紹介 – Tommy Ludwig

Tommy Ludwig (@TommyLudwig)トラベルサービス開発・運用部

Booking Platformチーム

仕事Walt Disney Parks & Resorts

・ 予約システムの開発Rakuten (現在)

・ 楽天トラベルの予約システムの開発

Open source• Spring Boot• Spring Session

撮影者:藤井貴浩 (Spring One 2015)

• Zipkin

Page 4: 楽天トラベルとSpring(Spring Day 2016)

Past Slides

• Spring REST Docsを利用して鮮度の高いDocumentを運用しよう

• Cloud Native:PaaS編 / Spring Cloud at Netflix

• Spring CloudとZipkinを利用した分散トレーシング

• JSUG SpringOne Platform 2016 報告会 - New in Spring Data

• SpringOnePlatform 2016報告会 Case study

Page 5: 楽天トラベルとSpring(Spring Day 2016)

Agenda

• 楽天トラベルの説明

• 楽天トラベルのarchitectureの変化

• 直面した課題と解決へのアプローチ

Page 6: 楽天トラベルとSpring(Spring Day 2016)

直面した課題と解決へのアプローチ

• APIドキュメントを継続して最新の状態を維持するには

• シンプルにセッションを管理するために

• 同じプロパティの値を複数のアプリでそれぞれ管理したくない

• Microservice化する中でログの追跡を可能にするには

• メンバーに使って欲しいライブラリを使ってもらうには

• もっと簡単にAPIを実装する為に

• 新しく来た人にSpringの色々を覚えてもらうには

Page 7: 楽天トラベルとSpring(Spring Day 2016)

楽天トラベルの説明

Page 8: 楽天トラベルとSpring(Spring Day 2016)

本セッションでは、楽天トラベルのシステム開発についてお話しさせて頂きます。楽天では、各サービス(カンパニー)毎でシステム設計が異なります。今回は、楽天トラベルというサービスにおいて、Springをどのように利用している/したいというお話しになります。

本日お話しする楽天のシステムについて

楽天市場 楽天銀行楽天証券

Page 9: 楽天トラベルとSpring(Spring Day 2016)

共通系のサービスは基本的に横断で管理

決済Platform

広告Platform

メールPlatform

会員Platform

楽天市場

Page 10: 楽天トラベルとSpring(Spring Day 2016)

楽天トラベルとJava• 楽天トラベルでは、メイン言語の1つとしてJavaを利用。

• 古くはStruts, SAStruts, Seasar等のフレームワークを利用していましたが、約5年前からSpringを利用し始めました。

• 現在では、自部署のJavaアプリケーションの多くがSpring, SpringBootを利用しています。

• 部署の開発環境・サービスに興味がある方は2年前の弊社カンファレンスでの発表資料をご覧ください。※ある程度古い為、現在の状態とは異なる場合があります。

Page 11: 楽天トラベルとSpring(Spring Day 2016)

サービス• ユーザサービス

– 楽天トラベルのサイトを構成するプロダクト

• 施設向けサービス(管理画面)– 楽天トラベルで商品を販売される

– クライアント(ホテル・レンタカー会社・バス会社など)向けのシステムのプロダクト

• 社内向けサービス

• 共通系サービス– 決済・会員・ポイント・広告・通知・メールなど

– 横断系の部署でサービス(市場・トラベル・金融系)を跨いで管理されるものが多い

Page 12: 楽天トラベルとSpring(Spring Day 2016)

楽天トラベルのarchitectureの変化

(ダイジェスト版)

Page 13: 楽天トラベルとSpring(Spring Day 2016)

国内ホテル 海外ホテル 航空券 レンタカー バス

施設管理画面

インバウンド外言語サイト

DP(ホテル+航空券)

etc…

Page 14: 楽天トラベルとSpring(Spring Day 2016)

HugeMonolithic

App

Page 15: 楽天トラベルとSpring(Spring Day 2016)

海外ホテル

Page 16: 楽天トラベルとSpring(Spring Day 2016)

MonolithicApp

MonolithicApp

MonolithicApp

Page 17: 楽天トラベルとSpring(Spring Day 2016)

施設ページ

(海外ホテル)

予約(海外ホテル)

検索(海外ホテル)

Page 18: 楽天トラベルとSpring(Spring Day 2016)

Front-EndApp

Front-EndApp

Front-EndApp

Back-EndApp

Back-EndApp

Back-EndApp

Page 19: 楽天トラベルとSpring(Spring Day 2016)

施設ページFront

予約Front

検索Front

施設API

予約API

検索API

Page 20: 楽天トラベルとSpring(Spring Day 2016)

国内ホテル 海外ホテル 航空券 レンタカー バス

施設管理画面

インバウンド外言語サイト

DP(ホテル+航空券)

etc…

Page 21: 楽天トラベルとSpring(Spring Day 2016)

似てるAPIができてる

国内ホテル

海外ホテル

予約API 1

予約API 2

Page 22: 楽天トラベルとSpring(Spring Day 2016)

分割と再構築

予約API1

予約(情報)

通知

決済(共通基盤)

在庫

予約API2

管理画面

・予約のドメインモデルを今一度理解する・予約するという行為を分解して共通化

Page 23: 楽天トラベルとSpring(Spring Day 2016)

Front-EndApp

Front-EndApp

Front-EndApp

Back-EndApp

Back-EndApp

Back-EndApp

Back-EndGeneric

App

Back-EndGeneric

App

Back-EndGeneric

App

Back-EndGeneric

App

Page 24: 楽天トラベルとSpring(Spring Day 2016)

予約Front1

予約Front2

Front-EndApp

予約API1

予約API2

Back-EndApp

通知API

決済API

施設情報API

Back-EndGeneric

App

Page 25: 楽天トラベルとSpring(Spring Day 2016)

予約Front1

予約Front2

Front-EndApp

予約API1

予約API2

Back-EndApp

通知API

決済API

施設情報API

Back-EndGeneric

App

Page 26: 楽天トラベルとSpring(Spring Day 2016)

予約API 1? 2?(もちろん本当はそんな名前ではないです笑)

Page 27: 楽天トラベルとSpring(Spring Day 2016)

予約するという(行為)は共通

国内ホテル

海外ホテル

航空券 レンタカー バス

予約する

Page 28: 楽天トラベルとSpring(Spring Day 2016)

分割と再構築

予約API1

予約(情報)

通知

決済(共通基盤)

在庫

予約API2

管理画面

Page 29: 楽天トラベルとSpring(Spring Day 2016)

分割と再構築

予約予約(情報)(REST)

通知(REST)

決済(共通基盤)

在庫(REST)

・行為として共通かできるものはできるだけ共通化する(したい)・機能を分割するだけではなく、同じにできるものは一つにしていく

・RESTfulに出来るならRESTfulに。APIを作るときは扱うリソースを意識する・BFF的なものを薄くする

管理画面

Page 30: 楽天トラベルとSpring(Spring Day 2016)

・APIの総数が増えてきた(新しいリソースの誕生・既存の機能の分割)

・APIの生まれ変わりが激しくなってきた(足りないAPIを作るから、最適なAPIを作るに)(APIをRESTfulに近づけていったり) +人も増えてきた

Page 31: 楽天トラベルとSpring(Spring Day 2016)

すると、多くの問題が(より)顕在化しました。

Page 32: 楽天トラベルとSpring(Spring Day 2016)

Issues

• APIの使い方がすぐには分からない

• セッション管理をもっと簡単にできないっけな、、

• アプリが増えてきて、プロパティファイルの変更が面倒…

• ログの追跡が面倒

• もっと簡単にAPIを実装できないっけな、、

• + 新しく来た人にSpringの色々を覚えてもらうのにコストがかかるな…

Page 33: 楽天トラベルとSpring(Spring Day 2016)

直面した課題と解決へのアプローチ

• APIドキュメントを継続して最新の状態を維持するには

• シンプルにセッションを管理するために

• 同じプロパティの値を複数のアプリでそれぞれ管理したくない

• Microservice化する中でログの追跡を可能にするには

• メンバーに使って欲しいライブラリを使ってもらうには

• もっと簡単にAPIを実装する為に

• + 新しく来た人にSpringの色々を覚えてもらうには

Page 34: 楽天トラベルとSpring(Spring Day 2016)

直面した課題と解決へのアプローチ

• APIドキュメントを継続して最新の状態を維持するには

• シンプルにセッションを管理するために

• Microservice化する中でログの追跡を可能にするには

• 同じプロパティの値を複数のアプリでそれぞれ管理したくない

• メンバーに使って欲しいライブラリを使ってもらうには

• もっと簡単にAPIを実装する為に

• 新しく来た人にSpringの色々を覚えてもらうには

Page 35: 楽天トラベルとSpring(Spring Day 2016)

Issue

APIの使い方習得するのに時間がかかる

「なんでこのAPIこんなに使うの大変なんだ…」「挙動がよく分からない…」「このパラメータの意味が、、」

Page 36: 楽天トラベルとSpring(Spring Day 2016)

API Documentation

• Documentが嘘をついている– 実際にデプロイされているものと異なる

– プロダクトの仕様変更を追えてない・更新漏れ

「このAPI, Documentに書いてある通りに呼ぶとエラーが返ってくるんだけど…??」

「ごめん、Documentには反映出来てないんだけど、最近API更新して、この項目にはこの値をセットすること

になったんだ」

Consumer Producer「まじか」

API利用者 API提供者

Page 37: 楽天トラベルとSpring(Spring Day 2016)

API Documentation

• APIのExampleの不足– 1パターンのRequest/Responseのサンプルしかない

– ※少ないExampleでAPIの使い方がConsumerに迷いなく伝わるべきではある

「このAPI、複数部屋の予約するときってこのこの項目のレスポンスの値ってどうなる?

Documentになかったんだけど」

「お疲れ様です。前に自分が送ったときのサンプルがあるので、見つけて送りますね。」

(そこきたかー)

「ありがとうございます。(たまに忘れられる)」Consumer

API利用者

Producer

API提供者

Page 38: 楽天トラベルとSpring(Spring Day 2016)

API Documentation

• 開発中のプロダクトのドキュメントが無い– DEV/STGなどにdeployされているAPIが本番と異なる仕様の場合の把握が難しい

「DEV環境の**API動いてなくない?」

「あ、今PJTで改修していて、インタフェースを変

更しています。○○にこの項目を追加してもらえれば呼べますよー」

「ありがとうございます・・・」Consumer

API利用者

Producer

API提供者

Page 39: 楽天トラベルとSpring(Spring Day 2016)

API Documentation

• 適正・役割・管理の問題– Documentの品質の不安定さ(ルールがなく、プロダクト担当のエンジニアに品質が依存する、特にエンジニアでは得手・不得手は結構はっきり分かれる)

– Documentを書く係の人なんていない(特に内部API)

– Documentが大切なのはみんな(たぶん)分かってる、が整備することができない(特に更新・維持)

「Document書くのはエンジニアの仕事じゃないんじゃないかな…」「そうでなくとも、Document書くの苦手・・」

「あの人の書くコードは分かりやすいんだけど、Documentが何言ってるか分からない…」

Developer1 Developer2「これリリースしたらあそこのDocument更新しないと・・・」(忘れる)何回か忘れると維持するモチベーションがなくなる

Page 40: 楽天トラベルとSpring(Spring Day 2016)

API Documentation(あとで見てね)• Issues

– APIの使い方のキャッチアップに時間が掛かる(生産性の低下)– Documentが嘘をついている(実際にデプロイされているものの仕様変更を追えてない・更新漏れ)– Documentの品質の不安定さ(ルールがなく、プロダクト担当のエンジニアに品質が依存する、特にエンジニ

アでは得手・不得手は結構はっきり分かれる)– Documentを書く係の人なんていない(特に内部API)– Documentが大切なのはみんな(たぶん)分かってる、一方でなかなか整備することができない(特に更新・維

持)– APIでカバーされている機能の領域が不明瞭(機能がかぶるAPIが他につくられたり、使えると思ったAPIが

機能足りてなかったり、思っていたのとちょっと違うということがAPIを使い始めてから分かったり)– APIのExampleの不足(1パターンのRequest/ResponseのサンプルしかないAPIなど)– 開発環境・QA環境で動いているプロダクトのドキュメントがない(今動いているプロダクトのドキュメントが環

境毎にほしい)– APIのRoll(Vision)が不明瞭で、ある機能を作成するのに、新規のAPIを作成するべきか、既存の機能を改修

するべきか悩むことがある– 古いシステム、日本語サイト用の仕様が日本(語)に依存するところがあったりして、英語でちゃんとドキュメ

ントを書いておかないと日本(語・文化)に詳しくない人には分かりにくい仕様がある– (昔の話ですが)似ているけど違う、他のチームのAPIだと連携に時間がかかったりすることが理由の一端と

なり、機能がかぶるAPIが作成された– サービス設計者が必要なリソースを取得するのに利用するAPIをすぐに特定できない

Page 41: 楽天トラベルとSpring(Spring Day 2016)

API Documentation Tool

http://swagger.io/

{ }…Swagger

RAML

http://raml.org/

SpringREST Docs

https://projects.spring.io/spring-restdocs/

etc...

Page 42: 楽天トラベルとSpring(Spring Day 2016)

API Documentation Tool

https://projects.spring.io/spring-restdocs/

etc...

今日は、

Spring REST Docsについて話します。

Page 43: 楽天トラベルとSpring(Spring Day 2016)

Spring REST Docs

こんな感じのDocumentが作れます。

Page 44: 楽天トラベルとSpring(Spring Day 2016)

Spring REST Docs

自動生成

自動生成

Page 45: 楽天トラベルとSpring(Spring Day 2016)

API Documentation Tool

src/test/javaの下に

*Documentation.javaというクラスを作成します。※Document対象となるクラス名のルールは変更可能

spring mvc testのテストコードに、documentするためのmethodを追加するようなイメージ※REST Assuredでもできます

Page 46: 楽天トラベルとSpring(Spring Day 2016)

Actual code(Sample)

Build

この3つの.adocファイルがビルド時に生成される(デフォルト)

※ここを変更するとdocumentが

できるディレクトリを分けられます

Page 47: 楽天トラベルとSpring(Spring Day 2016)

adocって?

[source,bash]

----

$ curl 'http://localhost:8080/greeting?name=takahiro' –I

----

[source,http]

----

GET /greeting?name=takahiro HTTP/1.1Host: localhost

----

[source,http]----HTTP/1.1 200 OKContent-Type: application/json;charset=UTF-8Content-Length: 37{"id":1,"content":"Hello, takahiro!”}----

curl-request.adoc

http-request.adoc

http-response.adoc

adocを直接開くとこんな感じです。

Page 48: 楽天トラベルとSpring(Spring Day 2016)

adocって?

curl-request.adoc

http-request.adoc

http-response.adocadd-on,plugin

firefox : https://addons.mozilla.org/ja/firefox/addon/asciidoctorjs-live-preview/

chrome : https://chrome.google.com/webstore/detail/asciidoctorjs-live-

previe/iaalpfgpbocpdfblpnhhgllgbdbchmia

sublime : https://github.com/asciidoctor/sublimetext-asciidoc

atom : https://github.com/asciidoctor/atom-asciidoc-preview

対応しているブラウザ/ソフトで開くとこんな感じに表示されます。

Page 49: 楽天トラベルとSpring(Spring Day 2016)

Spring REST Docsって何してくれるの?

http://projects.spring.io/spring-restdocs/

snippet : 切れ端・断片

> Document RESTful services by combining hand-written documentation with auto-generated snippets produced with Spring MVC Test.

Page 50: 楽天トラベルとSpring(Spring Day 2016)

SpringRESTDocsは

snippets(断片)

を自動生成してくれるもの

Page 51: 楽天トラベルとSpring(Spring Day 2016)

snippetsの親は自分で用意

Page 52: 楽天トラベルとSpring(Spring Day 2016)

親adoc

src/main/asciidocの下に

*.adocというファイルを作成します。

api-guide.adocの中で、SpringRESTDocsで生成したsnippetsをincludeすることができます。

Page 53: 楽天トラベルとSpring(Spring Day 2016)

Spring MVC Test

1.SpringRESTDocsが部品(snippets)を作ってくれる(with SpringMVCTest)2. snippetsをincludeする.adocファイルを作ると、ビルド時に指定した形式に変換してくれる

SpringREST Docs

*-request.adoc

*-response.adoc*Documentation.java

api-guide.adoc

Asciidoctor

api-guide.html

snippets

*-request.adoc

*-response.adoc

Page 54: 楽天トラベルとSpring(Spring Day 2016)

targetフォルダ

targetの中にできるので、例えばJenkinsとかのbuildからドキュメントが参照できる

api-guide.html

appname.jar

アプリの中にドキュメントを組み込み、アプリ配下にドキュメントページ

を組み込める

api-guide.html

Page 55: 楽天トラベルとSpring(Spring Day 2016)

Why Spring RESTDocs for us now

テスト成功

Create document

start

end

false

true

・Documentの正確性が保証されることが大切だった(テストコードからDocumentを作る・テストが通らないとDocumentは生成されない)

・継続的な更新が仕組みとして提供される

・Documentをアプリに内包出来るので、各環境にデプロイされているアプリのDocumentが提供される

・Documentを作成するのに、テストコード側の修正しかいらない

・エンジニアはテストコードかける(テストコードを書く感覚で、APIを使うのに必要なサンプルケースはまず間違いなく揃うとかも)

・Hypermediaに対応してる

Page 56: 楽天トラベルとSpring(Spring Day 2016)

How we use Spring RESTDocs

• 利用促進/簡単に使ってもらえるためにabstruct classを提供(jarで + SpringInitializr経由で配布(後述))

• DefaultでアプリにDocumentがincludeされるようにする

• EndPointを統一

• Method名でsnippetが作られるように

• alwaysDo入れておいて、コード書く側は何も考えず(いや、考えるんですが)テスト書いたらsnippetsが出来るような状態

Page 57: 楽天トラベルとSpring(Spring Day 2016)

How we use Spring RESTDocs

@Beforepublic void setUp() {

this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).apply(documentationConfiguration(this.restDocumentation)).alwaysDo(document("{method-name}/{step}/")).build();}

http://docs.spring.io/spring-restdocs/docs/current/reference/html5/

Page 58: 楽天トラベルとSpring(Spring Day 2016)

How we use Spring RESTDocs

this.mockMvc.perform(delete("/entry?parameter=hoge")).andExpect(status().isOK());

http://docs.spring.io/spring-restdocs/docs/current/reference/html5/

→ Snippetsが作成される

Page 59: 楽天トラベルとSpring(Spring Day 2016)

API Documentation

• 結果

– APIの使い方のキャッチアップに時間がかなり減った

– Documentが嘘をつかなくなった

– サンプルが充実(API console無いのが、少し悩ましい)

– アプリに内包、URIを統一することで、誰もが簡単に各環境で動いているアプリのdocumentを閲覧できる

– 他のチームのエンジニアに喜ばれた(嘘をつかない安心の価値が高かったと思う)

Page 60: 楽天トラベルとSpring(Spring Day 2016)

API Documentation• 所感

– 正しいDocumentが当たり前にある最初の一歩としてSpring REST Docsは良かった。

– もっと色々なことをやりたくなったら変えるかも(Swagger+Springfox/RAMLで作られているプロダクトもあります)

– 実際に使えるデータを使ったDocumentを作れないかなー– version差分を自動生成できないか。あるいはDocumentationのversioning– 基本的にテストコードだけいじればDocument作れるので、進めやすかった– Document作成より、REST DocsでDocument作るタスクの方がモチベートできそうな肌感覚

– API Documentを作りはじめるのに、REST Docsは少ない工数で始められた– トップダウンのときどうしようかな– 今回のDocumentationの範疇ではないが、1アプリのDocumentではないものについて(依存関係は可視化すれば十分?)

Page 62: 楽天トラベルとSpring(Spring Day 2016)

直面した課題と解決へのアプローチ

• APIドキュメントを継続して最新の状態を維持するには

• シンプルにセッションを管理するために

• Microservice化する中でログの追跡を可能にするには

• 同じプロパティの値を複数のアプリでそれぞれ管理したくない

• メンバーに使って欲しいライブラリを使ってもらうには

• もっと簡単にAPIを実装する為に

• 新しく来た人にSpringの色々を覚えてもらうには

Page 63: 楽天トラベルとSpring(Spring Day 2016)

SESSION管理

Session management

Page 64: 楽天トラベルとSpring(Spring Day 2016)

Session管理

• セッション毎にデータを持ちたい(買い物かごやCSRFトークンなど)

• applicationのインスタンスをスケールしたい

• 標準のServlet APIを使い続けたい

– HttpServletRequest

– HttpSession

Page 65: 楽天トラベルとSpring(Spring Day 2016)

3つの解決方法

• Sticky sessions

• (アプリケーションサーバの)Session replication

• Spring Session

Page 66: 楽天トラベルとSpring(Spring Day 2016)

Sticky sessions

UsersApplication

instances

Session

dataバランサー

Page 67: 楽天トラベルとSpring(Spring Day 2016)

Sticky sessions

UsersApplication

instances

Session

dataバランサー

Page 68: 楽天トラベルとSpring(Spring Day 2016)

Sticky sessions

UsersApplication

instances

Session

dataバランサー

Page 69: 楽天トラベルとSpring(Spring Day 2016)

Session replication

同期

同期

同期

UsersApplication

instances

Session

dataバランサー

Page 70: 楽天トラベルとSpring(Spring Day 2016)

Session replication

同期

同期

同期

UsersApplication

instances

Session

dataバランサー

Page 71: 楽天トラベルとSpring(Spring Day 2016)

Session replication

同期

UsersApplication

instances

Session

dataバランサー

Page 72: 楽天トラベルとSpring(Spring Day 2016)

Session clustering (Spring Session)

Data store cluster

UsersApplication

instances

Session

dataバランサー

Page 73: 楽天トラベルとSpring(Spring Day 2016)

Session clustering (Spring Session)

Data store cluster

UsersApplication

instances

Session

dataバランサー

Page 74: 楽天トラベルとSpring(Spring Day 2016)

Session clustering (Spring Session)

Data store cluster

UsersApplication

instances

Session

dataバランサー

Page 75: 楽天トラベルとSpring(Spring Day 2016)

解決方法の比較

方法 メリット デメリットSticky sessions バランサーの設定だけ

で済むHAではない

ASのSession replication

HA 設定・実装はASに依存する

Spring Session • HA• AS問わず利用可能• REST/WebSocket

必要なdependencyが増える?

Page 76: 楽天トラベルとSpring(Spring Day 2016)

Spring Session

• Servlet Filterで標準のHttpSessionをwrapする

• Sessionのデータストア(SessionRepository)

– Redis

– Hazelcast

– JDBC

– Mongo

– GemFire

Page 77: 楽天トラベルとSpring(Spring Day 2016)

Spring Session

• Spring Boot 1.4からAuto-configがある

– See Spring Boot documentation

–例えば

• Spring SessionとHazelcastをクラスパスに入れて

• spring.session.store-type=hazelcast

• Spring Bootでない場合は

– @EnableHazelcastHttpSession

Page 78: 楽天トラベルとSpring(Spring Day 2016)

Spring Session @ Rakuten Travel

• すべてのapplicationはセッション管理が必要というわけではない。

• セッション管理が必要とされるapplicationの一部がSpring Sessionを利用– データストアはHazelcast

– プラスSpring SecurityでCSRFトークン生成・チェック

• 残りはその他のソリューション

Page 80: 楽天トラベルとSpring(Spring Day 2016)

直面した課題と解決へのアプローチ

• APIドキュメントを継続して最新の状態を維持するには

• シンプルにセッションを管理するために

• Microservice化する中でログの追跡を可能にするには

• 同じプロパティの値を複数のアプリでそれぞれ管理したくない

• メンバーに使って欲しいライブラリを使ってもらうには

• もっと簡単にAPIを実装する為に

• 新しく来た人にSpringの色々を覚えてもらうには

Page 81: 楽天トラベルとSpring(Spring Day 2016)

ログ追跡Log correlation with Spring Cloud Sleuth

Page 82: 楽天トラベルとSpring(Spring Day 2016)

問い合わせが来た時のログ調査は手間がかかりすぎる

Q

Issues

QAや他チームのデベロッパ

このリクエストのログが見たいんだけど…

A

呼んでるサービスからもらうわ

A

B〜Fさん、これ調べてくれない?

少々お待ちください!

。。。

F

Page 83: 楽天トラベルとSpring(Spring Day 2016)

Issues

問い合わせが来た時のログ調査は手間がかかりすぎる

全ログを収集して共通の場所から検索できたらええやんか

そうしても、一つのリクエストに関係するログは特定できないぞ

Page 84: 楽天トラベルとSpring(Spring Day 2016)

そんな人にログ追跡が必要ですよ

Page 85: 楽天トラベルとSpring(Spring Day 2016)

ログ追跡とは

• リクエストのstartからendまでの全サービスのログが見たい

• MDCというログの機能を利用し、ユニークIDをログに追加

• そのIDをサービスからサービスへ渡す

Page 86: 楽天トラベルとSpring(Spring Day 2016)

トレーシング用語

• Span –ひとつのサービス(境界)内の処理

• Trace – リクエストのstartからendまでのSpanを含む

Page 87: 楽天トラベルとSpring(Spring Day 2016)

それは分かった!自分のプロジェクトでどうやってするの?!

Page 88: 楽天トラベルとSpring(Spring Day 2016)

Spring Cloud Sleuthで実現

• Spring Bootが前提条件• spring-cloud-sleuth-starter

を追加するだけ

• ログを収集して分析ができる

Page 89: 楽天トラベルとSpring(Spring Day 2016)

それだけ?!

Page 90: 楽天トラベルとSpring(Spring Day 2016)

Sleuth Integrations

• HTTP

(RestTemplate)

• @Async

• @Scheduled

• Messaging

– Spring Integration

• Spring Cloud

– Zuul

– Hystrix

– Feign

• RxJava

• See Documentation

Page 91: 楽天トラベルとSpring(Spring Day 2016)

楽天トラベルでのログ追跡

• ログ追跡はまだ導入し始めた頃です。

• SleuthでIDを生成し、サービス間で伝搬させる

• Logstashでログ収集してElasticsearchに入れる

• Kibanaで簡単にTrace IDなどで検索できる

Page 92: 楽天トラベルとSpring(Spring Day 2016)

楽天トラベルでのログ追跡

• Spring Cloud Sleuthを利用するためにまずはSpring BootじゃないプロダクトをBoot化する

• slf4j・logback・ログフォーマットを統一した上でログ調査がしやすい

–共通コンフィグはSpring Cloud Configにある

Page 93: 楽天トラベルとSpring(Spring Day 2016)

楽天トラベルでのログ追跡

• (既に使っていなければ)Sleuthが対応しているIntegrationsを使うように修正する

• リクエストのフローの中に対応していないサービスがあれば、その先は追跡できなくなってしまう

Page 94: 楽天トラベルとSpring(Spring Day 2016)

直面した課題と解決へのアプローチ

• APIドキュメントを継続して最新の状態を維持するには

• シンプルにセッションを管理するために

• Microservice化する中でログの追跡を可能にするには

• 同じプロパティの値を複数のアプリでそれぞれ管理したくない

• メンバーに使って欲しいライブラリを使ってもらうには

• もっと簡単にAPIを実装する為に

• 新しく来た人にSpringの色々を覚えてもらうには

Page 95: 楽天トラベルとSpring(Spring Day 2016)

Centralized Configuration

Page 96: 楽天トラベルとSpring(Spring Day 2016)

アプリの数が増えてプロパティ変更が辛い

「え、またURL, KEY, **変わるの・・??」

Issues

Page 97: 楽天トラベルとSpring(Spring Day 2016)

Spring Cloud Config

• コンフィグはGitにある– バージョニング– source-controlled

• Config serverはHTTP APIを提供する

• クライアントはclient libraryでそのAPIを呼び、 SpringEnvironmentにコンフィグを追加する

• プロパティを暗号化できる

• 再起動なしでコンフィグのリフレッシュさせることができる

• デフォルトはクライアントからコンフィグをプル

• Gitのコミットたびにプッシュするように変えられる

Page 98: 楽天トラベルとSpring(Spring Day 2016)

VM-03

Local PCVM-01

VM-02

Config Server

Client

Client

Client

Client

JSON

Centralized

Source-controlled

On-the-fly updates

• アプリ共通の値の重複

• 環境共通の値の重複

• デプロイ・再起動なしでプロパティーを変更したい

• どこで実行してもコンフィグが取得できたい

問題

AA

B

C

Actuatorの/refresh endpoint

Git repo

JSONJSON

JSON

Page 99: 楽天トラベルとSpring(Spring Day 2016)

重複の対策

• SpringのProfileで環境別のプロパティを分ける

• 共通のプロパティをグループ化

– 某app、某環境のプロパティ

– 某app、環境共通のプロパティ

– app共通、某環境のプロパティ

– appも環境も共通のプロパティ

Page 100: 楽天トラベルとSpring(Spring Day 2016)

一部のappで共通のプロパティはどうすればいいの?

Page 101: 楽天トラベルとSpring(Spring Day 2016)

一部共通のプロパティ

Issue

• 共通のコンフィグだが、一部のappだけに該当する

• 全appのEnvironmentに入れたくない

Solution

• ”Shared config”を作る

• appのように作成

• Clientでapp nameとshared config nameをspring.cloud.config.nameにコンマ区切りで設定する

• appA,shareAB

Page 102: 楽天トラベルとSpring(Spring Day 2016)

Cloud Config @ Rakuten Travel

• セキュリティ:外からアクセスする必要がないので、アクセス制限で充分

–本番のコンフィグサーバは本番のアプリケーションからしかアクセス出来ない

• パスワードやキーを暗号化してGitに保存して、サーバ側で復号化してクライアントに返す

Page 103: 楽天トラベルとSpring(Spring Day 2016)

Cloud Config @ Rakuten Travel

• 静的ファイルの機能も利用しています!

–ログコンフィグ(logback-spring.xml)

– Hazelcastのコンフィグ(hazelcast.xml)

• SpringのResourceで静的ファイルへのURI

• IDEのauto-completeが使えなくなるのは個人的に悲しいところです。

Page 104: 楽天トラベルとSpring(Spring Day 2016)

直面した課題と解決へのアプローチ

• APIドキュメントを継続して最新の状態を維持するには

• シンプルにセッションを管理するために

• Microservice化する中でログの追跡を可能にするには

• 同じプロパティの値を複数のアプリでそれぞれ管理したくない

• メンバーに使って欲しいライブラリを使ってもらうには

• もっと簡単にAPIを実装する為に

• 新しく来た人にSpringの色々を覚えてもらうには

Page 105: 楽天トラベルとSpring(Spring Day 2016)

Create your scaffold from Spring Initializr

Page 106: 楽天トラベルとSpring(Spring Day 2016)

Issues(Improvement)

API

APIAPI

簡単に

共通化

API

API API

API

API・高品質なAPIを提供するには・Spring周りの機能を使えるように

・社内で共通の仕組み・ルールを適用する・色んなチームがAPIを作る中、最低限共通化したいところが出てきた(ロギングはこのライブラリで等)・毎回同じことやってる…??

Page 107: 楽天トラベルとSpring(Spring Day 2016)

http://start.spring.io/

Page 108: 楽天トラベルとSpring(Spring Day 2016)

https://start.spring.io/ https://github.com/spring-io/initializr

Spring Initializr

Page 109: 楽天トラベルとSpring(Spring Day 2016)

https://start.spring.io/ https://github.com/spring-io/initializr

Spring Initializr

Page 110: 楽天トラベルとSpring(Spring Day 2016)

https://start.spring.io/ https://github.com/spring-io/initializr

Spring Initializr

Page 111: 楽天トラベルとSpring(Spring Day 2016)

https://start.spring.io/ https://github.com/spring-io/initializr

Spring Initializr

Page 112: 楽天トラベルとSpring(Spring Day 2016)

https://start.spring.io/ https://github.com/spring-io/initializr

Spring Initializr

Page 113: 楽天トラベルとSpring(Spring Day 2016)

Spring Initializr• アプリケーションに必要なクラスライブラリ群がセット

されたプロジェクトをサクッと作ることができる

• これを使えば、様々なタイプのアプリをSpringで簡単に、素早く作ることができる。

• 簡単にカスタマイズ可能で、社内で利用しているライブラリをSpring Initializrから設定できるようにすることができる。

Page 114: 楽天トラベルとSpring(Spring Day 2016)

- name: Custom

content:

- name: Jasypt

id: jasypt

description: Provides Jasypt encryption support for property

sources

version: 1.6

groupId: com.github.ulisesbocchio

artifactId: jasypt-spring-boot-starter

Add a custom section(application.yml)

https://github.com/spring-io/initializr/blob/master/initializr-service/src/main/resources/application.yml

下記のファイル一度ご参照ください

自分で3rd partyのライブラリを追加できる(簡単に)社内のプライベートなライブラリを足したりとかも

このymlもclooud-configで管理すると更新が楽

Page 115: 楽天トラベルとSpring(Spring Day 2016)

Spring Initializrのカスタマイズとは

Dependencyに追加できるようになる

Page 116: 楽天トラベルとSpring(Spring Day 2016)

Spring Initializrのカスタマイズとは

IDEからでもカスタマイズしたInitializrを利用することが可能

Page 117: 楽天トラベルとSpring(Spring Day 2016)

Spring Initializr

RakutenTravel Initializr

InternalRepository

PublicRepository

lombok*.jarspring*.jar

rakuten*.jar

customize

Rakuten Travel Initializr

Page 118: 楽天トラベルとSpring(Spring Day 2016)

Spring Initializr

• 会社の環境にあったinitializrの作成が可能。

• 個人やOpenなプロジェクトに限った利用ではなく、各社のSpringアプリケーションのinitializrとしても 利用することができる。

• Spring Initializrを使って、簡単に社内の環境に即したアプリを作ることができる。

• Spring Initializrを使って新規プロジェクトを作るフローにするとある程度使われるライブラリやバージョンの統制がとれる。

Page 119: 楽天トラベルとSpring(Spring Day 2016)

・社内ライブラリを追加する・不要 / 使わせたくないライブラリ(SNAPSHOT等を取り除く)

・Initilizrのconfigをcloud configで管理・defaultのgroupを変更・利用促進中

こんな感じです。

Spring Initializr @ Rakuten Travel

Page 120: 楽天トラベルとSpring(Spring Day 2016)

Easy Consumption of Microservices(SpringOne Platform(2016))・Spring Initializrのカスタマイズについて触れています

Appendix

Page 121: 楽天トラベルとSpring(Spring Day 2016)

・spring-boot-actuatorを導入し、health checkerを自動実装、必要に応じてカスタマイズここのサービス毎にバラバラだったhealth checkを統一している

Appendix (Spring-Boot Actuator)

http://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#production-ready

<dependencies><dependency>

<groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId>

</dependency></dependencies>

Page 122: 楽天トラベルとSpring(Spring Day 2016)

・spring-boot-actuatorを導入し、health checkerを自動実装、必要に応じてカスタマイズ

Appendix (Spring-Boot Actuator)

Initializrでactuatorをチェックすればプロジェクト作ったタイミングからもうhealth checkエンドポイントが実装されている

Page 123: 楽天トラベルとSpring(Spring Day 2016)

直面した課題と解決へのアプローチ

• APIドキュメントを継続して最新の状態を維持するには

• シンプルにセッションを管理するために

• Microservice化する中でログの追跡を可能にするには

• 同じプロパティの値を複数のアプリでそれぞれ管理したくない

• メンバーに使って欲しいライブラリを使ってもらうには

• もっと簡単にAPIを実装する為に

• 新しく来た人にSpringの色々を覚えてもらうには

Page 124: 楽天トラベルとSpring(Spring Day 2016)

Issues・プロダクトも増えれば、人も増えている・最近はインターンの方もたくさん来てくれる

Page 125: 楽天トラベルとSpring(Spring Day 2016)

Issues

みんなが(最初から) Springに詳しいわけではない

:Springちょっとできる

Page 126: 楽天トラベルとSpring(Spring Day 2016)

Issues

教えるのに時間を結構使う

:Springちょっとできる

Page 127: 楽天トラベルとSpring(Spring Day 2016)

https://spring.io/guides

Page 128: 楽天トラベルとSpring(Spring Day 2016)

TRVDD tutorial

New comer 向けチュートリアルをasciidoc使って作りました :)

Page 129: 楽天トラベルとSpring(Spring Day 2016)

TRVDD tutorial

New comer 向けチュートリアルをasciidoc使って作りました :)

Page 130: 楽天トラベルとSpring(Spring Day 2016)

TRVDD tutorialGuideへのリンクがたくさん笑 + 補足

Page 131: 楽天トラベルとSpring(Spring Day 2016)

Result

緑色になる最初の一歩を加速!

+ 僕の素振りとして非常にいい機会に。。

Page 132: 楽天トラベルとSpring(Spring Day 2016)

まとめ

・ APIドキュメントを継続して最新の状態を維持するには(Spring RESTDocs)

・シンプルにセッションを管理するために(Spring Session)

・ Microservice化していく中でログの追跡を可能にするには (Spring Cloud Sleuth)

・同じプロパティの値を複数のアプリでそれぞれ管理したくない(Spring Cloud Config)

・メンバーに使って欲しいライブラリを使ってもらう・scaffoldを提供する(Spring

Initializr)

・ health checkなどの自動実装(Spring Boot Actuator)

・新しく来た人にSpringのいろいろを覚えてもらう(Spring guides)

Page 133: 楽天トラベルとSpring(Spring Day 2016)

まとめ

・ 課題を明確すること/課題に優先度をつけることは大切

解決策として新しい技術が使えるの方が導入しやすいし、結果がわかりやすい

(通常の業務と並行して勧めやすい)

課題に対する解決策として使えるツールがSpring周りに沢山ある。

・ Spring/Microservice周りでもまだまだ出来ることは沢山ある。

やろうとして出来ていないものもかなりある。

(Service Discovery / Circuit Breaker / CQRS / CDC / Event-Driven などなど…)

おまけ

・ ここ1,2年で、様々な会社がSpring Boot/Cloud/ CFなどのケーススタディを紹介するようになったイメージがあります。 ( SpringOne Platformでも色々な所のケーススタディの紹介がありました)

Page 134: 楽天トラベルとSpring(Spring Day 2016)

ケーススタディの情報交換など、大歓迎です。

気軽にお声がけいただけると嬉しいです。

Page 135: 楽天トラベルとSpring(Spring Day 2016)

We are hiring!

Java / Spring 好きな方大歓迎…!!

http://corp.rakuten.co.jp/careers/engineering/

直接お声がけいただいても!