41
Scala が支える 医療系ウェブサービス Kazuhiro Sera @seratch 2015/02/21 #jissenscala

Scala が支える医療系ウェブサービス #jissenscala

Embed Size (px)

Citation preview

Scala が支える 医療系ウェブサービス

Kazuhiro Sera @seratch 2015/02/21 #jissenscala

アジェンダ•サービス要件・チームの現状を紹介 •Web 開発における技術変遷 • Play Framework 導入事例 •実戦での OSS Octoparts 紹介 • Skinny Framework 導入事例 •その他の事例、実践内容 •所感、まとめ

自己紹介

•2009 年から現職、ソフトウェアエンジニア •主に Java/Ruby/Scala でコードを書く仕事 •基盤開発チーム:全社共通サービス・ライブラリの開発・保守、AWS 管理等を担当

• ScalikeJDBC プロジェクトリード • Skinny Framework プロジェクトリード • Scalatra, json4s メンテナ(PR 待ってます)

何をやっている会社?

提供サービス(抜粋)

提供サービス(抜粋)

サービス要件の特徴•m3.com は医療従事者向け会員制サービス • AskDoctors など一般の方向けサービス •サービスは小規模を含めると 50 以上 •システム障害に非常にシビアなサービス •医療現場に近いシステムの場合、安定性が第一 •創業時 (2000 年) から続くサービス、DB •既存のレポート向けデータ集計も考慮した設計

チームの特徴

•事業別で約 10 (変動) のチームに分かれる •オンプレミスが中心、インフラチームは全チームを横断で対応する体制

•新卒はほとんどいない(今年度は 1 名入社) •内製比率を高く保つことにこだわっている • Java が得意なエンジニアが多いが Java/Ruby/Scala 全てこなすケースも増えている

外国人採用への取り組み

http://itpro.nikkeibp.co.jp/article/COLUMN/20140411/550091/

正確には ”ネイティブレベルの日本語能力を必須としない” という意図

Web 開発の歴史

•創業期: シンプルな Servlet、XML 中心な Java フレームワーク、Zope の活用

• 2000 年代中盤: SAStruts、Spring MVC、Play1が主流、ほぼ Java のみ

• 2010 年代: 既存 Java システムに JSON API を提供させて段階的にフロントエンドを刷新、Rails、Play2、Skinny など Java 以外の言語での開発が活発に

アプリ開発技術の変遷創業期 2008 - 2012 2013 - 2015

開発言語 Java Python Java

Java Ruby Scala

Web フレームワーク

独自 MVC Servlet / JSP

Zope

SAStruts Spring MVC

Jersey (JAX-RS) Play Framework 1

etc..

Ruby on Rails Play Framework 2 Skinny Framework

Spring MVC

ORMJDBC そのまま 独自 JDBC

S2JDBC Doma

Spring JDBC Hibernate

ActiveRecord ScalikeJDBC Skinny ORM

Doma

今週リニューアル

m3.com を支える技術

2015 年からの新しい m3.com は多くの Scala OSS に支えられています(Play、ScalikeJDBC、Skinny・・・)

新 m3.com 構成

JSON

JSON

JSON

JSON

JSON

Octoparts 等の詳細は後ほど紹介

トップページ等のレンダリング

導入事例の紹介

Play Framework

https://playframework.com/

Play 導入状況

•2.0 リリース時 (2012 年) から一部で導入、当時から稼働し続けるシステムもある

• 2014 年~ Scala がメインの開発チームのリードにより Play の導入が増えた

•現在、ロンチ前のものも含め 6 件の実績 •必要に応じて Scala/Play にキャッチアップするエンジニアが増加中

Play 事例(一部)

既存 Java システムのリニューアル 2 件

長年運用していた Servlet、JSP ベースのシステムを REST API に置き換え。データモデル class の共有、Swagger 連携、ScalikeJDBC (複雑なクエリ対応、commons-dbcp2)、Elasticseach (elastic4s)、Sentry (raven-logback)、metrics-play、scaldi-play。

Octoparts (OSS) https://github.com/m3dev/octoparts

複数のバックエンド API コールを並列実行してまとめて返すミドルウェア。Netflix が公開している Hystrix を使ったバックエンド障害検知・切り離し・自動復旧。キャッシュの設定・キャッシュ削除 API。Elasticsearch + Kibana 連携でバックエンド API のパフォーマンスを視覚化。

ライブラリ・運用•定番で連携しているのは Scaldi、Swagger、Dropwizard Metrics, Sentry あたり

•基本的には Play が提供する API を使う • DB アクセスは ScalikeJDBC のみ • Octoparts を挟んだシステム間 API 連携 • Jenkins ジョブで sbt universal:package-zip-tarball 実行 & アプリサーバに配布

• Play の daemon は upstart で起動停止

Octoparts http://m3dev.github.io/octoparts/

character design by @yancharica

Octoparts とはバックエンド API 呼び出しを並列化するだけでなくキャッシュ・障害検知・切り離し・自動復旧まで賢くやってくれるシステム間連携の仲介役

 Hystrix ・Netflix が公開している Java で実装された OSS

・Octoparts は内部的に Hystrix の Command としてバックエンド呼び出しを行う(#run() で)

swagger-ui

http://octoparts.herokuapp.com/swagger-ui/

キャッシュの破棄

Part の収集を API に依頼

API リクエスト例

https://github.com/m3dev/octoparts/blob/develop/models/src/main/scala/com/m3/octoparts/model/

{ "requestMeta": {"id": “req-12345", "userId": “sera"}, "requests": [{"partId": “beer", "params": [{"key": “beerId”, "value": "1"}]}] }

{ "responseMeta": {"id": “req-12345", "processTime": 26}, "responses": [{"partId": “beer", "id": “beer”, “contents”: “{\”name\”: \“yonayona\”}”, “statusCode”: 200, “mimeType”: “application/json”, ”cookies”: [], "cacheControl": {"noStore": false, "noCache": false}, "warnings": [], "errors": [], "retrievedFromCache": false}] }

リクエスト例

レスポンス例

設定の変更

・Part 単位の各種設定 ・スレッドプールの設定値変更 ・キャッシュグループの設定変更 ・JSON で設定をインポート ・JSON で設定をエクスポート

Hystrix ダッシュボード

・Hystrix が元々持つ機能 ・Circuit と Thread Pool の状態を可視化 ・どの Part がどの程度スローダウンしているか現状がリアルタイムで分かる

ES + Kibana

・Fluentd 経由で Elasticsearch + Kibana で Part 単位の応答状況を可視化(success/timeout/failure/cached

success、応答時間)・本番環境のリアルタイムな状況把握に利用

Skinny Framework

http://skinny-framework.org/

Skinny 導入状況

•Rails、Play2 に次いで採用事例が増えている • Play1 メインだったチームが Skinny に移行 • Scala フリークではなかったチームが選択 •本番稼動 5 件、開発中含め計 6 件の実績 • 2014/03 ~ まだ若いフレームワークだが、特にトラブルなく本番稼働中

ライブラリ・運用

•普通の Web アプリ要件は標準機能で間に合う •既存の社内 Java ライブラリ(Servlet 関連も含む)をそのまま組み込む

•本番運用は Jenkins で war を社内 Maven リポジトリに publish、Tomcat に配る

•運用側から見ると従来の Java と全く同じ

Skinny 事例(一部)

アンケートサービスAngular.js サーバサイド、Grunt で JS ビルド。既存の ServletFilter 組み込み。Skinny ORM の複数データソース・スキーマ対応。管理 UI は scaffold ベース。

トラッキングデータ集計基盤

データ分析の ETL(複数 DB・ログファイル)を crond でキックした skinny-task で実行。社内の担当者向け Web UI(設定入力、結果データダウンロード)。各種メール通知(入力催促・結果通知)。

リアルタイム判定 API サービス

履歴データを元にリアルタイムで判定して結果を返すAPI サーバ。複数の条件判定を Servlet 上の Future 待ち合わせで並列化。98 %tile 50ms 応答。管理 UI は i18n 機能で日英対応。

Play と Skinny

•事実、Play は Scala 界隈でのデファクト •後発の動機 = 違う方向性のものを求めた • Skinny MVC は Future 前提の実装を求めないアプリ要件・開発チームと相性がよい

•会社としては常にすべての技術選択に開発チームによる主体的な判断を尊重する

Jenkins CI

• sbt-scoverage でカバレッジ計測 • scct の頃に比べればかなり安定している •テスト結果が変わってしまうことがある対策として、テスト実行とカバレッジ計測のジョブを分けて、カバレッジ計測のジョブではテスト失敗を無視…

Zipkin

• Twitter 社の OSS 分散トレーシングシステム • 2013/10 から本番ボトルネック調査に活用 •自前の ServletFilter を仕込んでデータ取得 •運用が重くならないようにデータは Thrift で受けて Redis に保存

http://twitter.github.io/zipkin/

画面イメージ

ここからドリルダウンしてどのメソッドが遅いかまで追える

Typesafe Subscription

• Typesafe Subscription を契約 • Play、Scala、sbt に関する Q&A サービス • Q&A は英語のみ、24 時間以内の回答保証 •何度か利用実績がある

Apache Spark

•オンラインでの Apache Spark Workshop に参加(Typesafe 社、2 日間)

•社内 Tech Talk 等での情報共有 •一部で既存のログ集計・データ分析への応用を始めている

現場を見て私の所感•レビューで議論に時間をかけすぎない •定番のコードスタイルは徐々に見えてくる •動作検証のためのテストコードは当然必要 •不要に Scala のハードルを上げないコード • Future を扱うセンスに長けたメンバの需要 •同期処理が十分速ければよい場合もある •未来のアップデート対応コストへの意識

まとめ

•Scala が支える医療系ウェブサービスの話 • 3 - 4 年前は一部のメンバだけのもの •今は機が熟して “普通に” 使われるものに • Java の会社→Java/Ruby/Scala の会社 •Web 開発に Rails、Play2、Skinny • 適材適所で Scala をうまく使おう

一緒にやりましょう

at.m3.com/job