- はじめに
- 今回紹介する記事
- ZOZOTOWNについて
- ZOZOTOWNにおけるAPI Gateway
- 自分だったらどう考えるか?
- 個人的に勉強になる点
- API Gatewayをカナリアリリースする
- まとめ
はじめに
世の中にはすごいエンジニアや、よりよい物を作ろうと工夫しているエンジニアがたくさんいます。しかもその工夫や苦労をネットに公開してくれていることさえあります。
本になっているわけではないので体系的に学ぶことはできないのですが、そこで考えた工夫やエッセンス、調査内容は必ず誰かの糧になると思います。この記事では私が「読む価値がある!」と思った記事を引用しながら、自分の考えを追加して理解を深めていこうというものです。
今回紹介する記事
素晴らしい記事をだしてくださりありがとうございます。引用させていただきます。
ZOZOTOWNについて
ZOZOTOWNはさまざまな服飾を扱う巨大ECサイトです。ユーザ管理、ID管理、決済、商品管理などなど様々な機能が必要で、セール時にはトラフィックが急増することでも話題のサイトとなっています。
そんなZOZOTOWNですが、ZOZOTOWN作り直しをしよう!というのが2017年に発表されました。
それまではオンプレのIISと、SQL Serverを利用していた構成だったようです。またDBではストアドプロシージャが多用されており、SQLを叩くロジック部分がDBによっていたとのいうことです。
そこで、まずはストアドプロシージャをはがし、APIを使ってSQLを隠蔽することに。さらにクラウドへ移行。
そして最終的にはこのような形のマイクロサービスにもっていくとのこと。
ちなみに2020/11時点ではこのような構成になっているそうです。
左にあるASPとは、Active Server Pages の略で、Microsoft 社が独自に開発した技術です。JSP などと同様、サーバー上で Web サーバーが HTML 文書を解釈してスクリプト部分を実行して、その結果を反映したものをクライアントに送ります。とのこと。要するにwebページの動的生成を行っているサーバですね。( Webプログラミング入門 - とほほのWWW入門 より )
ここはまだオンプレで運用しているようでVMware Worldのセッションではリソース不足の際にDirect Connect経由でVMware Cloud on AWSを利用して増強をしているとのことです。
おそらくここにもメスが入れられ、どこかのタイミングでAWS EKSに移行するんだろうなあと思われます。
ZOZOTOWNにおけるAPI Gateway
【ZOZOTOWNマイクロサービス化】API Gatewayを自社開発したノウハウ大公開! - ZOZO Technologies TECH BLOG
この記事が見た時に非常に驚いた覚えがあります。まさかAPI Gatewayを自作するとは!。AWSを利用しているならAPI Gatewayがマネージドとしてありますし、ApigeeというGoogle謹製のもあるわけです。KongっていうOSSもあったよなあというのもよぎりました。
ZOZOTOWNでAPI Gateway自作にいたるには以下の理由があったそうです。
- リトライやタイムアウトの細かい制御機能 が既存のものでは難しい(カスタムプラグインの開発が厳しい)
- 自社のID基盤との連携がマネージド/OSSだと対応が難しい
- マイクロサービスの連携においてマネージドを経由すると従量課金が膨大に
1ですがブログに記載のあるExponential Backoff And Jitter
の実装やトレースIDの付与
あたりが必要だったのかなあと思います。Exponential BackoffはFluentdのretryのところでも実装されていますが、失敗してすぐにリトライではなく失敗回数に応じてだんだん時間がかかるようにすることで、最終的に成功するがリクエスト数をある程度コントロールすることができます。
トレースIDの付与はマイクロサービスの文脈では可観測性の実現、ログの連携などに用いるものです。このあたりはService Mesh(特にEnvoy)やSPIFFFの考え方を参考にして実装したのかなと勝手に推測します。
あとはこの辺りものタイムアウトもKernel Parameterでハンドリングするのは影響が大きすぎる(すべての通信に対して影響を与える)ため、個別に設定できるようにしたという感じかなと思います。
- connect_timeout は、1リクエストあたりのTCPコネクション確立までの間のタイムアウト値(ミリ秒単位)です。
- read_timeout は、1リクエストあたりのリクエスト開始からレスポンスボディを読み込み終わるまでの間のタイムアウト値(ミリ秒単位)です。
- idle_conn_timeout は、データが送受信されなかった場合にコネクションを維持する時間(ミリ秒単位)です。指定された時間内にデータが送受信されなかった場合、コネクションを閉じます。
- max_idle_conns_per_host
記事の下の方に書いてありましたがマイクロサービス間はサービスメッシュをいれるかも?とありましたので、最初の構成図ではフロント以外がマイクロサービスにいる形でしたが、実際APIを叩く様々なクライアントはマイクロサービス外にいるってことなんだと思います。
ただし、マイクロサービス間のAPIリクエストに関しては、サービスメッシュ(Envoy)の導入も検討しています。理由は、「API Gatewayの負荷軽減」とAPIクライアント毎に配布している「クライアントトークン管理の手間を削減する」ためです。
自分だったらどう考えるか?
API Gatewayを自作する選択がまず思いついていないですね。これまでの経験ということもありますが、SIerにいると長期にメンテナンスが必要で、だれも責任を持てないツールを作るという発想にならないです。
価格的にマネージドが使えないので何らかの製品やOSSの利用が前提になります。また細やかなタイムアウトやID連携のところは要件を並べて、OSSや製品の機能比較、またOSSのところは保守してくれる会社を探すことになるかなあと思います。(それこそEnvoyを単体で動かしどうこうするという可能性も)
個人的に勉強になる点
レガシーなところからモダンに切り替えるためのあゆみや、そこで選択する流れ、それを維持する方法など参考にならないところがないほどの情報なのですが、その中でもなるほどと思ったところを自分なりに読み込んでいきます。
ドキュメンテーション & スキーマ
API Gatewayを開発者が使うことになるのですが、自作のため世の中にほとんど情報がない&使い方がわからないということになりがちです。また人手を介したドキュメントの更新は時間がかかる&抜け漏れが発生しがちです。
ということでZOZOではAPI GatewayのAPIリファレンスを、コードから生成したJSONスキーマとそれをHTMLに自動変換する仕組みを用意しているとのことでした。
世の中にはAWSの構成から構成図を動的に起こしたり、実際の通信から通信フロー図を作成する試みもあるようですが、そういったことも併せて手間をかけない・自動化して品質を維持するといったことを意識してきたいですね。
テスト
API Gatewayは結局何かと組み合わせて使用されるためテスト時においてもMockを用意する必要があります。ZOZOではNginxとPrismを利用して、Mockを(おそらくAPIごと)に用意しdockerで起動できるようにしています。またタイムアウトのところはNginxでJavaScriptを読み込んでsleepを行ってタイムアウトを再現しているようです。
うーん。勉強になるなあ。なるほど機能に対してテストできるようにMockもリポジトリに用意しておくのか…。
API Gatewayをカナリアリリースする
ZOZOTOWNのコアとなるAPI Gatewayをどのようにバージョンアップしていくのか?についての記事を次は見ていきましょう。
API GatewayはEKSで動いており、外部からの通信はIngressとしてのALBからきているようです。
そのためこちらはAWSの仕組みを使って実現をしているだけのようで、ALBに届いたリクエストを加重ルーティングを用いてCanaryにしているとか。(AWS Load Balancer Controllerが担当)
これはZOZOがEKSをシングルクラスタで運用しているから可能なことですね。EKSのバージョンアップのためにマルチクラスタで切り替える会社であれば取れない選択です。(AWS Load Balancer Controllerを両方のクラスタに入れても別々のALBを管理するし、別のクラスタに対する制御をEKSからは行えない)
Quipper Limited社の事例ではALBの加重ルーティングを使うのは同じですが、外部からAWS CLIによって重みを変えて実現しています。個人的にはクラスタの更新はより安全に行うほうが良いかなあと思っているのでクラスタ切り替え派ですね。
まとめ
今回はZOZOの事例を見させていただきました!
正直ショートカットしたところやまだ理解がひじょーーに浅いところもありますが、書かれているエッセンスや観点は真似させていただきたいと思います!! また困ったときに見させていただきますのでよろしくお願いします。