PEOPLE

出前館エンジニアがAWSを活用してレガシーシステムの課題を解決した話

こんにちは。出前館のサーバーサイドエンジニアの三木一馬です。

マーチャント開発部 マーチャント開発グループに所属しており、主にToBのサービスを担当するチームに所属しています。

普段は、主にインフラ系の作業(TerraformやGithub Actions)と設計レビューやコードレビュー、システムの保守運用をしています。

プロジェクトの概要

出前館では、大規模な加盟店チェーンを中心に、出前館と加盟店様との間でAPI連携を実施しています。

API連携することにより、加盟店様としては以下のメリットがあります。

  • 加盟店側のPOSシステムへ自動的に出前館での売上データが連携できる
  • 加盟店側のPOSで受注が確認できるので、店舗で出前館タブレットの確認が不要
  • 加盟店側のPOSの店舗・商品マスタ情報を出前館側のデータにも反映ができる

今回は、2021年10月にPhase1のリリースを迎えました加盟店様とのAPI連携(以後外部連携)のリプレースプロジェクトにおける経験についてご紹介します。

現状の課題

出前館サービス自体、コロナ禍やTVCMなどでここ1年ほど注目されていますが、サービス開始より20年以上経過しています。

https://corporate.demae-can.com/company/history.html

長い歴史を持つシステムあるあるですが、既存の課題として以下の課題がありました。

―課題1 出前館システム全体が密結合なシステムになっている

まず出前館システム全体の課題として、密結合なシステムになっていることが挙げられます。

出前館システム全体が1つのDB(Oracle)に依存している以前の出前館ではシステム自体は分かれていましたが、ほとんどのサービスで参照しているデータベースが共通になっており、1つのデータベースへの依存度が高い状態でした。

共通になっていることで、もちろんメリットもあると思いますが、Oracleがダウンした際に以下の課題がある状況でした。

  • 出前館のOracleを利用しているサービス(ほとんど全てのサービス)がダウンする
  • データベースの定義変更が他のサービスに影響し得る
  • 外部連携システムと他サービス間の連携がほとんど同期処理で行われ、単一障害点になっている

―課題2 古いアーキテクチャ

①オンプレミス

出前館では自社でデータセンターを運用しており、そこのサーバー群を利用しておりました。もちろん、ラックのスペースにも限界があるので、動的なスケーリングは困難です。

また構築についても、事前にインフラ構築チームに依頼をしておかなければいけない状況で、利用までのリードタイムも意識する必要がありました。

②古いJavaバージョン、古いフレームワーク

古いバージョンのJavaのまま更新できていなかったことで以下の状況でした。

  • 利用したいライブラリが対応していない
  • HTTPSの通信要件を満たせない(TLS1.2に対応してない)
  • 古いJavaを回避するためだけの別外部連携システムが存在しており、外部連携システム自体が複数あることで、保守運用コストが高い

技術選定

ASISTOBE
言語Java6、8Java11
FWSeasarSpringBoot
ComputeオンプレAWS ECS、Lambda
CI/CDJenkinsGithub Actions
IaCTerraform
DBOracle
オンプレ
Oracle Aurora
DynamoDB
OtherKafka
monitoringNewRelic

チームの役割についても従来から変更があり、以前までは開発チームとは別のチームがインフラやCI/CDの構築を担当していましたが、現在は開発チーム内で実施しています。

もともと出前館はJavaで書かれているコードが多く、そのためエンジニアもJavaに詳しい方が多いため、言語はJavaを利用しています。

―アーキテクチャ詳細

アーキテクチャについては、出前館内のAWS環境における標準的なアーキテクチャを採用しています。

上の図は大きく分けて2種類の流れのアーキテクチャを記載しています。

①新規の注文

出前館ユーザーが新規注文を行うと、社内の他サービスからKafkaに注文情報がProduceされています。Produceされたデータは我々のConsumerで処理され、その中で加盟店様へ注文データを連携するためのAPIを呼び出しています。

②店舗情報(待ち時間や品切れ設定、店舗ステータス)の更新

出前館では店舗の待ち時間や品切れ設定、店舗ステータス(店舗の営業状態)の参照や更新リクエストを加盟店様に提供しています。こちらは加盟店様のシステムからAPIでのリクエストを受け付け、更新が必要なデータベースを更新しています。

困ったところ

―AWSやTerraform、Github Actions関連、Kafkaなどのナレッジがない

もともと従来の出前館では、上記のような技術は採用していませんでした。そのため、私含めチーム内にナレッジは不足していたのが課題でした。

しかし、LINE社からの出向しているメンバーや業務委託メンバーをはじめ、経験のある方々が参画してきており、逐次ペアプロやナレッジ共有を受けつつ、キャッチアップしながら、プロジェクトを進めることができました。

(もちろん個人でもECSで遊んだりしました!)

加盟店様から出前館へのリクエスト時に出前館側のグローバルIPを固定にする要件があった

通常リクエストを受ける側のグローバルIPアドレスはALBやAPI Gatewayを利用している場合、普通に利用すると固定ではない動的なグローバル IPアドレスが付与されますが、加盟店(クライアント)側の制約で、出前館側のグローバルIPを固定にする必要がありました。

詳しい部分は割愛しますが、複数の解決方法があり、今回はNLBでElastic IPを利用することで、解決しています。

課題に対してどうなったか

―課題1 出前館システム全体が密結合なシステムになっている

1.注文の流れで、Kafkaを採用

Kafkaを採用することで社内の他サービスと疎結合にすることができました。

2.一部のデータをOracleから切り出し

Oracleを参照・更新する機能が減ることでOracleへの依存度を減らすことができました。

(ShopやItemなどの影響範囲が広いテーブルについてはこれからなので道半ばではありますが・・・)

―課題2 古いアーキテクチャ

1.リリースサイクルを短くすることが出来るようになった

以前までの出前館のリリースは以下のような棲み分けで、複数のチームにまたがって実施されていました。

  • 開発資材の準備、SQLの作成
  • 運用:Jenkinsによるビルド&デプロイ、SQL適用

開発側でCI/CDやインフラ構築、デプロイまで実施することになり、少人数でのリリースや緊急時の迅速な対応が実施できるようになりました。

その影響もあり、現在ではリリースサイクルが短くできています。

最後に

現在出前館では一緒にフードテックを牽引してくれる仲間を大募集中です!少しでも出前館のことを気になっていただけたら、ぜひ一度カジュアル面談しましょう!

https://recruit.demae-can.com/engineer-recruitment/people/305/