Windows Azure サービス バスとモノのインターネット
Bruno Terkaly
Ricardo Villalobos
マシン ツー マシン (M2M) コンピューティングは、すべての開発者やアーキテクトが採用する必要があるテクノロジとして、急速に台頭してきています。多くの研究によれば、2020 年までに世界中のデバイスは数百億台 (地球上の全人類が 1 人 6 台保有する規模) に達するとされています (bit.ly/M2qBII、英語)。このような現象の理由の 1 つは、製造販売を視野に入れた消費者向けデバイスや商用デバイスのプロトタイプを、個人発明家や愛好家が今までにないほど簡単に作成できるようになったからです。ハードウェアの開発もソフトウェアの開発も、驚くほど安価に始められるようになりました。100 ドルもあれば、Arduino または Raspberry PI を注文できます。
しかし、価格相応の機能しか得られないうえに、これらのデバイス (特に Arduino) はさまざまなデバイス機能の中でもローエンドに位置しています。32 KB のフラッシュ ストレージと 4 KB の RAM では、Web スタックのごくシンプルな機能しか実行できません。Arduino は、小型チップ、メモリ、およびストレージを搭載した、オープン ソースのマイクロコントローラーです。Arduino のソフトウェアは、標準的なプログラミング言語コンパイラと、マイクロコントローラー上で実行するブート ローダーです。Arduino にプラグイン型拡張ボードを追加すると、モーター コントロール、GPS、イーサネット、LCD ディスプレイ、センサー、アクチュエーターなどに接続できます。もう少しお金を出せば、GNU/Linux OS のいずれかのバージョンと 256 KB の RAM を搭載した、より強力な Raspberry PI を購入できます。
これらのデバイスは、別のシステム (たとえば、データを受信してコマンドを送信するクラウド バックエンド) と接続しない限り価値がありません。しかし、クラウドで実行するアプリケーションからこれらのデバイスに接続して通信し、デバイスを管理しようとすると、特殊な問題が生じます。デバイス数が膨大でバッテリ残量と帯域幅が制限されているため、クラウド開発者はすべてのオプションを慎重に考慮しなければなりません。
この記事では、アドレス指定機能、帯域幅、およびセキュリティに関する主な問題を、開発者がどのように解決しようとしているかについて説明します。まず、IPv6 と仮想プライベート ネットワーク (VPN) をシンプルかつ効率的で安全だと見なす考えが正しくないことを証明し、このような問題の対処に最適な製品として、Windows Azure サービス バスを提案します。さらに、概念を理解しやすいように、クラウド バックエンドとの通信時にクライアント デバイスで使用できる 4 つのパターンを示します。最後に、Advanced Message Queuing Protocol (AMQP) 1.0 に対するサービス バスのサポートを簡単に紹介します。AMQP は、デバイス ツー クラウド コミュニケーション用の、相互運用可能で効率的なプロトコルです。
長年、安全な接続とは、IPv4 と TCP/IP の併用に VPN を組み合わせることでした。この対策はある程度成功しましたが、時代遅れの兆候が現れてきています。まず、デバイスで使用する一意の IP アドレスをパブリック インターネットに公開することは難しく、既に IP アドレスが枯渇しかかっています。このアプローチの根っからのファンは、IPv6 が救世主になると信じています。一般的な考えでは、デバイスに一意の IP アドレスを与えれば困難な問題がすべて解決するとされています。残念ながら、これで解決できるのは全体のうちごく一部の問題だけです。各デバイスに一意の IP アドレスを与えることは、決して、多くの人が待ち望んでいた特効薬ではありません。
簡単に言えば、IPv6 と VPN は、接続デバイスがあふれかえった世界では多くの問題を引き起こします。特に問題になるのが帯域幅です。デバイスとネットワークの間で頻繁に通信が発生するため、トラフィックが過剰になります。さらに、典型的な HTTP 要求/応答アプローチをすべてのメッセージに使用すると、多くのデバイスのバッテリ残量に悪影響が及びます。最も重大な問題は、セキュリティを保証できないことでしょう。VPN は、シナリオによってはまったく安全ではありません。解決策を示す前に、これらの問題についてもう少し詳しく説明しましょう。
クラウド バックエンドとの通信時に過剰なネットワーク トラフィックが生じるデバイスは、問題を引き起こしがちです。帯域幅には費用がかかり、頻繁に通信するデバイスが多いと莫大な額になることもあります。さらに、データが多いほど CPU を酷使することになります。つまり、モバイル デバイスの貴重なリソースである電力の消費量が多くなります。Wi-Fi トランスミッターと SIM カードを搭載しているバッテリ駆動型デバイスのほとんどは、データを送受信していない期間は低電力のスリープ モードに移行する必要があります。この省電力ポーリング機能は、IEEE 802.11 標準で定義されています。デバイスがスリープ モードの間、データはバッファーされます。デバイスのスリープ モードが解除されると、バッファーされたデータが送信されます。ネットワーク通信を頻繁に行うと、バッファーが満杯になり、デバイスのスリープ モードがすぐに中断されます。
HTTP 要求/応答アプローチは、HTTP 要求/応答インフラストラクチャ全体に対するペイロードのサイズを考えると、驚くほど無駄が多くなる場合があります。たとえば、気温、圧力、GPS 座標などの単純な数値をデバイスからクラウドに報告する必要があるとしましょう。このバイナリ データのサイズはおそらくたった数バイトですが、HTTP POST は一般的に少なくとも 500 ~ 1,000 バイトあり、要求ヘッダーだけでも 200 ~ 2,000 バイトに達します。もちろん一部の開発者は、HTTP 要求本文のオーバーヘッドを回避するために HTTP ヘッダーにすべての情報を詰め込むなど、工夫を凝らしています。しかし、これでも十分ではなく、セキュリティ資格情報を送信する必要がある場合は HTTP 要求サイズの肥大化を避けられません。
納得していただけるよう、簡単な計算をお見せしましょう。デバイスで気温データを 5 秒ごとに送信する必要があり、気温データのペイロードは多めに見積もっても 20 バイトであるとします。デバイスからクラウドへの気温データ自体の送信量は、24 時間で約 350,000 バイトになります。HTTP 要求/応答のエンベロープも追加すると、送信量が毎回 800 バイト増加し、41 倍になります。つまり、たった 350 KB の気温データではなく、14 MB 以上のデータをクラウドに送信することになります。このため、数千ものデバイスをサポートしている場合はコストが非常に高くなります。
最大の誤解は、VPN が本質的に安全であるという考えでしょう。実際には、VPN ネットワークは危険な場合があります。特に、VPN に接続しているデバイスを製造元や携帯電話会社がすぐ物理的に制御できないときは危険が高まります。1 台でもデバイスが不正侵入を受けると、同じ VPN に接続しているすべてのデバイスが危険にさらされます。信頼されていないユーザーが接続デバイスへのアクセスに成功すれば、そのユーザーはデバイスを使用して内部リソースの参照や攻撃ができるようになります。これらの欠陥があるにもかかわらず、多くの通信事業者は、しばしば VPN を唯一のオプションとして提供しています。
Windows Azure サービス バス アプローチ
Windows Azure サービス バス アプローチは、このような問題に対する優れた解決策をいくつか提供します。サービス バスを使用すると、デバイスはキューにメッセージを配置可能なインターネット上のエンドポイントにすぎなくなるので、安全性が向上します。デバイスから、クラウド サービス内の他の保護されたネットワーク リソースにはアクセスできません。さらに、デバイス接続にサービス バスを使用すると電力消費量が低下します。これは、定期的にデバイスのスリープを解除してキューから待ち状態のメッセージを取得するので、デバイスがスリープ モードに移行できる頻度が多くなるためです。
サービス バスには、さらに便利な次の機能があります。
- デバイスの通信と対話をクラウド サービスから切り離す
- バックエンド サービスの複数インスタンス間での負荷平準化と負荷分散を可能にする
- 重複するメッセージを特定する
- メッセージを論理グループ (セッション) にまとめる
- トランザクション動作と原子性を実装する
- 順序に従ったメッセージ送信をサポートし、各メッセージの有効期間を指定する
- トピックとサブスクリプションを使用して、簡単にパブリッシュ - サブスクライブ シナリオに拡張する
クラウド バックエンドとのデバイスの接続方法と通信方法をより具体的に把握するには、図 1 を参照してください。この図は、特殊用途デバイスを大きなアーキテクチャに組み込む方法を示しています。模範例として、ここでは OpenSprinkler という、天気を確認してから散水を決定できるオープン ソースでインターネット ベースの散水または灌漑用バルブ コントローラーを使用します。このコントローラーは Arduino パーツを使用して構築しています。図 1 では、Arduino がホーム ネットワークをインターネット接続として使用してスプリンクラー システムを制御し、クラウド バックエンドと通信しています。
図 1 Arduino スプリンクラー システムの参考アーキテクチャ
接続の問題を解決する
Windows Azure サービス バスには、アドレス指定機能とネットワーク接続の問題を解決する、優れた機能があります。場合によっては Arduino デバイスが NAT 層の背後に配置され、クラウド サービスからのアクセスが難しいことがあります。さいわい、サービス バスはリレー サービスとして動作し、クラウド バックエンドのプロキシとして機能するため、接続が大幅に簡潔になります。さらに、サービス バスはキュー、トピック、およびサブスクリプションを備えているので、クラウドとデバイスの間で送信されるメッセージのイベント ハブとして機能します。リレーとして動作するキューの分離された性質を利用すれば、一時的な接続であっても、デバイスとクラウドの間で非同期にメッセージを送受信できます。セキュリティについては、SharedAccessSignature、SharedSecret、SAML、または SimpleWebToken を使用してデバイスを認証できます。
図 1 では、1 つ以上のワーカー ロールがサービス バスのメッセージング キューから読み取りを行っている可能性に注目してください。ワーカー ロールは、判断を下してデバイスにコマンドを発行できます。他のワーカー ロールは、National Weather Service などの別のシステムから天気情報を取得している可能性があります。また、ワーカー ロールがすべての未処理の受信イベントを NoSQL データベース (MongoDB など) に保存している可能性もあります。
図 1 には、Web ロールと対話して散水スケジュールを設定するモバイル ユーザーも含まれています。モバイル ユーザーは、Windows Azure モバイル サービス (WAMS) からプッシュ通知を受信できます。WAMS は、Windows プッシュ通知サービス (WNS)、Microsoft プッシュ通知サービス (MPNS)、Apple プッシュ通知サービス (APNS)、Google Cloud Messaging for Android (GCM) など、主な通知ネットワークをすべてサポートしています。WAMS を使用すると Windows、iOS、および Android のサポートが容易になります。
アーキテクチャの機械学習部分もこの図から想像できます。Windows Azure は Linux VM をサポートでき、PyMongo (MongoDB 用の Python ドライバー) を構成してさまざまなデバイスから生成されるイベント ストリームを読み込むことも、PyML の機械学習手法を使用してイベント ストリーム データに関するパターンを発見したり予測したりすることも簡単です。クラウド サービスでは、一定の予測またはパターンに基づいて、散水の開始、停止などのコマンドをデバイスに送信するかどうか選択できます。
データ送受信用の主なエンドポイントであるメッセージング システムは、拡張可能です。なぜなら、デバイスから単一のメッセージ ストリームを送信し続けながらも、新しいシステムごとに新しいサブスクリプションをサービス バス トピックに追加して、これらのシステムで同じメッセージ ストリームを使用できるからです。新しいシステムは、リアルタイム分析、機械学習、および既に述べた他のシナリオに使用できます。
クラウドと通信する
クラウド サービスと通信するためにクライアントで使用できるパターンは 4 つあります。4 つのパターンの概要を図 2 に示します。
図 2 デバイス/クラウド サービス間通信の 4 つのパターン
パターン | 概要 | 例 |
テレメトリ | クライアント デバイスがデータをクラウド サービスに (一方向に) 送信します。 | 気温に関するメッセージをデバイスがトピックにパブリッシュします。クラウド サービスはパブリッシュされた気温メッセージの一部または全部をサブスクライブします。 |
問い合わせ | クライアント デバイスがクエリをクラウド サービスに送信し、応答を受信します。 | 天気に関する問い合わせをデバイスがトピックにポストして、天気予報を問い合わせます。クラウド サービスは問い合わせをサブスクライブし、メッセージの応答をクラウド サービスのトピックにポストします。このトピックをデバイスがサブスクライブします。 |
コマンド | クラウド サービスがコマンドをクライアント デバイスに発行し、クライアント デバイスが成功または失敗の応答を返します。 | デバイスがサブスクライブするトピックに、クラウド サービスが気温に関するメッセージまたはコマンドを発行します。次に、デバイスが散水を開始または停止し、クラウド サービスへの返答として、応答をトピックにポストします。 |
通知 | デバイスの動作に対して重要な一方向の帯域外通知を、クラウド サービスがクライアント デバイスに発行します。 | クラウド サービスは、デバイスがサブスクライブするトピックにメッセージをパブリッシュして、時間のリセット メッセージをデバイスに送信します。 |
4 つのパターンはどれもサービス バス トピックとサブスクリプションを利用しています。通信の方向 (デバイスからクラウド サービスへ、またはクラウド サービスからデバイスへ) に応じて、デバイスはトピックをサブスクライブする場合もあればトピックにパブリッシュする場合もあります。トピックはメッセージ送信メカニズムの一種ですが、サブスクリプションはメッセージの取得に使用します。サブスクリプションに関するフィルター ルールを作成すれば、取得メッセージを細かく制御できます。クラウド サービスのワーカー ロールは、メッセージをトピックにパブリッシュする処理にも、サブスクリプションからメッセージを取得する処理にも使用できます。
スペースの制約上、この記事ですべてのパターンについて説明することはできないので、1 つに絞って説明します。図 3 に、コマンド パターンの参照実装を示します。これは、ビル 1 とビル 2 のデバイスがメッセージ (コマンド) をサブスクライブし、応答をトピックにポストして返せることを示しています。クラウド サービスのワーカー ロールが気温および遮光コマンド トピックにメッセージをパブリッシュできることと、特定のデバイスが気温制御メッセージと遮光制御メッセージを別々にサブスクライブできることに注目してください。サービス バス トピックとサブスクリプションをさまざまな組み合わせで使用して、メッセージ フローを適切に区切ることができます。
図 3 コマンド パターンのアーキテクチャ
AMQP と相互接続性
先日 Windows Azure サービス バス チームは、メッセージ指向ミドルウェア用のバイナリ アプリケーション層を備えたオープン標準、Advanced Message Queuing Protocol (AMQP) 1.0 のサポートを発表しました。AMQP の主なメリットは、相互運用性が高いことと、バイナリ形式を接続に使用してペイロード サイズを最小限に抑えられることです。
AMQP は、信頼できるメッセージ送信、キューイング、ルーティング、パブリッシュ/サブスクライブなどをサポートします。AMQP はネットワーク間のデータ ストリーミングを対象とする回線レベルのプロトコルなので、ツールが準拠していれば実装言語に関係なくデータを操作できます。このため、オープンな標準プロトコルを使用するクロス プラットフォームのハイブリッド アプリケーションが実現します。ライブラリを使用すれば、.NET、Java、Python、および PHP をサポートしながら、さまざまな言語、フレームワーク、および OS を組み合わせることができます。詳細については、Windows Azure サンプル ページ (msdn.microsoft.com/ja-jp/library/windowsazure/jj841074.aspx) を参照してください。AMQP は軽量で相互運用性を確保するよう設計されているため、クラウド バックエンドに接続する必要があるさまざまな最新デバイスの多くに適しています。
しかし、AMQP は、現在の Arduino には荷が重いソフトウェアです。Arduino のメモリ、ストレージ、および処理能力は十分ではありません。AMQP を実行するには、トランスポート層セキュリティ (TLS) という、TCP 経由での通信セキュリティを提供する暗号化プロトコルをサポートする必要があります。TLS は X.509 証明書 (非対称暗号化) を使用して、ネットワーク上の通信相手の ID を検証します。さらに、多くの場合は Apache Qpid Proton というクライアント ベースのメッセージング ライブラリを使用して AMQP を組み込み、ルーター、ブリッジ、およびプロキシ経由の通信を簡略化します。こうした点から質問が浮かんできます。どうすれば、サービス バスのメッセージング インフラストラクチャのメリットを享受しながら、クラウド バックエンドに接続するローエンドのデバイスをサポートできるでしょう。
選択肢の 1 つは、さらにお金を出して Raspberry PI を購入することです。そのつもりがない場合は、もっと創造力を働かせる必要があります。手始めとして Clemens Vasters のコード (bit.ly/1acvLdS、英語) を利用すれば、Arduino でコマンドを受信してマイクロコンピューターの LED ライトを点滅できます。このコードは、Arduino の接続先 TCP エンドポイントを提供する、デバイス ゲートウェイを実装しています。NAT と Windows Azure ロード バランサーを経由した通信を維持するには、クラウド サービスから Arduino に 235 秒 (4 分弱) ごとに ping を送信する必要があります。詳細については、Vasters の C# プロジェクト、LedBlinkerServer を参照してください。
次回のコラムでは、コードのしくみと、Arduino でサービス バスやメッセージを送受信する方法について詳しく説明します。
まとめ
今月のコラムでは、デバイスとクラウド サービスの間で信頼できるメッセージ交換を確立するために使用できる、4 つのパターンを紹介しました。また、AMQP という、相互運用性の向上と帯域幅の最小化に役立ち Windows Azure サービス バスで完全にサポートされているオープン ソース メッセージ キューイング プロトコルを紹介しました。
接続デバイスのすばらしい新世界について理解する手助けをしてくれた、Clemens Vasters と Abhishek Lal に感謝します。クラウド サービスに接続した特殊用途デバイスの世界は、疑う余地なく急成長しています。クラウド サービスとの従来の通信方法を再評価する必要があります。セキュリティ、帯域幅、ネットワーク信頼性、および相互運用性は、アーキテクトや開発者が M2M の世界で直面する特殊用途デバイスの問題の一部でしかありません。Windows Azure サービス バスを使用すれば、このような問題への対処が簡単になります。
Bruno Terkaly は、マイクロソフトの開発者エバンジェリストです。彼の深い知識は、多数のプラットフォーム、言語、フレームワーク、SDK、ライブラリ、および API を使用してコードを作成し、現場で長年の経験を積むことで得られたものです。コードの作成、ブログ、クラウド ベースのアプリケーション構築 (特に、Windows Azure プラットフォームの使用) に関するライブ プレゼンテーションに携わっています。ブログは、blogs.msdn.com/b/brunoterkaly (英語) で公開されています。
Ricardo Villalobos は、経験豊かなソフトウェア アーキテクトとして、多くの業界の企業用アプリケーションを 15 年以上にわたって設計および作成しています。さまざまな技術認定資格の保持者であり、ダラス大学で経営管理の修士号を取得しています。彼はマイクロソフトの DPE Globally Engaged Partners チームのクラウド アーキテクトを務め、世界中の企業の Windows Azure ソリューション実装を支援しています。ブログは blog.ricardovillalobos.com (英語) で公開されています。
Terkaly と Villalobos は、大規模な業界カンファレンスで共同講演を行っています。彼らは、Windows Azure の詳細に取り組む読者の皆さんに、可用性に関する問い合わせを奨励しています。Terkaly の連絡先は bterkaly@microsoft.com (英語のみ) で、Villalobos の連絡先は Ricardo.Villalobos@microsoft.com (英語のみ) です。
この記事のレビューに協力してくれたマイクロソフト技術スタッフの Abhishek Lal および Clemens Vasters に心より感謝いたします。