antifragile java - java day tokyo 2017 d1-e1

64
Antifragile Java kawasima Java Day Tokyo 2017 D1-E1 TIS株式会社 川島 義隆

Upload: yoshitaka-kawashima

Post on 22-Jan-2018

3.341 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Antifragile Java - Java Day Tokyo 2017 D1-E1

Antifragile Java

kawasima

Java Day Tokyo 2017D1-E1

TIS株式会社川島 義隆

Page 2: Antifragile Java - Java Day Tokyo 2017 D1-E1

Antifragileリーマンショックで大儲けした

ニコラス・ナシム・タレブの書いた

ブラック・スワンに続くヒット作

(日本語訳は未)

主題は、不確実なことが実際に

起きたときに、大きなゲインを

得ようというもの。

Page 3: Antifragile Java - Java Day Tokyo 2017 D1-E1

Fragile変化に対して弱い・損失が大きい仕組み

● 後戻りの計画・その分の予算確保がないウォー

ターフォールのプロジェクト

● プロビジョニングが十分でないシステム

(ex. 30分 2000PVでダウンする図書館システム)

● 例外のハンドリングが雑なアプリケーション

Page 4: Antifragile Java - Java Day Tokyo 2017 D1-E1

Robust変化に対して、十分強い仕組み(フラジャイルの裏返し)

● よく計画されたウォーターフォールの開発プロジェクト

● 急激なアクセス増や異常なデータファイルに対しても、安全に処理できるアプリケーション

● 例外を適切にハンドリング出来ているコード

Page 5: Antifragile Java - Java Day Tokyo 2017 D1-E1

Resilient大きな変化に対し、一時的にシステムのパフォーマンス

を落としてもすぐに復旧できる仕組み

Page 6: Antifragile Java - Java Day Tokyo 2017 D1-E1

Antifragile変化が起これば起こるほどメリットがある仕組み

ストレスが増せば増すほど強くなる仕組み

そんなことが可能なのでしょうか?

Page 7: Antifragile Java - Java Day Tokyo 2017 D1-E1

Benefit

Change

Cost

Antifragile

ResilientRobust

Fragile

Page 8: Antifragile Java - Java Day Tokyo 2017 D1-E1

Antifragileへの道のり

Page 9: Antifragile Java - Java Day Tokyo 2017 D1-E1

現在の知識で予測しない早期に問題を起こして対処する

1697年まではヨーロッパでは真実だった。

「白鳥は白い」

経験に基づく知識

現在の知識の限界 → 分からないことが分からない

Page 10: Antifragile Java - Java Day Tokyo 2017 D1-E1

<%@ page contentType="text/html; charset=UTF-8"%>

クローラやDDoS攻撃を受けない環境で開発し

てきた人にとっては、問題が予測できない

<%@ page contentType="text/html; charset=UTF-8" session="false"%>

不特定多数がアクセスできるサイトでは、本来セッションを使わない

ページでも、空セッションが作られメモリを圧迫する。

Page 11: Antifragile Java - Java Day Tokyo 2017 D1-E1

Five Orders of Ignorance0OI: 全部分かっている

「答え」を持っている。あとは書き写すだけで完成する。

1OI: 分からないことが分かっている

答えを得るための「質問」を持っている。

2OI: 分からないことが分からない

「質問」を持たない状態。決定的な答えを引き出すための「質問」ができない。

3OI: 分からないことが分からない状況を何とかする術を知らない

2OI 1OI 0OI→ → と進んでいくためのプロセスがない状態です。

4OI: 無知にレベルがあることを知らない

http://qiita.com/seki_uk/items/4001423b3cd3db0dada7

Page 12: Antifragile Java - Java Day Tokyo 2017 D1-E1

2OIには予測できないBlack Swanが潜む

どうやってBlack Swanを見つけるか?

Page 13: Antifragile Java - Java Day Tokyo 2017 D1-E1

Bricolage(ブリコラージュ)プロダクトを組合せたり分解したりして

いじくり回し(Tinkering)新しい価値を生み出す

http://aisel.aisnet.org/cgi/viewcontent.cgi?article=1027&context=icis1991

トップダウンアプローチ ボトムダウンアプローチ

アレコレ試してるうちに

イノベーションが産まれる可能性が

あることを認めよう

突飛なアイデアは出にくい

Page 14: Antifragile Java - Java Day Tokyo 2017 D1-E1

GameDay消防士の災害訓練みたいなもの

● 実際の重障害発生をシミュレートして対応にあたる

● Amazonで始められ、Google、Yahoo、Netflixなどで同様に実施されている。

Page 15: Antifragile Java - Java Day Tokyo 2017 D1-E1

失敗を避けるのではなく失敗を前提としてシステムを設計する

Availability := MTTFMTTF + MTTR

https://www.slideshare.net/ufried/patterns-of-resilience

Werner Vogels(Amazon CTO): “Everything fails all the time”

MTTFを長くする → Robust

MTTRを短くする → Resilient

Page 16: Antifragile Java - Java Day Tokyo 2017 D1-E1

Minimize MTTR検知

原因解析

修正

テスト

デプロイ

それぞれのフェーズを

短くする

Page 17: Antifragile Java - Java Day Tokyo 2017 D1-E1

Antifragile System

Page 18: Antifragile Java - Java Day Tokyo 2017 D1-E1

レジリエントAntifragile

Resilient

Robust

Robust無きResilientの追求はFragileResilient無きAntifragileの追求はFragile

Antifragileは1日にしてならず。

まずResilientを目指そう

Page 19: Antifragile Java - Java Day Tokyo 2017 D1-E1

レジリエントの教科書

Page 20: Antifragile Java - Java Day Tokyo 2017 D1-E1

Timeout● Socket#connect● SocketInputStream#read(privateメソッドのため、実際はSO_TIMEOUTで指定する)

● Object#wait● Process#waitFor● Future#get● BlockingQueue#poll● …

スレッドをブロックする呼び出しは必ずタイムアウトを考えよう

Resilient

Page 21: Antifragile Java - Java Day Tokyo 2017 D1-E1

Retry● 冪等性に注意

(POSTリクエストのSocket Timeoutはリトライすると

二重処理される可能性がある)

● Timeoutした処理はすぐリトライしても、失敗する可

能性が高い

無闇なリトライはリソースを無駄に喰うだけ

Resilient

Page 22: Antifragile Java - Java Day Tokyo 2017 D1-E1

Resilient

https://github.com/jhalterman/failsafe

Failsafeを使うと、簡単にリトライポリシーを設定できる

Exponential backoff なども

Page 23: Antifragile Java - Java Day Tokyo 2017 D1-E1

Circuit BreakerResilient

Closed Open

Half Open

失敗が何度も続いたら呼び出し側で呼び出しを停める

(Release It!で紹介されてメジャーに)

失敗が閾値を越える

リセットを試みる失敗

リセット

Page 24: Antifragile Java - Java Day Tokyo 2017 D1-E1

https://github.com/jhalterman/failsafe

Netflix Hystrixが有名だが、前述のfailsafeでも実装可能

Page 25: Antifragile Java - Java Day Tokyo 2017 D1-E1

Bulkheads(隔壁)Resilient

Circuit Breakerと違って、呼び出される側のリソースを保護する

Web

Icon made by Freepik from www.flaticon.com 

Web Web

Free Paid Free Paid

無料会員の影響で、有料会員までアクセスできなくなることのないように

Page 26: Antifragile Java - Java Day Tokyo 2017 D1-E1

Steady state人間がサーバに触れば、そこには常に凡ミスの恐れがある

特に見積では遠い未来のことでも、リソース使用に上限が

設定されていないものは、近い将来、手運用が入るか、

本番障害として現れる

● ログファイル削除(ローテート)● データパージ●キャッシュの上限

Resilient

Page 27: Antifragile Java - Java Day Tokyo 2017 D1-E1

ログローテーションはOS全体の運用と合わせるとよい。(Log4j等のAppender自体の持つローテーションは運用トラブルをよく聞く)

http://qiita.com/kawasima/items/ab2c9c14e8bbb2d23df5

Resilient

Page 28: Antifragile Java - Java Day Tokyo 2017 D1-E1

Fail Fast失敗の可能性が早く分かるものは、その時点で失敗させる

Resilient

● トランザクションを始める前に、失敗の可能性があるかチェックする。

● リソースを使うより先に、ユーザの入力値チェックをおこなう

Page 29: Antifragile Java - Java Day Tokyo 2017 D1-E1

APIゲートウェイでValidationする

Resilient

API Gateway

Service A

Service B

HTTP

HTTP

入力フォーマットのチェックはここで

可能

そういうAPI Gateway (というかBFF)を開発中ですhttps://github.com/kawasima/darzana

Page 30: Antifragile Java - Java Day Tokyo 2017 D1-E1

Monitoring異常状態をいち早く検知することがAntifragileの必要条件

Page 31: Antifragile Java - Java Day Tokyo 2017 D1-E1

Anormaly DetectionMonitoring

http://docs.datadoghq.com/ja/guides/anomalies/

季節や時間帯などで変動の大きいデータの異常検知手段

Page 32: Antifragile Java - Java Day Tokyo 2017 D1-E1

Monitoring

Page 33: Antifragile Java - Java Day Tokyo 2017 D1-E1

Consumer Driven Contract Testing

Monitoring

Client(Consumer)

Server(Provider)

知らぬ間にServerのAPIが変更された、なんてことがないよう、

Contractを書いてテストして検知する

Page 34: Antifragile Java - Java Day Tokyo 2017 D1-E1

クライアントサイドからのモニタリングMonitoring

● ページのスクショを撮って、変わってないことを比較する

● ページのHTMLソースを比較する

● Javascriptのエラーが無いことを確認する

● 各ページのHTTPステータスをチェックする

● クライアントサイドの性能に異常がないことをチェックする。

https://github.com/Cognifide/aet

Page 35: Antifragile Java - Java Day Tokyo 2017 D1-E1

Unknownの早期検出「分かっていないこと」を、ランダム性やTinkeringによってあぶり出す

Page 36: Antifragile Java - Java Day Tokyo 2017 D1-E1

Failure Injection TestingUnknownの早期検出

https://www.slideshare.net/JoshEvans2/embracing-failure-reinvent-2014

意図的に本番障害を起こし、何が起きるかをモニタリングする

Netflixの取り組みChaos Monkey: EC2インスタンス単位で落とす

Chaos Gorilla: AZ単位で落とす

Chaos Kong: リージョン単位で落とす

Latency Monkey: 1Microserviceのレスポンスを遅延させる

Page 37: Antifragile Java - Java Day Tokyo 2017 D1-E1

Failure Injectionの自動化Unknownの早期検出

https://www.slideshare.net/InfoQ/applying-failure-testing-research-netflix

現段階では「Injectionのポイントを複数にしてテストしたいが、

組合せ爆発するので絞りたい」を解決しにいっている

Page 38: Antifragile Java - Java Day Tokyo 2017 D1-E1

Random Testing入力データをランダムに生成し、テストする

Unknownの早期検出

junit-quickcheckの例

Page 39: Antifragile Java - Java Day Tokyo 2017 D1-E1

clojure.specUnknownの早期検出

Design by ContractのためのツールだがProperty-based Testingにも使える

構造をもったJSONのようなデータも仕様に沿って生成できる

Page 40: Antifragile Java - Java Day Tokyo 2017 D1-E1

探索的テストUnknownの早期検出

探索的テストで、テストにもランダム性と変動性をもたせ

未知の問題をあぶり出す。

Explore (target)

with (resources)

to discover

(information)

何を目的にして何をテストするのかを明示してから

テスト実行する点において、Ad Hoc Testingとは異なる

Page 41: Antifragile Java - Java Day Tokyo 2017 D1-E1

速い改善のサイクル

Page 42: Antifragile Java - Java Day Tokyo 2017 D1-E1

高速起動アプリケーションの起動は速ければ速いほどよい

Java EEやSpringでは遅いしlightweightを謳うフレームワークでは機能面で物足りない

遅くなる原因● DIのためのクラススキャン● 設定ファイルの動的パース

速い改善のサイクル

Page 43: Antifragile Java - Java Day Tokyo 2017 D1-E1

Enkan

https://www.slideshare.net/kawasima/enkankotowarirepl

起動がとにかく速くなるように1から設計したフレームワーク

速い改善のサイクル

● 1〜3秒で起動し、Port Listenする。

● DIを最小限にし、明示的にコンポーネント生成・登録する

● 設定ファイルを一切無くし、コードで書く。(このためServlet APIにも依存しない)

Page 44: Antifragile Java - Java Day Tokyo 2017 D1-E1

EnkanSystem.of( "doma", new DomaProvider(), "jackson", new JacksonBeansConverter(), "flyway", new FlywayMigration(), "template", new FreemarkerTemplateEngine(), "metrics", new MetricsComponent(), "datasource", new HikariCPComponent( OptionMap.of("uri", "jdbc:h2:mem:test")), "app", new ApplicationComponent( "kotowari.example.MyApplicationFactory"), "http", builder(new UndertowComponent()) .set(UndertowComponent::setPort, Env.getInt("PORT", 3000)) .build()).relationships( component("http").using("app"), component("app").using("datasource", "template", "doma", "jackson", "metrics"), component("doma").using("datasource", "flyway"), component("flyway").using("datasource"));

コンポーネント定義

Page 45: Antifragile Java - Java Day Tokyo 2017 D1-E1

Routes routes = Routes.define(r -> { r.get("/").to(HomeController.class, "index"); r.get("/login").to(LoginController.class, "index"); r.post("/login").to(LoginController.class, "login"); r.scope("/admin", admin -> { admin.resource(UserController.class); });}).compile();

速い改善のサイクル

app.use(new DefaultCharsetMiddleware());

app.use(new MetricsMiddleware<>());

app.use(NONE, new ServiceUnavailableMiddleware<>(

    new ResourceEndpoint("/public/html/503.html")));

app.use(envIn("development"), new StacktraceMiddleware());

ルーティング

ミドルウェア定義

Page 46: Antifragile Java - Java Day Tokyo 2017 D1-E1

速い改善のサイクル

https://www.slideshare.net/syobochim/sier-devops-jjugccc-69780604/32

社内利用事例

Page 47: Antifragile Java - Java Day Tokyo 2017 D1-E1

速い改善のサイクル

https://www.slideshare.net/syobochim/sier-devops-jjugccc-69780604/49

Page 48: Antifragile Java - Java Day Tokyo 2017 D1-E1

無停止デプロイ速い改善のサイクル

Server#1

WebApplication

Load balancer

Server#2

WebApplication

Page 49: Antifragile Java - Java Day Tokyo 2017 D1-E1

Falchion ContainerFalchion Container

JVM real process

WebApplication

JVM pool

JVM virtual process

JVM virtual processJVM real process

WebApplication

Listen the same port

速い改善のサイクル

Page 50: Antifragile Java - Java Day Tokyo 2017 D1-E1

REST APIでJVMの再起動や監視ができる速い改善のサイクル

Page 51: Antifragile Java - Java Day Tokyo 2017 D1-E1

アプリケーションのデプロイ/切り戻し速い改善のサイクル

appdir/ /1.0.0

webapp-1.0.0.jar/1.1.0

webapp-1.1.0.jar

% curl -X POST http://[falcion]/container/refresh/1.1.0

% curl -X POST http://[falcion]/container/refresh/1.0.01.0.0へ切り戻す

1.1.0へバージョンアップ

バージョン毎にディレクトリを作ってアプリケーションのjarを置いておく

Page 52: Antifragile Java - Java Day Tokyo 2017 D1-E1

Auto Repair

http://program-repair.org/

速い改善のサイクル

システムの修復には2通りある

● 状態の修復 (トランザクションのロールバックなど)

● 振る舞いの修復 (プログラムのパッチなど)

プログラムの自動修復(パッチ生成)の研究も盛んに行われている

Page 53: Antifragile Java - Java Day Tokyo 2017 D1-E1

自動的にpatchを作ってくれる

速い改善のサイクル

Page 54: Antifragile Java - Java Day Tokyo 2017 D1-E1

Auto Tuning速い改善のサイクル

Page 55: Antifragile Java - Java Day Tokyo 2017 D1-E1

Antifragile Team & Process

Page 56: Antifragile Java - Java Day Tokyo 2017 D1-E1

Bimodal ITSoR SoE

● 安定性重視

● 予測可能業務

● リスクを抑えて安全運転

● 要件を事前に明確化

● スピード重視

● 探索型業務

● スピード重視で運転

● トライ&エラー、プロトタイピング

Martin Fowlerの批判

1.システムではなくビジネス視点でモードを考えるべきでは?

2.安全性とスピードはトレードオフではない

https://martinfowler.com/bliki/BimodalIT.html

Page 57: Antifragile Java - Java Day Tokyo 2017 D1-E1

リードタイムとプロセスタイムリードタイム

タスク着手 タスク完了チケット作成

プロセスタイム

慎重を要するプロジェクトとそうでないプロジェクトの違いは

リードタイムに現れる

Page 58: Antifragile Java - Java Day Tokyo 2017 D1-E1

リードタイムの短縮領域● 案件が失敗が許されないのか、失敗前提でいくの

かを起案時にハッキリさせる

● それに応じたチーム体制を用意する

● バッチサイズに応じた開発〜リリースプロセスを設計する

DevOpsの下地完成

Page 59: Antifragile Java - Java Day Tokyo 2017 D1-E1

Road to DevOps & Antifragile① DevとOpsを分離する

② Opsを無人化する

③ OpsのAntifragile化

Page 60: Antifragile Java - Java Day Tokyo 2017 D1-E1

DevとOpsの分離ITILやSOX法への対応のためには、開発者が

本番環境に気軽にアクセスできることはまかりならない

開発環境 本番環境

運用チーム開発チーム

アクセスは互いに

制限される

Page 61: Antifragile Java - Java Day Tokyo 2017 D1-E1

Opsの無人化Devが本番環境にログインしない

開発環境 本番環境

運用チーム開発チーム

デプロイ対象の提供

本番のメトリクス

発生障害情報の連携

Page 62: Antifragile Java - Java Day Tokyo 2017 D1-E1

OpsのAntifragile化

開発環境 本番環境

運用チーム開発チーム

Tinkering / FIT

本番環境にストレスを加えて強くする

Page 63: Antifragile Java - Java Day Tokyo 2017 D1-E1

まとめ

Page 64: Antifragile Java - Java Day Tokyo 2017 D1-E1

● RobustからResilient、Antifragileへ

Javaにはそのパーツが揃いつつある

● 予測は大事だが限界がある

あれこれいじくり回せる環境とプロセスを作ろう

● 失敗を防ぎきるよりも、前提とした設計を