システム連携で考えること

複数別会社とのシステム連携をする際、こういうことを考えたらいいのではないかというものを思いつく限り列挙した。 双方合意のもとに進めるシステム連携について考えている。自分達が欲しい相手方のデータを独自に解析して取得するシステム連携も存在するが、ここでは考えていない。

この記事は Farmnote Advent Calendar 2018 のために書いた。

各連携先とのやりとり

まず、各共有先と P2P でやりとりするのか、第三の共有地を用意して複数の連携ユーザーが共有する(例: 送信者はS3にエクスポートしたデータを置く、受信者はS3にアクセスする)形にするのか考える。

P2P なら、データの寿命、認可やセキュリティについて考えるのは簡潔でよい。相手が利用したくなったら渡し、相手とののセキュリティのことだけ考慮すればよい。 しかし連携先が増えれば増えるほど、処理も増えてしまうという欠点がある。

共有型なら、共有地にデータを置くと、あとはうまく各連携先が処理してくれるかもしれない。 しかしデータを消すタイミング、認可やセキュリティについてはより深く考えないと事故がおきる。

初期設定

運用開始前に必要な処理、例えば

解除設定

運用解除に必要な処理、例えば

再開

多くの場合は二度と復活させないと思うが、解除後に再開することを考えなければいけないことがあるなら、データの保持方針に違いがでる。 もし再開したときにデータが残っていて欲しいなら削除できない。

接続

どのような形態での接続を行うか。 例えば HTTPS、SSH、VPC 内に環境を作ったプライベートネットワークでやりとりするなど。

現状、データがクラウド上になく、PCに蓄積されている場合もある。その場合そのデータをどうやって安全にアクセスできるところに運ぶか。

例えばアップローダを作るということであれば、誰がどうやって作るか。アップローダーの脆弱性対策をどのように担保するか。

タイムアウト

TCPのような、接続してデータ送信、その後切断する場合には以下のことを考慮する必要がある。

接続はしたが、一定時間内にデータのやりとりができなかった場合、タイムアウトさせるか? もし接続を切らず、接続数を増やし続けるとエラーが発生する。

そのタイムアウトの基準は、初回接続してから一定時間後か? あるいは最終データのやりとりをしてから一定時間後か?

認証/認可

どのように、連携データを送ってくるユーザーを認証するか。アクセストークンで認証なら、そのトークンをいつ時間切れとするか。

どのように、要求してきたデータを受けわたしてよい人物かを判定するか。

向き

連携の向きは片方向か、両方向か。

複数システムのデータ統合については考えなければならないことが多い。 データに主従関係をつけ、主で従を上書きするなどの制約をつけられれば、非常に簡潔な作りに収められる可能性がある。

両方向の場合は、データの主従関係が作りにくく、考えて決めなければならないことが莫大に増える。

頻度

データを送ってくる/データにアクセスしてくる頻度はどの程度か?

ソフトリアルタイムなデータが必要なら、データを必要としている側が定期的に新データを問い合わせるポーリング方式ではなく、 データを必要としている側が保持している側にデータの更新があったときに通知してほしい先をあらかじめ登録しておき、データが更新されたときに呼び出されるコールバック方式がいいかもしれない。 ただしコールバックを送ったのに届かなかった場合の双方のエラーハンドリングは複雑になる。

データの連携にある程度の遅れが許容されるなら、複数のデータを一括して処理するバッチ方式にできると処理の効率は高まる。またハンドリングも容易となる。

一定期間データの待ち合わせをしなければいけないことはないか。その場合はリアルタイムな処理ではなく、バッチ処理が向いている。 参考: バッチ処理を再考する

経済主体の実体的なエンティティは、なんにしろ観測・測定の問題が必ず発生するので、一定の「区切り」で実務的な同期処理を行うことが必要です。 (略) その情報は一定の間隔やタイミングで同期処理を行うことが必要です。これはリアルタイム処理ではありません。「せーのでタイミング」を計って処理することが必要です。 そうでなければ、「会話」ができません。時間軸を整える必要があります。

処理に要する量はどの程度か?大量のデータが届く、または大量のデータ取得依頼が来た場合、その依頼頻度によっては時間内に処理が終わない間に次の処理対象が届いてしまい、処理待ちが増え続けいつしかシステムが壊れる可能性もある。

また、少ないときと多いときの量の変動はどの程度か? 変動が大きいと、多いときにあわせて準備しつづけると不経済だし、少ないときにあわせて準備しておくと多いときに対応できないことがある。

順序

処理の順序が逆転することがある。あるタイミングで送られたデータは大量で、次のタイミングで送られたデータは少量だった場合などは、何も手当てをしなければ後に受けとった方が先に登録を終わってしまう。 こういったことがあってもかまわないか。一般的には後に受けとった方が、先に受けとった方のデータと関連がなければ問題なく、関連があるなら考慮が必要になる。

トラブル回復時に一斉にファイルが送られてくることがあるのではないか。そのときも順番保証が必要か。もしそうなら送られてくるデータの塊の前後関係を把握する仕組みと、1つずつ処理する仕組みが必要。

変換

一方の保持しているデータが、そのまま相手側のデータとして利用できるケースは非常に稀である。どちらかが、相手にあわせて変換しなければいけない。どちらが行うか?

文字コード

海外の製品はもしかするとASCIIしか受けつけていないかもしれない。例えばUTF-8には対応可能となっているか? (最近は日本の製品でもEUC-JPやMS932、SJISのような文字コードは少ない気もする)

改行コード

CR だろうか LF だろうか CR + LF だろうか。その他ヌルバイトが改行の合図だったりしないか。

単位変換

データの形を相手にあわせる他に以下のような部分を揃えなければ双方でうまく動作しない

ID
双方のIDは異なることが多い。その場合は同じ存在を指すが双方で別々のIDをどのように結びつけるかを決定しなければいけない。
日時
双方がUTCで解釈した時間情報をやりとりしていれば問題ない。どちらかあるいは両方が特定のタイムゾーンを前提とした時間情報を利用していた場合変換が必要になる。その場合は、誰がどの情報に変換してほしいかという情報をどこかで管理しておく、あるいは問い合わせのときの付加情報に含めなければならない。

処理開始、処理単位、後始末

何を処理開始のトリガーにするか。よくあるのは定期的な時間になったら処理を初める。それではその定期実行時間は誰がどこに保持管理しておくか。

処理単位はどのようにするか、例えば HTTP のリクエストだと、1 リクエスト 1 処理が自然だろう。仮にストリームやファイルで処理を扱っている場合はどうするか。

処理終了時の後始末はどのようにするか。後始末だけうまく動かなかった場合、それは成功と見做すか失敗と見做すか。失敗の場合次は誰がどのように処理を再開すればよいか。

ファイル

ファイルをどこかに置いて取り込むような形態の場合、中途半端なファイルは扱わず、処理を初めていいという知らせはどのように行うか。例えばファイル生成が完了したら特定の名前のファイルを同一ディレクトリに含めるなど。

ファイルを取り込んだ後の始末はどうするか。保存しておくとエラー調査に便利なこともある。その場合の生存期間はどのくらいにしておくか。また連携解除の際は削除するか?

準正常系

キャンセル

データを相手方に送ってしまったが、まだ処理されていないことが期待されるとき、キャンセルしたいことはないか。もしあれば、どのように行うか。

再送、重複アクセス

データが相手先にうまく送れているかわからないとき、どのように振舞えばよいか。任意のタイミングで何度でも同じデータを送ってかまわないか。その場合送っているものが過去に送ったものと同じデータであるということをどのように示すか。

回復/無視可能なエラーのハンドリング

仮に回復可能や無視可能なエラー(例:複数データのうち一件だけ値が不正であった)が含まれているデータを受けつけた場合、どのように相手へそれを伝えるとよいか。

データ

データは、毎回全て送るか、差分を送るか。

差分を送る場合、いつからの差分か?前回からの差分を送る場合、前回が間違いなく相手に届いて処理が完了している必要がある。どのようにそれを担保するか。 相手に「〜からの差分が欲しい」と名乗ってもらう方法もある。こちらなら安全。

「データの変更」、「データ属性の変更」、「削除」、「(追加、変更、削除の)取り消し」をそれぞれどう表現するか。

信用できないデータ

受けとるデータが誤っている可能性はあるか。その場合、以降に訂正が渡ってくることはあるか?あるとすれば、どのような形で渡ってくるか。

遅れてくるデータ

ある時点Aでデータを受けとり、Aより後Bでデータを受けとったとする。 BをAより先に処理したいことはないか。もしそうならAを受けてから一定時間は処理を待つということが必要になる。

運用

一方が、もう一方の想定していない動作を検知したとき、いつどこでどのように連絡するか?緊急避難的に連携を切ることは可能か?そのとき強制的に切り離された側は連携以外の部分で通常動作ができるか。再開したときに切断した部分からのデータを取得することは可能か?そのとき急激な負荷上昇を避けられるか。

モニタリング、異常検知

モニタリングや異常検知をどのように行うか。一方が仕掛けたモニタリングは、もう一方にも共有するか?もしするなら、全てか?一部か?

ログ管理

トラブル時の調査を容易にするため、一方が他方にログ保存を義務づけるか?そのときログの内容や保存期間はどの程度とするか?

リミット

想定されている必要さを越した頻繁すぎるアクセスやデータ量に対して制限をかけるか。 かける場合、いきなりアクセス制限をかけるのではなく一定時間で回復するリミットを設けて、それぞれのレスポンスに残り量を含めたり、別のAPIで残り量を取得できるようにするか。

バックプレッシャー

受信側が処理しなければいけない量が多すぎる場合、受信側のトラブルにより縮退運転(止めはしないが、処理可能量を大幅に減らす)しなければならない場合に、送信側に対して送信量を減らすように依頼できるようにするか。 その場合の送信側の動きはどうなるか。いつその処理量を減らしてほしいメッセージを受信し、受信後どのくらいの時間で送信をどの程度の量減らせるか。

セキュリティ

片方がセキュリティに気を使っていても、もう片方のセキュリティが低いとデータの安全性、完全性、可用性が損われる。どのように担保し、どのようなことを求めていくか。 特定のセキュリティ診断、負荷テストにパスすることを求めるなど。

統合テスト

相互運用がうまくいくという確信をもつためのテストをどのように行うか?そのテストはある期間に断続的に行うか、あるいはテスト用の環境を常に提供しておくか。

APIアップデート

APIアップデートが必要なときに、アップデートをどのように知らせ、どの程度の期間を置いて移行してもらうか。どのバージョンをどのくらいの間維持するか。もしそれについてこれない接続先があったときにどうするか。

ドキュメント

相互接続のための技術情報をどこに、どのように残すか。またいつアップデートし、アップデートがあったことを他方に伝えるにはどうしたらよいか。