はじめに
Eight事業部のサーバサイドエンジニアをしている太田です。
私の行っている新機能の設計の一環で、ユーザイベントの連携機能をサーバレスで作ることを検討しています。
サーバレスという言葉はエンジニアの間では一般的になってきました。しかし仕事の大部分をサーバレス開発に当てているエンジニアはまだまだ少ないように思います。自分もサーバレスに関する知識はまだまだだったので、このタイミングでまとまってインプットしました。
この記事では、サーバレスな設計をどのように行ったかを簡単にまとめていきます。
設計
機能要件
ユーザイベント連携の要件は以下のようになります。
- 名刺アプリEight(以降Eight)からイベント(名刺の取り込み、更新など)を取得する。
- 取得したイベントを永続化できるデータストアに保存する。
- データストアに保存し、更に後続の処理を走らせる。(※今回の記事では割愛します。)
- 取得したデータはイベント発生時以外の処理にも利用する。データストアには何らかのクエリ機能が必要。
- マイクロサービス的な観点から、Eightからデータストアを直接触らないようにする。
- イベントはEightのwebサーバもしくはbatchサーバから発行する。
また、Eightでのクラウドの利用はほぼAWSなので、今回のシステムもAWS上に作ることにします。
データストアとの連携
今回の要件ではデータストアとEightのサーバたちをどう連携させるかが肝になります。
まずデータストアですが、サーバレスではデータストアはDynamoDBを使うのが一般的です。DynamoDBにはクエリの機能があり、要件を満たしているためDynamoDBをデータストアに使うことにします。
AWSにはRDSというデータベースサービスがありますが、LambdaからRDSを触るときにはコネクションの問題があり、サーバレスではRDSは不向きなことが多いです。
次に連携方法の検討です。DynamoDBとEight本体とをどう連携させるのが良いでしょうか? DynamoDBはLambdaを使って書き込むことでさまざまなサービスとの連携が可能ですが、全部を調査していると時間がいくらあっても足りません。
ここで参考になるのが、AWSが発表している形で考えるサーバーレス設計です。様々なユースケースと実装例があり、これらを組み合わせることでサービスの設計を行うことができます。
今回はちょうどイベント駆動の業務処理連携 というパターンが載っているため、参考にできるかどうかを見ます。
このパターンは以下のような順序で処理が行われます。
- イベントが起こったところでSNSトピックにメッセージを送信する。
- サブスクライブしているSQSにメッセージがエンキューされる
- 連携しているLambdaが実行される
このLambdaに対してDynamoDBの書き込みを行わせれば問題ないように見えます。
構成図は以下のようになります。
その他の検討事項
APIにする?
モバイルアプリやwebフロントエンドからイベントを発行する場合はAPI Gatewayを用いてhttpでやりとりする必要がありますが、今回はその必要がありません。また認証機能などを考える必要があり検討事項が増えてしまうためAPIを作ることは控えます。
SNSを使わずSQSにメッセージを積む?
SQSに直接メッセージを積むことも可能です。しかしSNSよりもサービス間が疎結合になり、また連携したいSQSが増えたときにも対応が容易なため、SNSを間に挟むことにします。
SQSを使わずSNSとLambdaを直接連携させる?
SNSとLambdaをそのままつなげることもできますが、失敗時のリトライなどが柔軟にできないためSQSを利用するのが良いでしょう。
まとめ
サーバレスの型を参考にすることで設計をスムーズに行うことができました。テーブル設計、エラー処理、パフォーマンス、監視など他にも検討すべきことは山積みです。ただどれに関してもかなり事例はでてきていますし、なによりもやってみないとわからないことも多いと思います。Eightでも今後どんどんサーバレスに挑戦していきます。