0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#15. Modality→Edge PCのTCP通信断に備える ― ACK・再送・データ保持・重複排除の設計

0
Last updated at Posted at 2026-10-12

はじめに

Azure IoT Edgeを使ったシステムで、Edge PCからCloudへの通信断に備えてStore-and-Forwardを構成していても、データが失われる可能性は残ります。

それは、Edge PCにデータが届く前の通信断です。

今回扱うシステムは、次の構成です。

Modality(医療機器)
    ↓ TCP
Edge PC(Ubuntu / Azure IoT Edge)
    ↓
Azure IoT Hub

Edge PCからCloudへの通信断については、ローカルでデータを保持し、復旧後に再送する仕組みを検討してきました。

しかし、ModalityからEdge PCへのTCP接続が失敗した場合、データはEdge PCに到達しません。

つまり、Edge PC側のStore-and-Forwardだけでは不十分です。

この記事では、実際に遭遇したTCP接続トラブルを例に、次の点を整理します。

  • TCPのACKとApplicationのACKの違い
  • SYNが届いてもTCP接続できない原因
  • 送信失敗時のデータ保持と再送
  • ACKが返らなかった場合の処理
  • 再送によるDuplicate(重複データ)への対応
  • 無人運用でのTimeoutとErrorの扱い

1. 環境と通信構成

今回の環境は以下のとおりです。

項目 構成
送信元 Modality(医療機器)
受信先 Edge PC
Edge OS Ubuntu 24.04
Edge Runtime Azure IoT Edge 1.6
Container Docker / Moby
通信Protocol TCP
使用Port TCP 57545
Cloud Azure IoT Hub

Edge PC内では、複数のContainerによってデータを処理しています。

Modality
    ↓ TCP 57545
Edge PC
    │
    ├─ TCPServer
    │      ↓
    ├─ RelayConversion
    │      ↓
    ├─ SendAzure
    │      ↓
    └─ edgeHub
           ↓
    Azure IoT Hub

この構成で通信断が発生する箇所は、大きく2つあります。

① Modality → Edge PC

② Edge PC → Cloud

②については、Edge側にデータを保持して再送するStore-and-Forwardが有効です。

しかし、①で通信が失敗した場合には、Modality側にも対策が必要になります。

2. TCP通信でもApplicationのデータ保持は保証されない

TCPには次のような仕組みがあります。

  • ACK(受信確認)
  • Retransmission(再送)
  • Sequence Number(順序管理)
  • Flow Control(フロー制御)

これらによって、TCPは信頼性の高い通信を実現しています。

ただし、TCPが保証することと、Applicationが保証することは異なります。

TCP ACKとApplication ACKの違い

TCP ACKは、相手側のTCPスタックが送信済みデータを受信したことを確認する仕組みです。

しかし、次の処理までは保証しません。

TCPでDataを受信
    ↓
ApplicationがDataを読み取る
    ↓
Dataの内容を検証する
    ↓
Dataを保存する
    ↓
後続処理へ渡す

例えば、Edge PCがTCPデータを受信した直後にApplicationが異常終了した場合、受信済みデータがApplicationとして保存されていない可能性があります。

そのため、重要なデータを扱う場合は、Application側でもACKやResponseを設計する必要があります。

Modality                   Edge PC
   │                          │
   ├──── Data送信 ────────────>│
   │                          │
   │                    Data受信
   │                          │
   │                    Data検証
   │                          │
   │                    Data保存
   │                          │
   │<──── Application ACK ────┤
   │                          │
送信完了

このACKが何を保証するかは、システム側で定義します。

例えば、

「Edge PCがデータを安全に保存したこと」

をACKの成功条件にする設計です。

単にTCPで受信した時点でACKを返す設計と、永続化が完了してからACKを返す設計では、障害時のデータ損失リスクが異なります。

なお、このACKはEdge PCへの保存完了を意味するものであり、Azure IoT Hubへの送信完了まで保証するものではありません。

3. 実際に遭遇した「SYNは届くのにTCP接続できない」障害

過去に、ModalityからEdge PCへTCP接続できない問題が発生しました。

Packet Captureを確認したところ、ModalityからのSYNはEdge PCに届いていました。

Modality
    │
    │ SYN
    ↓
Edge PC

さらに、Docker Container側ではSYN/ACKが生成されていました。

しかし、TCP Connectionは成立しません。

調査すると、Edge PCのRoutingが原因で、応答PacketがModalityのNetworkではなく、別のInterfaceへ送られようとしていました。

Modality
    │
    │ SYN
    ↓
Edge PC
    │
    │ SYN/ACK
    ↓
誤ったNetwork Interface

つまり、

  • Modalityからの通信は届いている
  • Containerも応答を生成している
  • しかし、戻りの通信経路が正しくない

という状態です。

受信方向のPacketが確認できても、戻りの経路が正しいとは限りません。

Linuxでの確認コマンド

同様の問題が発生した場合、まずRouting Tableを確認します。

ip route

次に、ModalityのIPアドレスへの経路を確認します。

ip route get <Modality_IP>

例えば、Modalityへ到達するためのInterfaceが想定と異なっていないかを確認します。

Packetを確認する場合は、tcpdumpを使用します。

sudo tcpdump -ni any \
  "host <Modality_IP> and tcp port 57545"

ここでは以下を確認します。

① ModalityからSYNが届いているか

② Edge PCからSYN/ACKが返っているか

③ ModalityからACKが戻ってくるか

Linux Host側のRoutingだけでなく、DockerのNetwork Namespace、Port Mapping、NATなども関係します。

そのため、必要に応じて各Network InterfaceでCaptureし、どのInterfaceからPacketが出ているかを確認します。

今回の経験から、Applicationが正常に動いていても、Network Pathが成立しているとは限らないことが分かりました。

4. 送信できなかったデータをModality側で保持する

TCP Connectionが成立しない場合、Edge PC側にはデータが届きません。

そのため、Edge PC側にどれだけStore-and-Forwardを構成していても、このデータを救うことはできません。

必要なのは、Modality側にも未送信データを保持する仕組みを持たせることです。

正常時は次のようになります。

Modality
    ↓
Data生成
    ↓
Edge PCへ送信
    ↓
Application ACK受信
    ↓
送信完了

一方、通信失敗時は次のようにします。

Modality
    ↓
Data生成
    ↓
DataをLocal保存
    ↓
Edge PCへ送信
    ↓
Connection Error / Timeout
    ↓
Dataを保持
    ↓
一定時間後にRetry
    ↓
通信復旧
    ↓
再送成功
    ↓
ACK受信
    ↓
送信完了

重要なのは、送信失敗を理由に元データを削除しないことです。

また、データ消失を防ぐためには、送信前のLocal保存や保存領域の永続性も考慮する必要があります。

メモリ上のQueueだけでは、Modalityが再起動した場合に未送信データが失われる可能性があります。

5. ACKが返らない場合は「受信失敗」とは限らない

再送設計で注意したいのが、ACKだけが失われるケースです。

例えば、次のような状況です。

Modality                  Edge PC
   │                         │
   ├──── Data送信 ───────────>│
   │                         │
   │                    Data保存成功
   │                         │
   │<──── ACK送信 ────────────┤
   │
   × ACKが途中で失われる
   │
Timeout
   │
   ├──── Data再送 ───────────>│

Modalityから見るとACKが届いていないため、送信が成功したかどうか判断できません。

しかし、Edge PC側ではすでにデータを保存している可能性があります。

ここで再送すると、同じデータが2回届きます。

そのため、次の2つはセットで考える必要があります。

ACKが届かない
    ↓
再送する
    ↓
重複受信を検出する

6. Duplicate(重複データ)を防ぐ設計

再送を許可する場合、Duplicateの対策も必要です。

例えば、Modalityがデータを送る際に、Message IDを付与します。

{
  "messageId": "device001-000123",
  "deviceId": "device001",
  "timestamp": "2026-10-01T10:00:00Z",
  "data": {
    "status": "completed"
  }
}

Edge PCでは、Message IDを確認します。

Data受信
    ↓
Message ID確認
    ↓
保存済み?
    │
    ├─ NO
    │    ↓
    │  Data保存
    │    ↓
    │  ACK返却
    │
    └─ YES
         ↓
       二重保存しない
         ↓
       ACK返却

この仕組みによって、同じMessage IDのデータが再送された場合でも、二重処理を防げます。

ここで重要なのは、Retry時も同じMessage IDを使うことです。

再送するたびに新しいIDを発行すると、Edge PC側で同一データと判断できません。

また、実装時には次の点も考慮する必要があります。

  • Message IDが一意になる範囲
  • 重複チェック履歴の保持期間
  • Edge PC再起動後も履歴が残ること
  • 重複チェックと保存処理の整合性

Message IDの確認だけでは、並行処理による二重保存を完全に防げない場合があります。

例えば、保存処理に一意制約を設けるなど、冪等性(Idempotency)を確保する設計が必要です。

7. TimeoutとRetryの設計

一時的な通信断が起こるたびにApplicationを停止させると、24時間365日の無人運用が難しくなります。

例えば、次のような設計です。

Data送信
    ↓
Responseなし
    ↓
ERROR
    ↓
Application停止
    ↓
Operatorによる復旧待ち

これでは、一時的なNetwork Troubleでも現地対応が必要になります。

そこで、通信失敗と致命的なApplication Errorを区別します。

通信失敗を段階的に扱う

以下は設計例です。実際の時間や回数は、業務要件に合わせて決定します。

状態 処理
一時的な通信失敗 データ保持・自動Retry
通信失敗が一定時間継続 Warningを記録
長時間復旧しない Operatorへ通知
保存領域が逼迫 優先度の高いAlert
データ保存自体に失敗 別途定義した重大障害処理

Retry間隔についても、一定間隔で再送する方法に加え、失敗が続く場合に間隔を広げるExponential Backoffなどがあります。

例えば、

Retry 1回目 → 5秒後

Retry 2回目 → 10秒後

Retry 3回目 → 20秒後

以降 → 上限時間内でRetry

という考え方です。

複数のModalityが同時に復旧する環境では、Retryタイミングにランダムな揺らぎ(Jitter)を加えることも有効です。

ただし、無制限のRetryで障害を隠してはいけません。

データを保持してRetryを継続することと、異常をOperatorへ通知することは両立させる必要があります。

8. ModalityからCloudまでを通した設計

ここまで整理すると、データ保持を考えるべき場所は1か所ではありません。

┌────────────────────┐
│ Modality           │
│                    │
│ Data生成           │
│ Local保存          │
│ 送信 / Retry       │
│ ACK確認            │
└─────────┬──────────┘
          │
          │ TCP
          ↓
┌────────────────────┐
│ Edge PC            │
│                    │
│ TCPServer          │
│ Data受信・重複判定 │
│ Data永続化         │
│ ACK返却            │
│                    │
│ Store-and-Forward  │
└─────────┬──────────┘
          │
          │ AMQP over WebSocket
          ↓
┌────────────────────┐
│ Azure IoT Hub      │
└────────────────────┘

この場合、通信断への対策は2段階になります。

通信区間 主な対策
Modality → Edge PC Modality側保存、Retry、Application ACK、Duplicate対策
Edge PC → Cloud Edge側Store-and-Forward、再送、保存容量管理

ここでは、ACKの意味も区間ごとに区別する必要があります。

例えば、Modalityが受信するACKを「Edge PCへの永続化完了」と定義した場合、それはCloudへの到達保証とは異なります。

また、Cloud側も含めてデータの二重処理を避けたい場合には、後続の処理でもMessage IDを活用する必要があります。

システム全体で考えると、基本的にはAt-least-once Delivery(少なくとも1回の配信)と冪等な処理を組み合わせる設計が現実的です。

9. 設計時に確認しておきたいこと

今回のようなシステムでは、以下の項目を事前に確認しておくと、通信断が発生した際のData Lossを防ぎやすくなります。

確認項目 確認内容
送信前保存 Data送信前に元データを保存しているか
Connection失敗 TCP接続失敗時にDataが残るか
ACK Timeout ACK未受信時に再送できるか
ACKの意味 受信完了か、永続化完了か
再起動 Modality再起動後も未送信Dataが残るか
Duplicate 同じMessage IDの二重処理を防げるか
Retry 間隔やBackoffが適切か
Monitoring 通信断が長時間続いた場合に検知できるか
保存容量 長時間の通信断に耐えられるか

特に重要なのは、正常系のテストだけで完了させないことです。

TCP Connection失敗

送信途中の切断

ACKだけが失われる

Edge PCの再起動

Modalityの再起動

通信断が長時間継続

復旧後の一斉再送

これらの状態でもデータが保持され、復旧後に正しく処理されるかを確認する必要があります。

なお、実際の医療機器への適用では、データの重要度や業務上の安全要件に応じて、処理停止・警告・自動復旧の条件を個別に定義する必要があります。

まとめ

今回のポイントは、TCPの信頼性とApplicationのデータ保証を分けて考えることです。

TCPにはACKや再送の仕組みがありますが、それだけでApplicationによるデータ保存や後続処理まで保証されるわけではありません。

また、実際の障害では、ModalityからのSYNがEdge PCに届いていても、Routingの問題によってTCP接続が成立しないケースがありました。

そのため、Modality側から次の仕組みを考える必要があります。

  1. 送信前にDataを保持する
  2. 送信失敗やTimeout後にRetryする
  3. Application ACKの成功条件を明確にする
  4. ACKが失われても安全に再送できるようにする
  5. Message IDによってDuplicateを防ぐ
  6. 一時的な通信断と重大障害を区別する

重要なのは、通信断を完全になくすことではありません。

通信が切れてもデータを失わず、復旧後に処理を継続できる構成にすることです。

これはEdge PCからCloudへの通信だけではなく、データを生成するModality側から設計する必要があります。


次回

これまでは、Edge PCの安定化、通信断検知、Store-and-Forward、Modality側の再送設計など、主に技術的な対策を整理してきました。

次回は少し視点を変えて、これらのReliability・Security・Monitoring対策が、Downtime削減やRemote Support、保守工数削減といった顧客価値にどうつながるのかを整理します。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?