ROBOT PAYMENT Engineers Blog

株式会社ROBOT PAYMENTのテックブログです

請求管理ロボシステム基盤の概要

目次

はじめに

はじめまして、請求管理ロボシステムチームの田中(@j_untanaka)です。SREを自称して好き勝手やっております。
今回は弊社テックブログ開設後2つ目の投稿ということで、挨拶がわりに請求管理ロボシステム基盤の概要や技術スタック等をご紹介したいと思います。

請求管理ロボとその歴史

アイスブレイク的に、請求管理ロボシステムの成り立ちについてお話します。

請求管理ロボは、請求情報を登録すると毎月の請求書発行、入金管理、消込、催促等といった業務を自動化してくれるWebサービスです。
"毎月の"というところがわりと推しポイントで、今流行りのサブスクリプションビジネスを展開されているような企業さんの場合、一度請求情報を登録すれば以降の請求管理業務を継続的に自動化することができます。

2014年ローンチ当初、請求管理ロボはアプリケーションの設計/実装からインフラの構築/運用まで技術的な要素は全て外注していました。
しかし外注先企業とのコミュニケーションコストが高く新機能の追加や不具合改修に時間がかかることや、お世辞にも高品質なサービスを提供できているとは言えない状況から、やはり自分たちのプロダクトは自分達の責任でクオリティコントロールしながらいいものを作っていくべきという機運が高まり、徐々に内製化に向けた体制作りが進められていきました。

なんやかんやありまして、ついに2017年半ば、社内に請求管理ロボシステムチームが立ち上がります。ちなみに私もこのタイミングでROBOT PAYMENTにjoinしたくちです。いわゆるリファラル採用です。
閑話休題で、これからご紹介するのは内製化後に再構築した基盤についてのお話です。

サービス基盤

ここから本題です。
請求管理ロボシステム基盤は、基本的にすべてAWSで動いています。

使用している主なサービスは以下の通りです。

  • ECS(on EC2)
  • AWS Batch
  • EC2
  • ALB
  • RDS(Aurora(MySQL))
  • S3
  • Cloudwatch Events/Logs
  • WAF
  • Route53

お話する内容に絞って超簡略化していますが、以下のような構成になっています。 f:id:j-u:20190823122823p:plain

いくつかポイントを絞ってご説明します。

アプリケーションはコンテナで動いている

請求管理ロボは基本的にPHPで書かれたモノリスなWebアプリケーションです。
コンテナというとマイクロサービスをイメージされる場合が多いかと思いますが、コンテナ化することでThe Twelve-Factor Appに定義されるような状態に自然と整えていくことができるので(もちろんそうするための努力は必要ですが、そういう道筋が立てられるということ)、モノリスだからコンテナ化は向いていないということではないと考えています。

基盤の設計時、特に重視したのが「変化に強い構成にしよう」という点です。
コンテナにすると、現状ツール類はDockerが吸収してくれるし、実行環境もKubernetesはじめ各種オーケストレーションツールの成熟や、CNCFの舵取りによってOCIや各種IFの標準化がいい感じで進んでいると認識しており、当面どこかのクラウドプロバイダに実行環境を縛られる心配はないと考えています。Docker Desktopのおかげでローカル開発環境でもそのまま動かせるのもありがたいです。
反面、より運用フリーなマネージドサービスを採用したほうが安価に安定稼働させられて開発も楽というケースもあるかと思いますが、この先限られたエンジニアリソースである程度の期間運用していくことになるであろう弊社展望を鑑みて、コンテナを採用しました。

偉そうなことを書いてしまいましたが、より現実的なポイントとして

  • 既存のコードの大部分は元の環境からそのまま移行する必要があるが、アプリケーションをフルスクラッチで書き直すような余裕はない
  • そろそろコンテナで本番運用してみたいなという個人的な気持ち

なども考慮の上もろもろ決めたということも付記しておきます。新しいことやってみたいという気持ちは大事。

技術選定

請求管理ロボでコンテナを動かす方法として2パターンあって、Webトランザクションの処理はECS(on EC2)、非同期的な処理はAWS Batchを採用しています。

ECSを選定した理由は、当時AWSにおいてWebアプリケーションをコンテナで実行するためのサービスがECSしかなかったからです(ちなみにAWSを使う大きな理由の一つはAuroraを使いたいからなのですが、話がそれるので割愛)。Fargateはまだ東京リージョンにきていなかったのと、一部都合でECSインスタンス自体に細工をする必要があり選定外となりました。EKSもまだなかった。Kubernetesその他による自前クラスタ構築はシステム規模や人的リソースの都合から検討しませんでした。

以上の通り、ECSを使う強い理由はないので今後運用の都合や時流に応じて変更する可能性はあります。品質を担保できる前提ではありますが、実質的な問題がなくても一定期間で使う技術を変えることでアプリケーションが変化に対応できるか評価できるし、メンバーが使ってみたい/採用に有利そう、といった理由での技術選定も間違いではないと思っています。

さて、ALB+ECSはわりとよくある構成かと思いますので、次の項でAWS Batchの使い方についてご紹介します。

ワークキューシステムとしてのAWS Batch

AWS BatchはAWSのコンテナサービスの中では地味な存在ですが、一言でいうと程よくマネージドなワークキューシステムです(と捉えています)。
キューやコンピューティング環境と呼ばれるワーカーの実行環境(実体はECSクラスタ)といった汎用的な機能はマネージドに提供されつつ、ジョブはコンテナが起動するのでアプリケーションはポータブルな状態を維持できます。

キューごとにジョブを実行するクラスタを指定できるのも特徴で、このジョブは即時実行してほしいからリザーブドインスタンスを常時稼働させたクラスタで、このジョブは実行時間に厳密な制約はないから必要な時にスポットインスタンスを起動するクラスタで、等を比較的簡単に実現できます。固定ではなく優先順位づけもできるので、こっちのクラスタが空いてなければこっちで、みたいなこともできます。
ただ多少癖もあって、デプロイをやや作りこまないといけなかったり、コンピューティング環境の構成変更が難しかったり等、実際に運用しようとするとしばしば、むむ?となることもあるのですが。

さて、請求管理ロボではAWS Batchを大きく以下の2つのパターンで使用しています。

その1 非同期処理(Webトランザクションに対して)

1トランザクションで処理してレスポンスを返すには時間がかかりすぎる機能について、AWS Batchで動かすジョブにオフロードしています。
具体的には、ECSで稼働するWebアプリケーションからawssdkを用いてAWS Batchにジョブをsubmitしています。

サービスの性質上この手の重たい処理は複数存在しており、いくつかの機能では無理矢理Webトランザクション内で完結させようとしてパフォーマンス問題が発生しているのが現状です。そのため現在進行形で少しずつ非同期化を進めているところです。

その2 cronの代わり

定時に実行する必要があるジョブについてもAWS Batchを使用しています。
厳密にはcronの代わりをしているのはCloudwatch Eventsで、ターゲットにジョブキューを指定した上でcron式でスケジュール設定しています。

まとめ

以上、現時点の請求管理ロボ基盤についてざっくり説明しました。ちょっとふんわりした話になりすぎてしまいましたね・・・。
まとめると、

  • 請求管理ロボというサービスと、それを支えるチームがあります
  • WebトランザクションはECS、非同期処理はAWS Batchを使っています
  • ベースがレガシーアプリであることに起因する課題が複数あるけど、少しずつでも負債を返済しながらいいプロダクトを作っていくべく日々前向きに取り組んでいます

というあたりが伝われば良かったかなと思っております。

さて、続いては監視・モニタリング・ログ・CI/CD・構成管理などなど運用基盤まわりや今後やっていきたいことについてお話したかったのですが、長くなるのでまた今度にさせていただきます。

ふんわりしすぎだからもう少し詳しく聞きたい、私ならもっといい感じにしていけるから手伝ってあげてもいい、という方がいらっしゃいましたらいつでも手ぶらで遊びにきてください!