「連携が2回動いて、同じ受注が2件できていました」
ネットワークが一瞬切れて、連携が再送された。その結果、同じ受注が2件、同じ活動が2回記録された。別の日には、1件の不正なデータのせいで、残りの999件も送られていなかった。それに気づいたのは2週間後だった。連携は、必ずどこかで2回動き、必ずどこかで失敗します。その前提で作るための3つの論点です。
シリーズ「システム連携の設計」2/3本目 ・ 次:運用編
重複:2回動いても、1回分の結果にする
エレベーターのボタンは、何回押しても1回押したのと同じです。何度やっても結果が同じになる性質を、冪等性(べきとうせい)と呼びます。連携は、再送・二重起動・イベントの重複で、必ずどこかで2回動きます。そのときに結果が2倍にならないように作ります。
- 「新しいレコードを作る」→「この外部IDのレコードを、この値にする」
- 作成ではなく、外部IDでのupsertにする
- 「金額に1万円足す」→「金額を11万円にする」
- 足し算ではなく、値そのものを送る
- 「メールを送る」→「このIDのメールがまだ送られていなければ送る」
- 一度だけ行う処理には、処理済みの印を残す
失敗:戻ってくる道と、気づける仕組みをつくる
宛先不明の手紙は、差出人に戻ってきます。戻ってこなければ、届かなかったことにすら気づけません。連携の失敗は、種類によって扱いを分けます。
- 一時的な失敗
- ネットワークの瞬断、相手の一時的な混雑。少し待って再試行する。待つ時間を少しずつ延ばす
- データの失敗
- 必須項目が空、値の形式が違う。再試行しても直らないので、別の場所に退避し、人が直す
- 相手の変更
- 項目名が変わった、認証が切れた。全件が失敗するので、すぐに知らせる
そして、1件の失敗で全体を止めないことです。1000件中1件の不正なデータのせいで残りの999件が送られない、という事故はよく起きます。失敗した行だけを外して進め、外した行は理由と一緒に退避場所に残します。失敗を握りつぶさず、誰に知らせ、誰が直すかを決めておきます。
ここで先に反論しておきます。「エラーが出ていないから、ちゃんと動いている」と思うかもしれません。ですが、エラーを握りつぶす連携では、エラーが出ていないことは何の保証にもなりません。毎日0件しか処理していない連携は、失敗と同じくらい怪しいのです。
制限:上限を知り、まとめて、変わったものだけを送る
高速道路の料金所の数には限りがあり、一度に大量の車が来れば渋滞します。Salesforceにも、1日に呼び出せるAPIの回数や、1回の処理で扱える件数・時間に上限があります。APIの回数は、ほかの連携と共有しています。
- まとめて送る
- 1件ずつではなく、まとめて1回で。件数が多いときは、大量データ用の方法(Bulk API)を使う
- 変わったものだけを送る
- 毎回全件ではなく、差分だけ
- 使っている割合を見る
- 上限の何割を使っているかを監視する。最初は動いていた連携が、データの増加で上限を超えることがある
自己診断
- 連携が2回動いたら、レコードや金額は2倍になりますか?
- なるなら、冪等になっていない
- 連携が失敗したとき、誰がいつ気づきますか?
- 答えられなければ、失敗は握りつぶされている
- 1件の不正なデータで、全体が止まりませんか?
- 止まるなら、失敗した行だけを外す作りにする
- APIの呼び出し回数の上限のうち、何割を使っていますか?
- 知らなければ、ある日ほかの連携まで止まる
シリーズ:システム連携の設計
- 1.基本編:正・方向・キー
- 2.信頼性編:重複・失敗・制限(この記事)
- 3.運用編:変換・認証・監視・選定
6つのシリーズの全体像は仕組みの設計:6つの要素にまとめています。
問い
今動いている連携を1つ選び、「もしこれが2回動いたら」「もしこれが今夜止まったら」と考えてみてください。2つの答えがすぐに出てこなければ、その連携は、まだ運が良くて動いているだけかもしれません。