Amazon Web Services ブログ

AWS IoT Device SDK を使用してアクティブな状態を維持するレジリエントな IoT デバイスアプリケーションを構築する

このブログは Diggory Briercliffe によって書かれた Build resilient IoT device applications that remain active using the AWS IoT Device SDKs を翻訳したものです。

はじめに

このブログ記事では、AWS IoT CoreAWS IoT Device SDK、および MQTT プロトコルを使用して、回復力のある Internet of Things(IoT) デバイスアプリケーションを構築する方法に関する推奨事項を説明します。これらの推奨事項は、MQTT クライアントの管理、メッセージの発行と受信、デバイスアプリケーションのプロセスの開始、ネットワーク接続の設定、ソフトウェア更新の実行、および耐障害性のためのハードウェア機能の統合をカバーしています。

おそらくすべての IoT デバイスアプリケーションはサービスダウンにつながる可能性のあるシナリオを経験することになります。例えば、ネットワーク接続のダウンや不安定さ、電源喪失、自社ソフトウェアの障害、デバイスのハードウェア障害、サーバー側の切断、認証エラーなどがあります。

IoT デバイスのアプリケーションを構築する側としては、障害シナリオに強いアプリケーションを構築し、サービスダウンを回避または軽減する責任があります。デバイスアプリケーションをエッジに配置する場合、オンサイトでの対応は現実的でない、あるいは不可能な場合があります。

レジリエンスの目標は、IoT デバイスアプリケーションがアクティブな状態を維持し、仕様どおりに動作することを確認することです。アプリケーションがアクティブでない場合、障害を緩和することができなくなります。レジリエンスに優れたデバイス・アプリケーションは、シームレスに素早くサービスを復旧させることができます。

推奨事項を説明するために、まず AWS IoT 上に構築された基本的なIoTデバイス・アプリケーションを説明します。その後、そのデバイスアプリケーションに今回の推奨事項を段階的に適用する方法を説明します。独自のデバイスアプリケーションを構築する場合、どの推奨事項をいつ適用するかを決定することができます。早期にレジリエンスを実現し、時間とともにレジリエンスを向上させるということができます。

読了時間 8分
学習レベル 上級(300)
使用サービス AWS IoT Core
AWS IoT Device Management
AWS IoT Device SDK

基本的な IoT デバイスアプリケーションの構築

AWS IoT の技術を使用して、基本的な MQTT ベースの IoT デバイスアプリケーションを構築することができます。アプリケーションは最低限、以下をサポートする必要があります。

  • AWS IoT Core を使ったプロビジョニングのアプローチ。
  • AWS IoT Core のエンドポイントアドレスを使用した構成。
  • そのエンドポイントアドレスに接続するためのクレデンシャルの配置。
  • 選択したプロトコル、プログラミング言語、ランタイム環境にマッチする MQTT クライアントとの統合。
  • MQTT クライアントと正しいプロトコル(MQTT または MQTT over WebSocket)を使用した AWS IoT Core への接続。
  • MQTT トピックへのサブスクリプション、メッセージの発行、メッセージの受信。

デバイスアプリケーションを AWS IoT Device SDK と統合し、選択した SDK から MQTT クライアントを使用することをお勧めします。AWS IoT Device SDK にはレジリエンス機能が組み込まれており、AWS IoT Core のレジリエンス機能と密接に統合されています(後述)。

AWS IoT Device SDK を使用した基本的な IoT デバイスアプリケーションの構築に関する完全なガイドについては、チュートリアル「Connecting a device to AWS IoT Core by using the AWS IoT Device SDK」を参照してください。

IoT デバイスアプリケーションを構築したら、それをエッジデバイスにアップロードして実行します。アプリケーションを(エンドポイントと認証情報を使って)正しく構成した場合、AWS IoT Core に接続し、メッセージを発行および受信することができます。

ここまでは順調です。あなたは基本的な IoT デバイスアプリケーションを構築し、動作しています。しかし、何か不具合が起きたらどうでしょうか?ネットワーク接続が失われた場合はどうでしょうか?あるいは、MQTT ブローカーが認証エラーで接続を拒否したら?アプリケーションがクラッシュしたらどうでしょう?

デバイス・アプリケーションがネガティブなシナリオに特別に対処していない場合、アプリケーションが終了し、サービスダウンにつながる可能性があります。そこで、次の推奨事項が役に立ちます。

推奨事項

1)MQTT 接続を管理する

AWS IoT Core、AWS IoT Device SDK、および MQTT プロトコルは、レジリエンスを念頭に置いて構築されています。MQTT クライアントが AWS IoT Core との接続を確立した後、デバイスアプリケーションは、一時的に接続が中断したとしても MQTT メッセージを発行および受信することができます。

MQTT クライアントの設定を微調整するために、メッセージ配信に QoS(Quality of Service)を設定したり、MQTT keep-alive を設定したりできますが、ネガティブシナリオに対する完全なレジリエンスを実現しようとすると追加の開発作業が必要になります。

ここでは、IoT デバイスアプリケーションで MQTT 接続を管理するためのテクニックをいくつか紹介します。

推奨事項 説明
AWS IoT CoreとMQTTの回復機能を活用する

MQTT クライアント (例: AWS IoT Device SDK) および AWS IoT Core MQTT プロトコル接続のドキュメントを注意深くお読みください。

以下の AWS IoT Core および MQTT の機能は、デバイスアプリケーションの耐障害性を高めるのに役立つ場合があります。

  • Persistent sessions – クライアントが一時的に切断された後に再接続すると、AWS IoT Core Persistent session はトピックのサブスクリプションを復元し、QoS 1 でクライアントに発行されたメッセージを配信します。
  • Retained messages – AWS IoT Core Retained message は、オフライン時間が長かった後でも、オンラインになったときにクライアントに発行されたメッセージを配信できます。
  • Last Will and Testament (LWT) – AWS IoT Core LWT は、クライアントが突然切断した場合にメッセージを配信でき、クラウドアプリケーションはこのメッセージに基づいて処理できます。
  • QoS – デバイスアプリケーションが QoS 1 でメッセージを発行する場合、メッセージ配信の成功または失敗を確認でき、アプリケーションはそれに応じて対応できます。
MQTT クライアントをカプセル化する デバイスアプリケーションソフトウェアで、MQTT クライアントをカプセル化し、クライアントのライフサイクルを完全に制御します。また、クライアントの作成、設定、および起動に必要なその他の機能もすべて制御します。クライアントが完全にカプセル化された後、アプリケーションがアクティブである間、クライアントを複数回作成、構成、使用、および最終的に破棄できます。
MQTT クライアントイベントを処理する デバイスアプリケーションが MQTT クライアントイベントをリッスンし、それに対処するように設定します (後述)。有用なイベントには、接続、切断、エラー、中断、および再開が含まれます。
MQTT の接続状態を追跡する MQTT 接続の状態を追跡するフラグを維持します。これには、接続、切断、割り込み、および再開のイベントを使用します。接続がない場合に、あなたのデバイスアプリケーションがサブスクリプションとメッセージをどのように管理するかを調整します (次の推奨事項を参照)。
サーバー側の切断から回復する ある MQTT ブローカーが MQTT 接続を切断することを決定するかもしれず、これは起こり得ると考えるべきです。AWS IoT Core メッセージブローカーでもそうです。デバイスアプリケーションは、いつでも何度でも切断を処理できるようにしておく必要があります。しかし、実際には、MQTT 接続は何日も何週間も開いたままにしておく必要があります。
認証失敗から回復する 認証の失敗がデバイス・アプリケーションにとって致命的であると決めつけないでください。認証失敗の中には、サーバー側のポリシーがまだ有効でない場合など、一時的なものもあります。認証に失敗して接続できなくなった場合、アプリケーションが回復することを確認してください(接続の健全性チェックのテクニックを参照)。
MQTT クライアントエラー/例外を処理する すべての MQTT クライアントエラーと例外をキャッチします。どちらが致命的か、どれが警告または一時的なものかを観察し、それに応じて適応します。コネクションが使用できなくなった場合はそのコネクションを切断します。
一定間隔で接続ヘルスチェックを実行する 間を置いて、MQTT 接続の正常性を確認し、修正します。たとえば、次のようになります。

  • 認証情報がない場合は、後でもう一度確認してください。
  • MQTT クライアントがない場合は、作成してみてください。
  • MQTT 接続がない場合は、作成してみてください。
  • MQTTコネクションが接続されていない場合は、接続してみます。
接続再試行の方法を定義する 接続試行を再試行するときは、エクスポネンシャルバックオフ戦略を使用します。これにより、複数のクライアントが同じ根本的な問題の影響を受ける場合に、過度の接続試行を防ぐことができます。

2) MQTT サブスクリプションとメッセージフローを管理する

メインデバイスのアプリケーションロジックがメッセージを発行する場合、またはメッセージの受信を想定している場合、MQTT 接続の低レベルのレジリエンスは問題にならないはずです。アプリケーション設計にモジュール方式を採用することで、メインのアプリケーションロジックと MQTT クライアントを疎結合な別個の関心事として扱うことができます。

このような関心事の分離を可能にするために、メインデバイスのアプリケーションロジックと MQTT 接続を管理するロジックの間にソフトウェア層を導入できます。このレイヤーは、接続が使用可能になるまで送信メッセージをバッファリングでき、基盤となる MQTT クライアントまたは接続の状態に関係なく、受信メッセージのサブスクリプションが正しく構成されていることを確認できます。

デバイスアプリケーションで送信メッセージをバッファリングすることにした場合、AWS IoT Device SDK を使用してメッセージをパブリッシュするときに、これがどのように動作するかを検討する必要があります。アプリケーションは各メッセージのパブリッシュの成功または失敗を追跡し、それをアプリケーション内のメッセージバッファを更新する際に使用する必要があります。アプリケーションが QoS 1 でメッセージをパブリッシュしている場合、接続が一時的にオフラインになったときに SDK がそれらのメッセージをバッファリングすることが期待できます。実装のガイドとして、選択した AWS IoT Device SDK のドキュメントを参照してください。SDK を使用して QoS 1 でメッセージを発行する方法と、関連する PUBACK 応答を受信する方法を確認してください。

3) IoTデバイスのアプリケーションを管理する

これで IoT デバイスアプリケーションが内部的にレジリエンスを持つようになったので、次はアプリケーションが実行される環境に焦点を移すことができます。

IoT デバイスアプリケーションが実行されるランタイム環境はあなたの要件によって異なる場合がありますが、以下のレジリエンス手法はすべてのタイプのランタイム環境にとって重要です。

レジリエンス手法 説明
プロセス管理 (PM) アプリケーションプロセスを自分で管理する代わりに、よく知られたプロセス管理ソフトウェアを使用してみてください。例として PM2Docker が含まれます。
グレースフルスタートとシャットダウン すべてのオペレーティングシステムには、アプリケーションを起動およびシャットダウンするメカニズムがあります。アプリケーションは、アプリケーションをデプロイするオペレーティングシステムにとって慣用的な方法で、これらのメカニズムと統合する必要があります。特に、アプリケーションが依存するすべてのリソースを利用できるようにし、アプリケーションが適切なタイミングで開始および停止できるように、アプリケーションに適したランレベルを選択します。
オペレーティングシステムシグナル オペレーティングシステムはアプリケーションにシグナルを送ることができます。アプリケーションはこれらのシグナルを尊重し、それに応じて反応する必要があります。たとえば、オペレーティングシステムがアプリケーションを終了するように通知した場合、アプリケーションは終了する前にリソースを整理できます。整理するリソースの例は、MQTT 接続を正常に終了し、バッファリングされたメッセージをローカルストレージにフラッシュすることです。
アプリケーションロギングとメトリクス アプリケーションは、有用な運用情報をログに記録する必要があります。アプリケーションが対応すべきネガティブなシナリオがある場合、これらの詳細をログに記録すると、アプリケーションにレジリエンスがあることを確認するのに役立ちます。ロギングは、まだ軽減していないシナリオを知るのにも役立ちます。

4) ネットワーク接続を管理する

デバイスにネットワーク接続がない場合、IoT デバイスアプリケーションは MQTT 接続を確立できません。最大限の接続稼働時間を達成するために、ネットワーク接続が慎重に構成および管理されていることを確認することは、デバイスアプリケーションがネガティブなシナリオに対して回復力があることを保証する上で重要な部分です。

ネットワーク接続のレジリエンスを自分で実装しようとしないことをお勧めします。それには多大な実装、テスト、および継続的なメンテナンス作業が必要となるためです。代わりに、動作することがわかっている既存のソリューションを使用できます。例として、多くのシステムには、Network ManagerModem Manager のパッケージがプリインストールされています。これらのパッケージは連携してデバイスのネットワーク接続を維持し、ネガティブなシナリオを軽減します。接続失敗時のフォールバック戦略を構成して、代替ネットワークを選択できます。

ネットワーク接続に携帯電話ネットワークを使用している場合、ネットワーク間のローミングなど、プロバイダーが提供する高度な機能を利用できる場合があります。クラウド側では、デバイスフリートの接続ステータスを検査および分析し、最大限のレジリエンスを得るようにデバイス接続オプションを調整できる場合があります。一部のベンダーは、デバイスにシグナルを送信する機能を提供しており、デバイスアプリケーションが停止している場合に回復を実行するために使用できます(リモートブートの開始など)。

5) ソフトウェアアップデートの管理

IoT デバイスアプリケーションとデバイスソフトウェアをリモートで更新できることは、IoT アプリケーションのレジリエンスをサポートするための重要な要素です。

IoT デバイスアプリケーションはデバイスへの最初のデプロイで完成することはほとんどありません。ソフトウェアアップデートを使用して、アプリケーションに新機能とバグ修正を展開する必要があります。同様に、デバイスのオペレーティングシステムの更新が必要になる可能性が高いため、セキュリティ修正プログラムを迅速に展開できることが特に重要です。

AWS IoT Device Management Job を使用してソフトウェア更新機能を構築できます。これを使用して、作成したエージェントデバイスアプリケーションで、デバイスに送信してデバイスで実行できるリモート操作を定義できます。ソフトウェアアップデートを実装する場合、メインのデバイスアプリケーションとは別に実行されるエージェントデバイスアプリケーションを作成することがよくあります。このエージェントアプリケーションも、メインアプリケーションと同様にレジリエンスを考慮して設計する必要があります。

6) デバイスハードウェアのレジリエンス機能を有効にする

お使いの IoT デバイスに、ウォッチドッグタイマーや UPS デバイスなど、レジリエンスを支援する技術が統合されているかどうかを確認します。

デバイスにウォッチドッグタイマーがある場合、デバイスが応答しなくなったり、障害が発生したりした場合に、デバイスを再起動するなどの措置を取るようにウォッチドッグを設定することができます。

デバイスが無停電電源装置(UPS)を介して電力を供給されている場合、電源が失われるときにデバイスアプリケーションに信号を送るように設定できるかもしれません。デバイス・アプリケーションは、シャットダウンを指示したり、クラウドアプリケーションに状況を通知したりすることができます。

7) ディザスターリカバリーと高可用性のための戦略を採用する

最後に、IoT デバイスアプリケーションのディザスターリカバリー(DR)とハイアベイラビリティ(HA)戦略を採用することをお勧めします。良い出発点は、Disaster Recovery for AWS IoT Implementation GuideDisaster Recovery for AWS IoT Solution です。AWS IoT Core のレジリエンスに対するアプローチを理解するには、AWS IoT Core の耐障害性を読むとよいでしょう。

まとめ

このブログ記事では、AWS IoT Core と AWS IoT Device SDK を使用してレジリエントな IoT デバイスアプリケーションを構築するのに役立ついくつかの推奨事項と詳細なテクニックを紹介しました。デバイスアプリケーションはネガティブなシナリオを経験することになり、これらを軽減するのはあなたの責任です。上記の推奨事項に従うことで、デバイスアプリケーションはよりレジリエントになり、ネガティブなシナリオにおいてもアクティブな状態を維持することができます。

さらに詳しい情報としては、IoT Lens from the AWS Well-Architected Framework をお勧めします。特に Design for offline behavior の設計原則はレジリエンスに関連しています。

著者

Diggory Briercliffe は、Amazon Web Services の Senior IoT Architect として、IoT 分野のお客様をサポートしています。

この記事はソリューションアーキテクトの井上が翻訳しました。