ݫൿɿຊࢿྉͷҰ෦·ͨશ෦ΛɺNatureגࣜձࣾͷڐՄͳ͠ʹɺෳɺసࡌ͢Δ͜ͱΛې͡·͢ɻIntroduce aboutSeptember 3, 2019NatureגࣜձࣾRemoͷཪଆAWS DevDay Tokyo 20194th Oct, 2019~ AWSͱWebٕज़ΛIoTͷੈքͰϑϧ׆༻͢Δ
View Slide
2Me• 松⽊ 雅幸 (id:Songmu)• Nature 株式会社 取締役CTO• https://songmu.jp/riji• https://github.com/Songmu• 好きな⾔語はGoとPerlと中国語• 3 Times ISUCON Winner• 著書に「みんなのGo⾔語」等
3Created Miscellaneous Go Tools• maltmill• ツールを簡単にhomebrewで配布するためのツール• horenso• バッチジョブのためのラッパー• peep• プロセスの終了通知をしてくれる君• gocredits• Goのツール配布時に依存ライブラリのLICENSEを同梱• etc.• ref. 「Goでツールを量産する僕の⽅法」• https://junkyard.song.mu/slides/gocon2019-fukuoka/#0
4Maintaining major Go toolsご意⾒あれば懇親会などでお声がけください• ghq (github.com/motemen/ghq)• ソースコードリポジトリ管理ツール• ghr (github.com/tcnksm/ghr)• GitHubへのバイナリリリース⽤ツール
5Recent Works• godzil (github.com/Songmu/godzil)• Goツール作成のためのAuthoring Tool• ecsched (github.com/Songmu/ecsched)• ECSのスケジュールタスク管理ツール• kibelasync (github.com/Songmu/kibelasync)• kibelaのクライアント• replaceablewriter (github.com/Songmu/replaceablewriter)• Write先を差し替えられるio.Writer
ࠓ͢͜ͱAgenda6
7Agenda• Nature及びNature Remoの紹介• Nature Remoのシステムアーキテクチャ解説• ECS活⽤事例• 現在の課題• その他の細かい取り組み
ձࣾͱCompany and Product8
Mission9Mission⾃然との共⽣をテクノロジーでドライブするVisionインターネットとセンサー技術を活⽤し、分散型で再⽣可能な電源を普及させ、エネルギーを⾃給⾃⾜出来る未来を創造する
8,980ԁ(੫ൈ)ʢ20187݄13ൃചʣ11,980ԁ(੫ൈ)ʢ201812݄6ൃചʣ(ୈ̎ੈʣNature Remo 1st Generationɺ201710݄16ʹ13,000ԁʢ੫ൈ͖ʣͰൃച10Product
֎ग़ઌ͔ΒεϚϗͰΤΞίϯΛON εϚʔτεϐʔΧʔͱ࿈ܞͯ͠ͰՈిΛૢ࡞11Features
εϚʔτσόΠε Nature Remo ՈిHow It Works
Traction132ऑͰ10ສಥഁೝˍγΣΞۀքNo.1
Funding142019年8⽉ 5億円調達• 環境エネルギー投資• DeNA (デライト・ベンチャーズ)⽇経電⼦版・TechCrunch等掲載継続成⻑中
Home Automation to P2P Electricity Platform152019Phase 1 (ݱࡏ)Home Automation2020Phase 2Energy Management2022Phase 3P2P Electricity Auction Platform
Confidential 16
Nature Remo E• ʮεϚʔτΤωϧΪʔϋϒʯ• ECHONET LiteϓϩτίϧΛར༻• ຊࠃͷεϚʔτϝʔλͱHEMSΛܨ͙ඪ४ϓϩτίϧ• ܦ࢈লೝఆ• ՈఉͷWifiʹͭͳ͍ͰUDPWi-SUNͳͲͰ௨৴• ՈఉͷεϚʔτϝʔλʔιʔϥʔύωϧɾిͷૢ࡞ใऩर• ిྗσʔλͷӾཡૢ࡞ͳͲεϚʔτϑΥϯΞϓϦ͔Β• εϚʔτϝʔλʔ࣮΄΅શͯͷ͝ՈఉͰར༻Մೳ
Nature RemoͱGoNature Remo and Go18
Features• いわゆるIoT製品のスマートリモコン• スマートフォンやスマートスピーカーから家電操作• エアコン・TV・ライト等• 既存の⾚外線リモコンをそのまま置き換えられる• 簡単なリモコン学習(検出)機能• センシングやユーザーの位置情報をもとに家電操作• 温度・湿度、家から離れた時、近づいたときなど
Conditions• Nature Remoは⾃宅のWi-Fiに接続してローカルIPは保持• → ⾃分からインターネットに出ていくことはできるが、外からのリクエストを受け付けるのは容易ではない• しかし屋外のスマホ、スマートスピーカー、ルールなどに対して素早く反応する必要がある• → どうやって? • Nature Remoはマイコンボード上でCのFirmwareが動作• あまり複雑なことをさせたくはない
Possible Solutions (?)• UPnP等によるポート開放とDDNSの組み合わせ• セキュリティ上の懸念• UDPホールパンチング等のNAT越え技術を⽤いたP2P• 接続維持が難しそう。特に移動体↑これらはかっこいいけど、現実的ではない
Realistic Solution• スマホアプリからはAPIリクエスト (開発者向けAPIも提供)• 我々のクラウドシステムがNature RemoにWebsockt経由で指令を送る• 「この⾚外線信号を出して」HTTP API WebSocket- ֎ઢ- ηϯαʔใ- Թ- ࣪
Why WebSocket?• リアルタイムに双⽅向通信がお⼿軽にできる• 「普通の」Web技術• 接続や切断時の再接続はNature Remo側が制御• 常時接続になるため接続管理が割と⼤変ではある• 10万台+増加の⼀途
ΞʔΩςΫνϟArchitecture25
APIStreamWorkerSystem DiagramAmazon ECSSubscribePublishWSWSPub/Sub
Components• API• スマホアプリやスマートスピーカーとの通信• Stream• Nature RemoとのWebSocket通信• Worker• ルールの実⾏すべてGo製でAmazon ECS上で動かしている
Remarkable Points• 素朴なGo製のWebアプリケーション• Redis Pub/Subを⽤いた、API - Stream間のやりとり• Consulによるサービスディスカバリとコネクション管理• AlexaのカスタムスキルはAWS Lambda経由を使って実⾏される
Simple Web Applications with Go• 普通のWebアプリケーション• もともとherokuでホストしていた名残も• フレームワークは使わずGorilla web toolkitを部分的に利⽤• MySQL/Redis• gorp/redigo• DynamoDBはじめました• guregu/dynamo
Utilize Redis Pub/Sub• Redis Pub/Subを活⽤している• APIからはRedisにPublish• StreamはRedisをSubscribe• 相互通信しない疎結合を実現している• Stream側はあくまでWebSocketとRedisからのSubscribeで受け付けた命令の実⾏しかおこなわず状態を持たない
Service Discovery with Consul• 歴史的経緯によりNature RemoはALBへの直接接続が困難• NginxからproxyしてStreamサーバーに接続している• NginxでTLS終端とWebSocketのProxyを実施• エフェメラルポートの都合上、6万接続程度が上限• 接続数が少ないサーバーにNature Remoは接続する• 接続先IPを返すAPIをまずコールし、返されたIPにWS接続• Consulを使ってディスカバリを実現
ECSΛ༻͍ͨίϯςφ׆༻ECS and Containers32
Our almost services running on Amazon ECS• 前述の通り、ほとんどのサービスをECS上で動かしている
CI/CD Pipelinesgit-pr-releasegit pushgo testgo builddocker builddocker pushecspresso deploy1234
Introduce "ecspresso" for Deploying• github.com/kayac/ecspresso• ecs-deployから乗り換え• ecs-deployからの乗り換え先としてちょうどよい• 既存のTask Definitionを利⽤できる• そのままシームレスに移⾏可能• CircleCI上で実⾏してdeploy
The ECS Task Definition become reviewable• Taskへのサイドカー追加やパラメーター変更がreviewableになったのは良かった
--no-wait Option• https://github.com/kayac/ecspresso/pull/38• デフォルトではサービスが⼊れ替わるまで待ってからコマンド終了するが、待たないオプション• ecs-deployとの互換挙動• CD上で利⽤する時に便利
՝ࠓޙऔΓΈ͍ͨ͜ͱProblems38
Nginx Proxy• 歴史的経緯によりNature RemoはALBに接続できない• Nginxに直つなぎしている• Nginxはstreamにproxyしているので6万接続程度が上限• エフェメラルポート関連• コネクション数管理が煩雑!• → ALBに⼀本化したい• DNSベースで⾃動で内部のノード増やしてくれる
Service Discovery• Consulのサービスディスカバリはかっこいいが不安定になることも• Consul⾃体のバージョンも古い…• Cloud Mapなどに切り替えていきたい
Stream Reconnection• streamをdeployすると⼀⻫にNature Remoとの接続を切断することになるため再接続ラッシュとなる• ⼀時的にAPIが過負荷気味になる• コンテナがコネクションを維持したまま、ローリングで⼊れ替えていく⽅法を模索中
Log Monitoring• go.uber.go/zap でJSONログをCloudWatch Logsに送信• CloudWatch Logs Insightsも安定してきて便利• しかし如何せん⾼い• ⼀部のログはアプリから直接firehoseを叩いてS3送信• Athenaで調査• firehoseがたまに⼀時的にエラーが続くことに困っている• 改善したい
Further use AWS• AWS IoT• 無理して使う必要はないと考えているが、選択肢を広げて必要に応じて使いたい• 機械学習系機能• ユースケース• 室温や快適度の⾃動調整• 電⼒の最適化や需給調整
RDB Migration• gooseを利⽤• 積み上げ式のMigrationはイマイチ• メンテも滞っている• マスターデータ⼊れるのもやっているので若⼲乗り換えづらい• schemalexに乗り換えたい• sqldefでも良いがschemalexは社内に作者がいる
࣋ଓՄೳͳ։ൃͷͨΊʹೖࣾޙऔΓΜͩ͜ͱMinor Topics45
Go Modulesಋೖ• depから移⾏• vendorを残すなら以下のステップのみ% GO111MODULE=on go mod init% GO111MODULE=on go mod vendor% rm Gopkg.*• ビルド時に `-mod=vendor` を⼀律つける必要はある• vendoringなんだかんだで便利だと思うようになった…• CI環境で考えることも減らせる
Dependabotಋೖ• dependabot.com• 依存ライブラリのバージョンが上がっていたらpull requestを起票してくれるサービス• GitHubが買収して今は無料で使える• とにかく依存ライブラリ最新にし続けたいので便利• Go対応正直微妙な部分も…• 頑張ってほしい…• 起票後CircleCI上でgo mod tidy⾛らせるなどの⼯夫もしている• アップデート当番のアサインも⾃動化
git-pr-releaseࣗಈԽ• developブランチにfeatureブランチマージしたら勝⼿にリリースpull requestが⽣えてきて便利• https://songmu.jp/riji/entry/2019-07-28-circleci-git-pr-release.html
ECS Scheduled TaskཧͷͨΊͷπʔϧecsched• github.com/Songmu/ecsched (作りかけ)• バッチ類は、ECSのScheduled Taskを利⽤しているがそれをバージョン管理したいという動機
·ͱΊ50
Nature Remoͷཪଆ• サーバーサイドはほぼ全てGo• 実は割と普通のWeb技術を使って実現している• インフラはAWSに寄せているし、もっと寄せていきたい• 本質的なサービス開発に注⼒したい• WebSocketの接続管理周りがチャレンジング• サービスも急成⻑中• 開発体験を上げるためにも⾊々やっています
We are hiring!積極採⽤中です!• バックエンドエンジニア• スマートフォンエンジニア• 機械学習エンジニア• 組み込みエンジニアぜひオフィスに遊びに来てください@恵⽐寿