なぜBtoB事業部が中国版ZOZOTOWNの開発に関わっているのか

岡元政大氏(以下、岡元):ZOZOテクノロジーズBtoB事業部の岡元政大と申します。本日は「Fulfillment by ZOZOと中国版ZOZOTOWNでAWS Lambdaをどのように用いて開発を行なっているのか」について紹介します。

あらためまして、自己紹介をさせてください。岡元政大と申します。BtoB事業部所属で、こちらは今年の4月に株式会社アラタナが統合されてできた部署になります。拠点が宮崎と東京にあり、自分は東京で働いています。また、個人的な活動として、Serverless Frameworkやその周辺のプラグインへのコントリビューションを行なったりしています。

本日のアジェンダは、まず、BtoB事業部で開発しているサービスの紹介。次にそのサービスの構成。また、その構成にどのような問題点があり、どのような工夫を行なっているのか。最後にまとめという流れで発表したいと思います。

おそらくみなさま、初めて「Fulfillment by ZOZO」というサービスを耳にすると思いますので、簡単に紹介します。

Fulfillment by ZOZO、以降はFBZと略しますが、一言でいうと、FBZは自社ECとZOZOBASEをつないでくれるサービスになります。自社ECとZOZOBASEの間で商品や注文といったデータを連携することで、商品の保管や配送の処理をZOZOBASEが行なってくれるようになり、商品の欠品による機会損失を減らすメリットがあります。

具体的にはこちらのURLに説明がありますので、見てもらえるとうれしいです。

次に中国版ZOZOTOWNについてです。ZOZOTOWNは昨年の12月に中国へ再進出しました。中国ではファッションメディアECとして展開を行なっています。

おそらくみなさま、なぜBtoB事業部が中国版ZOZOTOWNの開発に関わっているのか不思議だと思いますので、こちらについて簡単に説明します。

中国で開発を行なっていた中国側のカートとなるアプリケーションがあるのですが、そのアプリケーションとZOZOの間でどのように商品や注文といったデータを連携するか困っていました。

そこで、FBZで提供している機能の中にすでにZOZOとデータを連携してくれる機能があったので、「それが使えるのではないか?」という話になりました。そういった経緯があり、FBZの開発を行なっていたBtoB事業部が中国版ZOZOTOWNのバックエンドのデータ連携部分の開発に関わっていった、というような経緯があります。

以上で、BtoB事業部と、そこで開発を行なっているサービスの紹介になります。

FBZと中国版ZOZOTOWNの違い

ここからはFBZと中国版ZOZOTOWNの構成について技術的な視点から紹介します。

FBZと中国版ZOZOTOWNはどちらもサーバの管理が不要なサーバレスなリソースを用いて開発を行なっています。具体的にはAWS LambdaやDynamoDBといったリソースになります。また、これらのリソースの管理にServerless Frameworkを用いています。

AWS Lambdaをメインに用いているのですが、LambdaのコードはPythonで書いています。また、ここがFBZと中国版ZOZOTOWNで特徴的な点だと思うのですが、FBZでは約400個、中国版ZOZOTOWNでは約90個のLambdaが存在しています。このLambdaの数はけっこう多いのではないかと思っています。

次にFBZと中国版ZOZOTOWNの構成についてより詳しい紹介になりますが、基本的にはオーソドックスなつくりになっています。

サービスには大きく分けてAPIとBatchが存在します。APIのほうは、カートからのリクエストをAPI Gatewayで受け、そのイベントからLambdaを実行し、DynamoDBやZOZOへデータの連携を行なってレスポンスを返す、というような流れです。Batchのほうは、Cloud Watch EventsからLambdaを実行し、こちらも同じくDynamoDBやZOZOへデータの連携を行なうというような流れです。

FBZと中国版ZOZOTOWNはミクロで見ると同じ構成をしていますが、中国版ZOZOTOWNはFBZの後発として開発を行なっているので、FBZで課題となっていた点の解決を狙って開発を行なっています。

FBZの問題点と中国版ZOZOTOWNの工夫

ここからはFBZでどのような課題があり、中国版ZOZOTOWNでどのような工夫をしながら開発していったのかについて紹介します。FBZの問題点です。FBZには一度のリリースに1時間、時間がかかってしまうという問題点がありました。

この原因は、先ほども紹介しましたが、FBZには約400個のLambdaが存在しており、そのサービスのソースコードに変更があった際はこれらのLambdaの更新を行なわなければなりません。Lambdaの更新をする際、400個のLambdaやAPI Gateway、DynamoDBといったリソースが1つのCloudFormationスタックに入り切らないため、これらのリソースを十数個のスタックに分けて更新を行なっています。

図にするとこのようなイメージです。約400個のLambdaが存在しており、その中で動いているソースコードがあります。ソースコードに変更があった際はこれらのLambdaの更新を行なわなければなりませんが、このLambdaが十数個のCloudformationスタックに分かれて存在しているため、すべてのスタックを更新するのに1時間、時間がかかってしまっています。これがリリースに1時間かかるFBZの正体です。

中国版ZOZOTOWNではFBZの経験から開発が進み、「Lambdaが増えるにつれ、FBZと同じ構成をしていると、リリースに時間がかかってしまうようになる」という知見がありました。

そこで、中国版ZOZOTOWNではサービスを小さく分けて開発を行なっていきました。サービスが小さく分かれていることで、更新があったサービスだけリリースできるようにする狙いです。

図にするとこのようなイメージです。上のサービスと下のサービスに分かれていることで、上のサービスに変更があった場合は、上のサービスだけをリリースすればリリースが完了します。

しかし、サービスを分けてしまったことで、一方のサービスからもう一方のサービスの処理を、直接ソースコードを参照して呼び出せなくなってしまいました。

例えば注文を扱うサービスと商品を扱うサービスでサービスを分けた場合、注文を扱うサービス内の注文登録の処理中に商品が販売可能かをチェックしたいとき、商品サービスがもっている商品が販売可能かをチェックする処理を呼び出すのに、ひと手間必要です。

そこで中国版ZOZOTOWNでは、ほかのサービスへ公開したい処理をLambdaとして公開することでサービス間のやりとりを調整しました。先ほどの注文登録の例で言うと、注文登録の処理中に商品サービスが公開している商品が販売可能かをチェックするLambdaを呼び出すことで、注文登録処理中のチェックを実現しています。

一般的にはこういったサービス間の同期的なやりとりにはHTTPのAPIを用いることが多いと思うのですが、中国版ZOZOTOWNではLambdaを用いました。

中国版ZOZOTOWNの構成と工夫した結果

サービス間のやりとりにHTTPのAPIではなくLambdaを用いるメリットについて、2つ紹介します。ここではHTTPのAPIをAPI Gatewayを用いて提供している場合と比較しています。

1つ目は、IAMによる認証認可が楽というメリットがあります。API GatewayでIAM認証を用いる場合、APIのリクエストに署名が必要ですが、Lambdaを用いる場合、AWS SDKがLambda呼び出し時のリクエストに署名を行なってくれます。そのため開発者が署名に関するコードを書く必要がなくなります。

次に、管理が楽というメリットがあります。API Gatewayを用いてHTTPのAPIを公開する場合、APIの呼び出し側はAPIのエンドポイントやURLのパス、POSTやGETといったメソッドを知っていなければAPIを呼び出せませんが、Lambdaを用いる場合、Lambdaの名前を知っていれば呼び出しが可能です。

中国版ZOZOTOWNではFBZの経験から工夫をもって開発を行なってきました。これらの工夫を行なったことでどういったいいことがあったのか紹介します。

まず、一つひとつのサービスが小さく分かれているのでそれぞれのサービスの構成が複雑にならず、サービス内の構成が把握しやすいため、保守性が向上しました。また、括弧つきで「(やろうと思えば)」と書いていますが、変更したサービスのみでのリリースが可能です。

実は中国版ZOZOTOWNでは変更があったサービスだけでのリリースを行なっていません。この理由が、中国版ZOZOTOWNではすべてのサービスを1つのリポジトリで管理しているため、変更があったサービスだけリリースするには仕組みづくりに工夫が必要だからです。

言い訳をしておくと、現状、中国版ZOZOTOWNのリリースの時間は10分程度とFBZと比べてそれほど長くはないため、これは今後の課題として対応を据え置いています。

サービスを小さく分けることでリリースの時間の短縮

ここまででFBZの構成と中国版ZOZOTOWNでの工夫と課題について紹介しました。最後にまとめます。

BtoB事業部で開発を行なっている「Fulfillment by ZOZO」「中国版ZOZOTOWN」では、AWS Lambdaを活用して開発を行なっています。FBZの経験から「Lambdaが増えすぎ、また、その構成によってはリリースに時間がかかってしまうようになる」という問題点が発生することがわかりました。

そこで、中国版ZOZOTOWNではサービスを小さく分けることでリリースの時間の短縮を狙いました。サービスが小さく分かれていることで、変更があったサービス個別でのリリースが可能です。

また、保守性も向上するという副作用がありました。実際に個別でリリースを行なう仕組みづくりは今後の課題です。

以上で発表を終わります。ご清聴ありがとうございました。

質疑応答

坂井華子氏(以下、坂井):岡元さん、ありがとうございました。それではさっそくですけれども、質問を見てまいりたいと思います。下のはじめのほうからいきたいと思います。

まずこちら。「LambdaのCI/CDを行なうアーキテクチャが知りたいです」とのことですが、こちらいかがでしょうか?

岡元:LambdaのCI/CDは、CD……デプロイとのところだけで言うと、Serverless FrameworkをCodeBuildの中で実行してデプロイを行なっています。それをServerlessのデプロイで1個1個リリースしているような状況です。こんな答えで大丈夫でしょうか。

坂井:ありがとうございます。次に「リリースの時間が長くなると、エンジニアの時間が取られる以外にも、サービスを運営する上で生じるデメリットはありますか?」とのことです。

岡元:ここは開発チーム内でも話しているのですが、リリースを行なった直後にロールバックが必要な障害とかが発生したときに、またロールバックするのに1時間、時間がかかってしまうような感じになっているので、そこで問題が大きくなってしまうようなことがあるかなと思っています。幸い、そういったことは今まで起こっていません。以上です。

坂井:ありがとうございます。お時間の都合もあるのであと2〜3個いきたいと思います。お願いします。「課題が見えているということですが、FBZのアーキテクチャのリニューアルは今後考えていらっしゃいますでしょうか?」。

岡元:そうですね。リニューアルも今後していきたいなという話はあるのですが、日頃の目の前のタスクに追われがちというのもあって、まだ構想だけで止まっているような段階です。以上です。

坂井:ありがとうございます。

それでは次の質問です。「もしZOZO CHINAにおいて変更があったサービスを個別にリリースできるようになるとすると、どのような方法が考えられますでしょうか?」。

岡元:中国版ZOZOTOWNでは、ソースコードの管理にGitHubと、先ほども紹介したCodeBuildを用いているので、GitHubのWebhookの情報から変更があったファイルの一覧を取得して、そこから更新をしなければならないサービスの更新を行なうといったような方法が考えられるかなと思っています。

坂井:ありがとうございます。それでは、次を最後の質問にしたいと思います。「変更があったものだけをデプロイするとありましたけれども、変更があったものは機械的に抽出されるのでしょうか? それとも人が判断するのでしょうか?」ということですけれども、いかがでしょうか?

岡元:ここは現在変更があったものだけのリリースは行なっていないんですけど、今後やろうとするとそういうかたちに、変更があったファイルからリリースしないといけないサービスを特定してリリースを行なうような仕組みになると思います。

坂井:ありがとうございます。それでは以上でこのパートを終了といたします。岡元さん、ありがとうございました。

岡元:ありがとうございました。