新メール配信基盤への移行 /ikyu-mail-platform
by
minato128
Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
新メール配信基盤への移行 株式会社一休 宿泊事業本部 開発部 飯迫 正貴 2017/06/28 【一休 × bitFlyer】C#を使ったサービス開発の裏側
Slide 2
Slide 2 text
今日お話すること
Slide 3
Slide 3 text
今日お話すること • 背景 • 新メール配信基盤の概要 • どう移行したか • 運用開始後にわかったこと • (全体を通して)意識したこと
Slide 4
Slide 4 text
背景
Slide 5
Slide 5 text
背景 • すべてのサービスをオンプレからクラウドへ移行中 • トランザクションメールが対象 • 既存の各サービスからのメール • SMTPでオンプレの共通メールサーバーから送信していた • マーケティングメールは対象外 • メルマガ
Slide 6
Slide 6 text
要件整理・課題 • サービス側がクラウドに移行するまでにメールもクラウドに • もちろんそうですね • ユーザーからの問い合わせに対応するためのログが必要 • CSチームで送達確認や本文の確認をしている • 既存の仕組みだと検索が面倒で時間がかかっている • メール送信処理が同期処理になっていて遅い • 非同期にしたい • 今となってはメールである必要のないものがある • システムチーム宛のものなど • SaaS になると送信量で課金額が決まる
Slide 7
Slide 7 text
どうしたか • 新メール配信基盤は最初から全部クラウドで構築 • Mail SaaS は SendGrid に • SMTPをとりあえず生き残らせるとかはやらない • 暫定対応なしで一気に最終形へ • メールの送信ログは DynamoDB へ • 権限がある人には簡単に参照できる検索画面を用意 • メール送信リクエストは Message Queue で非同期に • 送る側は SQS に Queue を入れるだけ • メールでなくていいものは新基盤には移行しない • 代替として Log SaaS へ流す • 必要に応じて Log SaaS から Slack へ通知する
Slide 8
Slide 8 text
新メール配信基盤の概要
Slide 9
Slide 9 text
アーキテクチャ • メール送信
Slide 10
Slide 10 text
アーキテクチャ • Webhook 受信
Slide 11
Slide 11 text
使い方
Slide 12
Slide 12 text
メール送信履歴検索 • CSチームでユーザーから問い合わせがきたときに利用 • 送達確認 • 内容(本文)確認 • バウンスリストからの削除
Slide 13
Slide 13 text
メール送信履歴検索(Before) 面倒…
Slide 14
Slide 14 text
メール送信履歴検索(After) 権限のある人は即検索可能に!
Slide 15
Slide 15 text
アーキテクチャ • メール送信履歴検索
Slide 16
Slide 16 text
実装 / インフラ • メール送信 • ASP.NET Core / .NET Core /C# • AWS Elastic Beanstalk • 64bit Amazon Linux running Docker • Webhook 受信 • .NET Core / C# • AWS Lambda • メール送信履歴検索 • ASP.NET Core / .NET Core / C# • Windows Server • 諸事情あってまだオンプレ
Slide 17
Slide 17 text
CI / CD • Staging • GitHub master merge => Circle CI => AWS EB or Lambda • Production • GitHub release merge => Circle CI => AWS EB or Lambda
Slide 18
Slide 18 text
CI / CD
Slide 19
Slide 19 text
どう移行したか
Slide 20
Slide 20 text
移行方針 • 送信量の少ないサービスから移行 • AWS 側のリソース調整 • IP ウォームアップ • 詳しくはこちら => https://sendgrid.kke.co.jp/blog/?p=326 • 送信量の少ないサービスは一括移行 • 送信量の多いサービスは徐々に移行 • メールを送る必要がないものやめる • 代替を用意 • 添付ファイルをやめる • もちろん SendGrid API は対応している • が、DynamoDB には JSON を保存するだけにしたい
Slide 21
Slide 21 text
移行順序 / 送信量 / 言語 • 一休.com海外 • 送信量 小 • ASP.NET MVC / C# • 一休.comギフト • 送信量 小 • Classic ASP • 会員基盤や内部向けAPI • 送信量 中 • ASP.NET MVC / C# • 一休.com(宿泊予約) • 送信量 大 • ASP.NET Web Forms / VB + C# • 一休.comスパ • 送信量 小 • PHP • 一休.comレストラン • 送信量 大 • Classic ASP スパまで完了
Slide 22
Slide 22 text
移行方法 (C# or VB) • 共通メール送信用ライブラリ • 現行と同様のインターフェースで別の namespace に新 API を追加 • 旧 API は Obsolete • 部分的な移行もできるように • AppVeyor NuGet で管理 • ライブラリを利用しているサービス • namespace 変更のみで移行完了 • プルリクのレビューが楽 • ライブラリを利用していないサービス • 同じ方針で実装
Slide 23
Slide 23 text
移行方法 (C# or VB)
Slide 24
Slide 24 text
移行方法 (C# or VB)
Slide 25
Slide 25 text
移行方法 (Classic ASP) • namespace 戦法が使えない • 共通の送信ロジックを変更して一括移行(ギフト・スパ) • もしくは、地道に新APIに移行(レストラン) • AWS SDK ない問題 • AWS API Gateway + Lambda で対応(ギフト・スパ) • Lambda から SQS に Enqueue • COMで対応?(レストラン) • レストランはこれから
Slide 26
Slide 26 text
部分移行 • 特に予約完了メールは送信量が多い • かつ重要度が高い • 1%, 10%, 50%, 100% と徐々に新APIへ移行 • テストはしているが、完璧ではない可能性がある • もし失敗しても 1% リカバリーするほうが比較的楽
Slide 27
Slide 27 text
部分移行
Slide 28
Slide 28 text
メールの代替を用意(Before) • バッチ処理結果や特定の例外をメールで送っていた • システムチーム宛 • サービス開始当時はそれしかなかった • メールを GAS で振り分けて Slack にアラートを上げていた • アラートの条件変更がメンテしづらい
Slide 29
Slide 29 text
メールの代替を用意(Before) • 例外メールによる全体の配信遅延 • たまにアプリのバグで例外メールが飛び続けていた
Slide 30
Slide 30 text
メールの代替を用意(After) • Log SaaS (Logentries) へ流すようにした • 同時に構造化ログに • フィルターや集計がしやすく • Logentries 側からアラートを設定 • 条件変更は誰でも簡単にできる • ただデフォルトの Slack 通知機能は微妙 • Raw log が出るだけでカスタマイズもできない • Azure Functions で Webhook を受け取って Slack に通知 • 最初は csx で作ったが、あとで Precompiled Function に変更 • チームで管理するのでちゃんと CI/CD をやりたかった • csx は CD 設定簡単だけどコンパイルエラーだと死ぬ • CI/CD • GitHub => AppVeyor => MS Azure
Slide 31
Slide 31 text
メールの代替を用意(After) バッチ処理結果ログ / Slack アラート
Slide 32
Slide 32 text
添付ファイルをやめる • バッチ処理でメールにファイルを添付していた • 提携企業や経理あて • S3 への保存に変更 • ダウンロード用の Pre-signed URL を本文に記載
Slide 33
Slide 33 text
添付ファイルをやめる(Before) 経理あてのメール
Slide 34
Slide 34 text
添付ファイルをやめる(After) 経理あてのメール
Slide 35
Slide 35 text
ドメインホワイトリスト • 移行前 • 開発環境からメールは送れなかった • 確認方法はあった • 移行後 • 開発環境からもStagingの新メール配信基盤を使うようにした • 開発用実装を持ちたくなかった • 環境依存バグの温床 • とはいえ、誤送信は困る • Config に宛先ドメインのホワイトリストを追加 • Staging はこの設定により特定のドメインにしか実際に送信されない
Slide 36
Slide 36 text
ドメインホワイトリスト
Slide 37
Slide 37 text
運用開始後にわかったこと
Slide 38
Slide 38 text
docomo/au のバウンス率が高い • docomo/au 限定で5回までは自動的にバウンスリストから削 除する仕組みを追加 詳しくはこちらで! https://docs.com/shibayan/6046/sendgrid-c-v3-api
Slide 39
Slide 39 text
yahoo.co.jp のバウンス率が高い • Yahoo!ログインに対応したためYahoo!ユーザーが増えた • Yahoo!メールは一定期間が使わないとメールボックスが Suspendされる仕様 • 使ってないけど通知先に設定されたままのユーザーが多い?
Slide 40
Slide 40 text
速い • アプリ側は Enqueue するだけなので • あるバッチの例 • ユーザーに一括でメール送信している系のバッチ
Slide 41
Slide 41 text
DynamoDB • Write / Read Capacity の調整がちょっと面倒 • provisioned throughput 課金 • 読み書きの性能を予約しておくスタイル • 超過すると例外が発生 • ProvisionedThroughputExceededException • 札束で殴ることもできるが… • 特にバッチ処理で一気に Enqueue されると厳しい • Elastic Beanstalk の設定で同時実行数(並列度)を微調整 • Worker Configuration => HTTP connections
Slide 42
Slide 42 text
Before
Slide 43
Slide 43 text
After
Slide 44
Slide 44 text
DynamoDB • Auto Scaling 機能が今月リリースされた • まだ試してない • 使用量に応じて自動的に Capacity を変更してくれる • ただし反映に時間がかかる • Write スパイクに有効な機能ではない
Slide 45
Slide 45 text
その他 • 一部の IP が Office 365 の Blacklist 入りしていた • いきなりたくさん送るとなりやすいらしい • 気をつけていたのに • https://sender.office.com/ から解除 • CS側でバウンスリストからの削除ができないと運用が回らない • メール送信履歴検索画面に削除機能を追加
Slide 46
Slide 46 text
SendGrid / KKE がよい
Slide 47
Slide 47 text
SendGrid / KKE がよい • SendGrid の採用が決まってからエヴァンジェリストの方にす ぐ来てもらえた • その後も何度もアドバイスをもらった • KKEさんはノウハウや事例をたくさん持っている • 安心・感謝 • しっかりしたドキュメントがある • 公式ライブラリが使いやすくなった
Slide 48
Slide 48 text
今後の対応 • ブロック検知 • メールの HTML 化と開封率の取得 • まだ一部のメールしか HTML 対応していない • プレーンテキストの見た目のまま無理やり HTML にすることは可能だ が、怪しまれて逆に開封率が下がるらしい • ちゃんと文面を HTML 対応する必要がある
Slide 49
Slide 49 text
意識したこと
Slide 50
Slide 50 text
意識したこと • 要件 / 課題整理 • どんな課題を解決するのか明確にする • オンプレからクラウドにしてスケールしやすく • 同期処理から非同期処理にして高速化 • メールログを参照を簡単にしてCSチームの手間を削減 • やらないことを明確にする • 暫定アーキテクチャは作らない • 要らなくなったメールは移行しない • 設計 / 構築 • とにかくシンプルにして、本当に必要なものだけ作る • C# で統一して生産性と安定性をとる • SaaS特性、クラウド特性を理解する • なるべくSaaSに委譲してエンジニアの関心事や手間を減らす • 移行作業 • 移行は必要最低限の変更だけやる • 改善の方にリソースを割く