応募トーク
これは応募されたトークです。聞きたいと思うトークをSNSで拡散しましょう。選考時に参考にさせていただきます。
talk
PythonでマイクロサービスアーキテクチャのWebサービスを実現する(ja)
スピーカー
Yuta Kashino
対象レベル:
中級
カテゴリ:
Best Practices/Patterns
説明
Webサービスの世界で未だに支配的なモノリシック構造は,サービスの規模の拡大と共にパフォーマンスの低下やメンテナンス困難などいろいろな弊害があることがわかっています.これに対する解決策の一つは,マイクロサービス構造を採用するということです.本トークではPythonのツールを利用してマイクロサービス構造を実現する方法を紹介します.非同期サーバー,メッセージングサービス,プロセスコントロールシステムなど,信頼できるPythonライブラリを紹介しながら,マイクロサービス構造の実現方法を具体的なコードとして提示したいと思います.
目的
参加者は適切なPythonライブラリを組み合わせれば比較的簡単な方法でマイクロサービス構造をもった比較的大きなプロダクトを作ることができることを知ります.
概要
Webサービスの世界ではPythonでもPloneやDjangoなどの比較的大きなフレームワークを使ってWebサービスを構築することが未だに支配的です.このような単体フレームワークを使うアーキテクチャは「モノリシック構造」と呼ばれます.Webサービスの立ち上げ時には,たくさん機能のあるよく使われたモノリシック構造のフレームワークを利用することは,開発の工期短縮なるので,いち早くサービスを立ち上げるという他には変えられないメリットがあります.
しかし時間が経つにつれ,機能要件が増え,ユーザが増加し,流通するデータが増えてくると,立ち上げ時にはメリットだったモノリシックという構造が足かせになるようになります.例えば,機能が増えるとそれともにコードベースが複雑になりメンテナンスの困難性が増えます.また,ユーザ数が増加し同時接続セッションが大きくなると,モノリシックなフレームワークではメモリ消費量や計算負荷が高まり,サービスレスポンスが低下していきます.更に,データが多くなってくるとそれを処理するには当然並行処理が必要になりますが,モノリシックな構造では最初から要件として含んでないと難しいことになる一方で,将来の要件を予想するのは困難なので現実問題では要件にはならないという事情もあります.
こういったモノリシック構造がもたらすサービス低下の解決策として提唱されているのが,マイクロサービス構造です.マイクロサービス構造は,モノリシック構造のサービスが一つのアプリケーションとして複数の機能を持つようにコードを書くのに対して,機能ごとに独立したアプリケーションをつくり,その小さな独立アプリケーション同士がメッセージを媒介しながら協調して一つのサービスを構成するようにしたものです.
![][1]
マイクロサービス構造にするとマシンリソースの有効活用ができるます.同時接続セッションが大きくなった場合でも,独立アプリケーションの数を増やして並列処理をすればいいので,サービスレスポンスが低下しません.機能ごとにアプリケーションを分割しますので,コードベースを小さくすることを保つことができ,コードメンテナンスが容易になります.
マイクロサービス構造を作るときにポイントになるのは次の要素です.
- 非同期アプリケーションサーバ
- メッセージングサービス
- タスクキュー
- プロセスコントロールシステム
- デプロイオートメーションツール
まず,非同期アプリケーションサーバはユーザからのリクエストや他のアプリケーションからのリクエストを効率よく捌くために非常に有効です.機能ごとに独立した非同期アプリケーションサーバを非同期アプリケーションサーバで書いておけば,大量のリクエストにも処理のボトルネックが減ることになります.PythonではTornadoやTwisted, そしてPython3から標準になったasync.ioなどがあり,非常に充実しています.
次に,複数の独立したアプリケーションの間を繋いで,アプリケーションを一つのサービスとして動作させるようにするのがメッセージングサービスです.このメッセージングサービスにより,複数のアプリに並列処理をさせたり,シーケンシャルの処理をさせたり,選択的なルーティング処理をさせたりします.良く利用されるのは非常に高速で信頼性の高いZeroMQで,そのPythonバインディングであるpyzmqは素直なpythonicなライブラリでとても使いやすいです.
また,複数の非同期アプリケーションを繋いだ非同期マイクロサービスを構築したとしても,データを永続化するときにボトルネックが発生するのはよく知られています.なぜなら永続化手段が同期接続しかできないRDBだったり,AWSのS3だったりするからです.そのときに利用されるのがメッセージキューです.永続化する処理を「タスク」としてキューに保持しながら,サービス全体の情報のフローを止めないようにするためです.PythonではRQ, Celeryなどとても信頼性のあり比較的高速なメッセージキューがあります.
さらに,複数の独立したアプリケーションがあるということは,それらのアプリケーションのプロセスを統一して管理する必要がでてきます.ここで用いられるのがプロセスコントロールシステムです.プロセスコントロールシステムでは複数のサービスのプロセスを監視し,プロセスがが落ちたら再立ち上げするようにして,サービスの可用性を高めます.Pythonにはプロセスコントロールシステムのディファクトスタンダードともいわれるsupervisorがあります.
最後に,複数の小さなアプリケーションがあるということは,それぞれの設定項目が増加しコンフィグファイルが増えるために,本番環境等へのデプロイメントが難しくなるということでもあります.これを解消する強力なツールがやはりPythonには存在します.言うまでもなくAnsibleやSaltStackです.
これらのPythonツールを利用すれば,楽にマイクロサービス構造を構築することができます.本トークでは,具体的なコード例を出しながら,どうやってマイクロサービス構造を構築すればいいかを提示したいと思います.マイクロサービス構造が実現できれば,リソースの有効利用とスケールアウトが可能になりますので,サービスの可能性が大きく広がります.Pythonは動的型付けのインタプリタなのでCやJavaに比べてあまり速度がでないといわれます.モノリシックな構造でサービスが作られる場合はその通りでしょう.しかし,マイクロサービス構造にして小さな独立アプリケーションに処理を分割すれば,Pythonでもかなりの負荷を持つサービスを運用できます.事実,私の会社では一日に100GBを超えるデータを処理するデータプラットフォームサービスを,一つのマルチコアサーバーだけで運用していますが,そのサービスはマイクロサービス構造にしたPythonスタックでできています.このように,マイクロサービス構造を実現できれば実行速度が速くないPythonであっても適用できる領域が大きくなり,Pythonの可能性が飛躍的に高まると思っています.
[1]: https://bytebucket.org/bakfoo/pub/wiki/pycon2015kashino/microservice.png?rev=d35f8df5b496d443a883c992e49f9d0fbc9a2c14