## 背景
社内で運用するサービスが増え、新しい機能を実現するためにサービス間連携が頻繁に起きるようになりました。サービス間連携で課題になるのはサービス同士の依存関係で、APIを利用する側は利用される側に依存することになります。この関係が1対1ならシンプルですが、1対多や多対多になることがほとんどです。依存関係が複雑になると、APIの仕様変更がどこまで影響するのかが把握しにくくなり、不意に広報互換性が壊れる変更が入って、連携が破綻してしまう可能性もあります。
こうした複雑化する依存関係を改善し、サービス間連携をスムーズにする社内基盤としてPub/Sub基盤を開発した というのが本プロジェクトです。構想自体はTLが既に考えていたので、その実装を行いつつ、追加で考慮すべき要件が上がった際はその解決策の設計から開発まで通しで行うこともありました。
また新規サービス間連携機能の開発で、実際にPub/Sub基盤の導入までサポートしました。一時的に開発チームにjoinして、基盤のユーザー=アプリ開発者に近い立場で導入サポートやトラブルシュートを行うことで、スムーズに導入を進めることができました。機能開発自体もオンスケで進み、シームレスなサービス間連携を社内でアピールする良い成功事例になったと思います。
https://corp.freee.co.jp/news/20231221freee_card_accounting.html
## やったこと
### GoによるPub/Sub基盤のクライアント実装
1stケースとしてAmazon KinesisをStreamとしてPub/Subが設計されていたので、AWS APIをラップする形で、Publisher, Subscriber両々のクライアントをGoの社内ライブラリに実装。元々Rubyでの仮実装が存在していたので、まずそのリプレースから行いました。
実装のコアになる部分はTLの方にリードしてもらい、徐々に1から実装するコンポーネントを増やしていきました。例を挙げると以下。
- Publish, Subscribe双方のlogを収集し、適切にEventが消化されたを定期的に確認するlogmatcher機構
- AWSがサポートするJavaのKCL(Kinesis Client Library)が持つ、KinesisのResharding対応の実装
### TerraformによるPub/Sub基盤のAWSインフラ構築(Amazon Kinesisなど)
インフラ構築は基本AWSで行うため、社内標準であるTerraformを使ってコードベースでKinesisなどを作成。上で述べたlogmatcher機構やResharding対応など、場合によって必要なリソース、パラメータが異なるので、関連するリソースを一括で構築できるようなmoduleを用意しました。
### Amazon EKS上にPub/Sub基盤用のkubenertesリソースのデプロイ
Subscriberは、KinesisとEventを受け取るサービス側との間にworkerを挟む構成をとったため、EKS clusterにそのworkerをデプロイ。こちらも社内標準の仕組みでEKS clusterを構築し、helmfileによるmanifest管理でworkerの構成を管理しました。