【セッションレポート】Nature Remoの裏側 ~ AWSとWeb技術をIoTの世界でフル活用する【#AWSDevDay】
こんばんわ、札幌のヨシエです。
今週開催されたAWS主催のAWS DevDay Tokyo 2019に参加しました。
以前より自宅で利用しているNature Remoに関してのセッションを拝聴しましたのでレポートとして書き出します。
登壇者
Nature 株式会社 松木 雅幸 氏(@songmu)
アジェンダ
- Nature 及びNature Remoの紹介
- システムアーキテクチャ解説
- ECS活用事例
- 現在の課題
- その他の細かい取り組み
会社と製品
Nature 株式会社
- 製品として「Nature Remo」、「Nature Remo mini」の2種類を販売している
Nature Remo/mini
- スマートリモコンとしてスマートフォンやスマートスピーカーから赤外線で家電などを操作出来る製品
- スマートフォンの位置情報を利用して家電を操作することが出来るので、外出先から家に近づいたタイミングでアプリが自動的にエアコンをONしてくる
- Nature RemoとNature Remo miniの差は主に搭載しているセンサーが違う
Nature RemoE
- スマートエネルギーハブ
- ECHONET Lite プロトコルを利用して、自宅の電力状況や太陽光発電などの情報をアプリケーションにて見えるようにする
- 国内のスマートメーターとHEMSをつなぐ標準プロトコル
- 家庭WiFiにつないでUDPやWi-SUNなどで通信を行う
Nature Remo and Go
- Nature RemoはいわゆるIoT製品のスマートリモコン
- スマートフォンやスマートスピーカーから家電操作が出来る
- センシング(位置情報)や設置場所の温度/湿度を元に家電操作
Nature Remoの仕組み
- Nature Remoは自宅のWiFiに接続してローカルIPは保持
- Nature Remo自身からインターネットに出ていくことが出来るが、インターネットを経由して設置場所のNature Remoでリクエストを受け付けることは容易じゃない
- しかし、屋外のスマートフォンやスマートスピーカー、ルールなどに大して素早く反応する必要がある
- Nature Remo実機に搭載されているマイコン上では「C言語」を動かしているので複雑なことをやらせたくなかった
実装に向けて検討した点
- UPnPなどによるポート開放とDDNSの組み合わせ
- セキュリティの不安が残った
- UDPホールパンチングなどのNAT超え技術を用いたP2P
- 接続状態を維持することが難しそう、特にスマートフォンのような移動体がポイントだった
- これらはかっこいいけど、現実的ではない
現実的な実装
- スマホアプリからはAPIリクエストを実装
- 開発者向けAPIも提供
- Nature社が管理しているクラウドシステムがNature RemoにWebsocket経由で指示を送る
なぜWebSocketを選択したのか?
- リアルタイムに双方向通信が出来る
- Nature社は多くのWebエンジニアが在籍しており、「普通の」Web技術として認識されていた
- 接続や切断時はNature Remo側が制御する
- 常時接続になるため、システムの接続管理が大変
- 目安として、10万台 * 増加の一途 = ???
具体的なアーキテクチャ
- ECSに「Worker」「API」「Stream」の機能に分離したGoが動くコンテナが動いている
- APIコンテナは指示を受け取るとRedisへイベントをPublishする
- StreamコンテナがRedisをSubscribeしてNginx経由でNature remoにAPIを実行する
- この実装によって相互通信を行わない疎結合を実現した
- サービスディスカバリにはHashiCorp社のConsulを利用している
ECS部分の使い方
コンテナへのデプロイフロー
デプロイフローとしては以下の順で実行されている
- github(PR/Merge)
- CircleCI(test/build)
- ECR(build/push)
- ecspresso deploy
- ECSで動作しているコンテナへデプロイする
ecspresso(kayac/ecspresso)とは
- ecs-deployからの乗り換え先としてちょうど良い
- 既存のTask Definitionを利用できる
- シームレスに移行可能
- CircleCI上で実行してコンテナDeploy
- Task(コンテナ)へのサイドカー追加やパラメーター更新がreviewableになったのかがよかった
- PullRequestを出して、--no-wait optionをPRで出している
- CIの都合でデプロイを実行したらすぐにコマンドが終わったことが経緯
課題や今後取り組みたいこと
- 歴史的経緯でALBに接続できない
- Nginxに直つなぎしている
- Nginxはstreamにproxyしているのでエフェメラルポートの都合により6万接続程度が上限
- コネクション数管理が煩雑
- 今後はALBに一本化することを考えている
- DNSベース(エンドポイント)のアクセスが可能で、自動で内部ノードを増やしてくれる
ServiceDiscovery
- Consulのサービスディスカバリはカッコいいが、不安定な状況に陥った時のリカバリが難しくバージョンが古い
- 今後はAWSサービスのCloudMapなどに切り替えていきたい
- streamをデプロイすると一斉にNature Remoとの接続を切断することになるため、再接続ラッシュとなる
- 一時的にAPIが過負荷気味になる
- コンテナがコネクションを維持したまま、ローリングで入れ替えていく方法を模索中
LogMonitoring
- 現在はzap(uber-go/zap)でJSONログをCloudWatchLogsへ出力している
- CloudWatchLogs Insightが安定して便利、しかしコスト面に注意している
- 一部のログはアプリから直接FireHose経由でS3にログを送信
- Athenaを利用して調査を行っている
AWS IoT
- 現在の接続方法から無理して使う必要はないと考えているが、選択肢を広げて必要に応じて使いたい
Migration
RDBのマイグレーションでgooseを利用
- 積み上げ式のMigrationは少し懸念を持っている
- Schemalexに乗り換えを件途中
minor topic
持続可能な開発のためにNature社への入社後に取り組んだこと
- Go modulesを導入
- depから移行
- Dependabotを導入
- 依存ライブラリのバージョンが上がっていたらpull requestを起票してくれるサービス、無償で使える
- 依存ライブラリを最新にし続けたい
- GoはALPHA版として考慮するべき点が数点存在する
- ECS Scheduled task管理のためのツールecsched
- バッチ類はECSのScheduled Taskを利用しているがそれをバージョン管理したいという動機
まとめ
- サーバーサイドはほぼ全てGoを利用、割と普通のWeb技術を使って実現
- インフラはAWSによせて、もっと寄せていきたい
- 本質的なサービス開発に注力したい
- Websocketの接続管理周りがチャレンジング
- サービスも急成長中
- 開発体験をあげるためにも色々やっています
最後に
自分が利用している製品がAWSで動いており、かつ今回のイベントで内部アーキテクチャを伺う機会があって正直驚きました。
うすうす気になっていたのがNature Remoがどのようにして外部からのリクエストを処理しているのかが気になっていた事が解消されたこと、ECS上のデプロイフローは他業種でも活用できるパターンの構成と思います。
またログ周りに関してはわかり見の部分があったので先日発表されたFirelensを利用されるとコスト面にいい影響を与えるかと思い
コンテナ周りの構成を考えたくなるセッションでした。
最後に自宅に設置されているNature Remoです。
引っ越し時にコーピーをこぼして以降、このシミは消えなくなりましたが夏は自宅から200m以内に入るとちゃんとエアコンが起動してくれて働き者です。