AWSにVPNでつないでSteam Home StreamingでAstroneerをやりたい

前回の記事で、手元にWindowsがなくてもAWS環境にWindowsマシンを用意し
リモートデスクトップを利用してAstroneerをプレイする方法を紹介しました。

takanamito.hateblo.jp

しかし、記事の最後にも書いてあるように
ドラッグが効かなかったりと、通常プレイにも支障が出てしまう状態でした。

今回はそれをクリアし快適にプレイすることができたので、その方法を書こうと思います。

きっかけ

前回の記事を投稿したところ知人からTwitter
「Steam Home Streaming」なるものの存在を教えてもらいました。

Steam ホームストリーミング

LAN内にあるマシンでリモートプレイできる仕組みのようです。

今回はこれを利用してプレイしたいので
Mac - WindowsVPNで接続してSteam Home Streamingが使える環境をつくります。

ちなみに前回紹介した海外の先駆者が公開している動画で、実際にどれくらいサクサクにプレイできるかが確認できます。

これだけなめらかに動けばAstroneerは余裕なはずです。


EC2 Steam streaming

手順

VPN環境の構築をしていきます。試される方は自己責任でお願いします。

OpenVPNの設定

今回1番難しい作業です。Mac - Windows間のVPN環境を構築します。
基本的には前回紹介した海外の先駆者の記事に記載の8番の工程を進めます。

まずはWindows

Windows側の手順はここまで
今回、上述の記事を参考にOpenVPN設定を試みたが、記事内で公開されている設定ファイルをどこまで信用していいかわからなかったので自分で読んで、一部設定を変更した。
ただVPN設定自体が初めての経験だったので、ほんとにこれが正しい設定なのかは自信がない。危ない設定あれば指摘ください。

また拡張子表示設定をしていなかったため、編集後の server.ovpnファイルが実は server.ovpn.txtになっており、OpenVPNが設定ファイルを読み込んでくれないなど
非常にしょうもないハマり方をしたので、拡張子表示設定を先にやっとくとよさそうです。

つづいてMac

  • Windowsから ca.crt, client.crt, client.keyの3つのファイルをダウンロードし、ローカルに置いておく
  • クライアント用の設定ファイルを鍵を置いたディレクトリに配置。設定サンプルはこちら 5行目にWindowsサーバーのIPを埋める
  • TunnelblickをDL
  • 起動後、先程のcliend.ovpnファイルを読み込ませて接続

この設定でVPN接続が可能なはず。
Windows側に接続されたっぽいログが表示されていれば成功。

AWSのセキュリティグループを変更し、自宅などのIPからUDPのアクセスを通す設定をお忘れなく。

Steam Home Streamingの設定

Steamアプリからホームストリーミングの設定をします
ハードウェアエンコードに関する設定をONにしてください。

f:id:takanamito:20161224120645p:plain

この段階でMacWindows双方の「ストリーミングを有効にする」チェックボックスがONになっていれば
上の欄にリモートサーバーが表示されているはずです。

表示されない場合は、チェックボックスのON/OFFを試すと表示されることが多かったです。

Astroneerをやる

MacのSteamからAstroneerを見てみると「プレイ」ボタンがあるはずの場所に「ストリーミング」ボタンが表示されているはずです。
これをクリックすれば、、、プレイ可能かと思いきや「画面はリモートコンピュータ上からロックされています」というエラーメッセージが表示され起動できません。

これはwindowsログインができておらず、ロックされていることが原因です。手軽に突破するにはChromeリモートデスクトップなどを利用しログインした状態をつくるのがおすすめ。
またログインするためには ctrl + alt + delete を要求されますが、Macからは ctrl + option + fn + deleteあたりで突破できたはずです。

その状態で「ストリーミングを」クリックすれば、、、

f:id:takanamito:20161224122601p:plain

ちょっと画質は悪いかも。でもサクサク動く。

f:id:takanamito:20161224121723p:plain

車とか作ると原付を手に入れた高校生くらい一気に移動範囲が広がる。

f:id:takanamito:20161224121728p:plain

「おおー。できてきたできてきた。」とか思って時計を見ると深夜3時になってたりして危険。

そのうち農業要素が追加されるらしいので、砂とうんこを混ぜた畑でジャガイモを育てたいです。

AstroneerがやりたくてAWS EC2でWindowsマシンを立ててリモートデスクトップでプレイ

「Astroneer」がやりたかった。

ただ、うちには動作条件を満たすWindowsマシンがなくて困った。

ゲームはそんなに長く続かないタチなので100時間もやらないはず。
そのためにわざわざ何万も払ってWindowsマシンを買いたくもないし、大掃除でせっかく空けた家のスペースも使いたくない。

諦めきれずに同僚にslackでAstroneerやりたいと話していたら
「AWSでWindows使えばいいじゃん」と言われた。

その発想はなかった。

調べてみると、海外に同じ事をしている人がいた。

意を決して作業を始めると、1時間くらいでAstroneerがプレイできる環境が手に入った。
今回はパフォーマンスそっちのけで、とりあえず動かせるところまで。

※2016/12/24追記
より快適にプレイするためのVPN導入 takanamito.hateblo.jp

環境

手元にはMacしかない
Macbook 12インチ Early 2016 (macOS Sierra)

手順

  • EC2インスタンスの起動
  • Microsoft Remote Desktopでつなぐ
  • グラフィックボードのドライバを更新する
  • オーディオドライバをインストール
  • Steamをインストール
  • Astroneerをインストール

※破産の可能性があるので自己責任でお願いします

EC2インスタンスの起動

AWSマネジメントコンソールからEC2を起動します。
今回使うAMIは「Microsoft Windows Server 2012 R2 Base」
※最新のWindows Server 2016がありますが、あとでインストールするドライバの関係で2012じゃないと動きません

  • AMI: Microsoft Windows Server 2012 R2 Base
  • インスタンスサイズ: g2.2xlarge
  • ストレージ: EBS gp2 100GB
  • セキュリティグループ: 3389番(RDP)のみ開放(リモートデスクトップで使用

※2016/12/23追記 同僚から「Windows Server 2012 R2 with the NVIDIA Driver」のAMIを使ったほうが ドライバのインストールが楽になるとの情報を教えてもらいました。

Microsoft Remote Desktopでつなぐ

EC2インスタンスが起動しステータスチェックが通ったら、下記の手順を実行しパスワードを入手します。

docs.aws.amazon.com

次にMicrosoft Remote DesktopをDLし接続設定をします

Microsoft Remote Desktop

Microsoft Remote Desktop

  • Microsoft Corporation
  • ビジネス
  • 無料

  • Connection name: お好きに
  • PC name: EC2のIPアドレス
  • User name: Administrator
  • Password: さっき取得したやつ
  • Start session in full screenのチェックを入れる
  • Use all monitorsのチェックははずした方がいい

これで接続できるはず。
ここからは普通にWindows触るときと同じ感覚で操作可能

ただしセキュリティ設定が厳しくて、IEでいろんなサイトにアクセスするときに
「このドメインを信用しますか?」的なダイアログがひたすら出続けるのでその辺は僕はポチポチして回避しました。
もっといい方法があれば教えてください。

グラフィックボードのドライバを更新する

リモートデスクトップでログインしたら、グラフィックボード NVIDIA GRID K520用のドライバを更新します。

NVIDIA DRIVERS Quadro Desktop Driver Release 367 WHQL

※ちなみにWindows Server 2016を使っていると、ここで古いバージョンのドライバしか入らず
ゲーム起動時にエラーで強制終了されてしまいました。

デバイスマネージャからデフォルトのドライバである「Microsoft Basic Display Adapter」をオフにしたあとにアンインストール さらにドライバのファイル自体も削除しておくとよい模様。C:\Windows\System32\Drivers\BasicDisplay.sys
僕は権限を与えることができずに削除失敗しました。

オーディオドライバをインストール

オーディオドライバは入ってなかったぽいのでインストール

Razer Surround Personalized 7.1 Gaming Audio Software | Razer US Site

これで右下のタスクバー?のボーリュームアイコンのバツ印が消えて
手元のMacから音が聞けるようになるはず

必要であれば言語設定も変更して
この辺で一度再起動しておくとよさそう。

Steamをインストール

あとはいつもどおり、Steamをインストールしたのちに
Astroneerをインストールすれば、、、

f:id:takanamito:20161220130231p:plain f:id:takanamito:20161220130237p:plain

コスト

今回使ったのが

  • CPU: 8コア
  • メモリ: 15GB
  • GPU: NVIDIA GRID K520

のg2.2xlargeインスタンス

東京リージョンで動かしても$1.01 / 1 時間

このスペックのパーツを買い揃えることを考えると 100時間やったとしても1万円強で、ものすごいコスパ

低レイテンシーを求められるゲームならまだしも、今のAstroneerのように
1人でのんびりとやるぶんには全く問題ない感じ。

所感

今の環境では完全互換とはいかず、なぜかマウスのドラッグアクションが効かずに
掃除機みたいなやつで吸うアクションがうまくできない。
この辺は別のリモートデスクトップクライアントも使って検証してみる予定。

公式ForumでもMac対応するってQ&Aに書いているので、気長に待ちます。

What about Mac users?
Eventually Astroneer will be supported on Mac. Not confirmed if it will be supported at Early Access launch yet though.

(Read First) Astroneer FAQ :: ASTRONEER General Discussions

2016年お買い物ランキング

2016年によかったものを12個書きます

takanamito.hateblo.jp

12位 IPPO

IPPO 1 (ヤングジャンプコミックス)

IPPO 1 (ヤングジャンプコミックス)

会社の同僚からおすすめされて買ってみたマンガ。
若手ビスポーク革靴職人の話でとにかく職人最高という気分になれる。
インターネットのサービス作るのもいいけど、やっぱり実際に手に取れるものもつくりたいですわな。

11位ヨーグルティア

こちらも同僚のすすめで購入。
ヨーグルトを無限に食べたいので、せっせと作っている。
最近はドリンクタイプのR-1を使うと美味しくできるということを発見。
牛乳パックを直接セットするタイプよりも、温度設定やタイマー設定があるので使いやすい。
低温調理器としても活躍していて、よく鶏ハムをつくる。
生ギリギリを攻めたほうが美味しいので毎回ドキドキしながら仕上がりを見るのもまた楽しい。

10位 ガメラ 大怪獣空中決戦 4K上映(トークショー付き)

hobby.dengeki.com

豊洲であったイベント上映。
4K上映自体は去年の東京国際映画祭でも見てたけど、今回はトークショー付きということで仕事をさっさと切り上げて通った。
何より良かったのは長峰役の中山忍さんを見られたことで、自分の年だと明らかに浮くような高めの年齢層の観客みなが
中山忍登場で"息を呑む"瞬間を体感できたのがよかった。
女優すごい。別格に綺麗でした。

9位 赤めだか

赤めだか (扶桑社BOOKS文庫)

赤めだか (扶桑社BOOKS文庫)

この記事に影響されて読み始めた。 今どきの若手育成にひそむ3つの思いこみ

おかげで初めて落語の寄席にも行ったり、なかなかいいおでかけトリガーになったと思う。 スライドにも引用されている箇所はしっかり意識して実践してる。

8位 SCYE x URBANRESEARCH ダッフルコート

2016AW SCYE x URBAN RESEARCHの名作ダッフルコート - 社会人3年目の服選び

大学のときにHAREで買ったダッフルコートをずっと着てたけど
もうちょっといいやつを着たかったので後輩に譲って新しいのを買うことにした。
Scyeのダッフルコートは名作とのことで、たまたまURBANRESEARCHの別注モデルで黒があったので購入。
形は綺麗だし、肉厚で温かいのでとても気に入っている。

7位 nginx実践入門

nginx実践入門 (WEB+DB PRESS plus)

nginx実践入門 (WEB+DB PRESS plus)

普段の仕事でも使いまくってるnginx
前からちょくちょく触ることはあったけど、行きあたりばったりな設定ファイルを作ってしまうことが多いので
ここらでちゃんと知識入れとくかと購入。

今でも机に置いて、リファレンス的な使い方をしています。

6位 キャプテン・アメリカ シビルウォー

今までマーベルシリーズではキャプテンのウインターソルジャーが1番好きだったのが、さらにそれを上回ってくる感じで最高。
2016年における映画の才能を全て集めて映画撮ったらこれができました!
みたいな感覚すら覚える。
猛ダッシュバッキー追跡シーンと、スパイダーマンがAT-ATぐるぐる巻きのことしゃべり出すシーンが最強。

5位 iPhone7

Apple Pay最高。
もう財布をリュックから出さなくていい。 ただ防水が信用できないところはちょっとやだ。

takanamito.hateblo.jp

4位 星野源 Live Tour "YELLOW VOYAGE" (初回限定盤) <Blu-ray>

Live Tour “YELLOW VOYAGE" title="Live Tour “YELLOW VOYAGE" (初回限定盤) ">

Live Tour “YELLOW VOYAGE" (初回限定盤)

逃げ恥の恋ダンスもいいけど、スーダラ節の弾き語りとかニセ明さんの君は薔薇より美しいもいい。
DOWN TOWN 〜 ステップにつなぐところのドラムがババちびるくらいかっこいい。

3位 東京国際映画祭 アメイジング・スパイダーマン2 野外上映

2016.tiff-jp.net

毎年、東京に住んでてよかったと思えるイベントのひとつ。
ヒルズでアメスパ2が野外上映するとのことで行ってみると
SONYの謎巨大4Kディスプレイに、でかスピーカーが準備されてて非常に高まる。

12月の極寒の中観る、ガーフィールドとエマ・ストーンの公園再会シーンは最高だし
映像自体Ultra 4Kとかいう規格のものを流していたらしく、エレクトロの電流をかいくぐって街をぎゅんぎゅん行くシーンがとんでもないことになっていた。

どなたがチョイスしているのかわかりませんが、本当にありがとうございました。

2位 nasne

nasne 1TBモデル (CUHJ-15004)

nasne 1TBモデル (CUHJ-15004)

死ぬほどテレビを観るので、今まで買わなかったことを後悔した。
torneアプリを使ったリモート操作/視聴が神で、友達や家族に「この企画おもしろかった」って言いながらさっと録画を見せられるのが最高。
あとこの機能のおかげで会社で同僚と日本シリーズ見れたりして非常に満足度の高い買い物でした。

1位 ALDEN 990

初めて新品の高級靴を買いました。
値段が値段なのでお手入れの方法も勉強したり、リテラシーを引き上げるきっかけになった一足。10年履きたい。

合わせて買った本もすごくよかった。

靴磨きの本

靴磨きの本

この靴を履くときは、朝の段階で天気予報を死ぬほどチェックする。

この靴を買ったおかげで、あまり知り合わないような人とも仲良くなれた。 もっとこういう話ができる人たちと会ってみたい。

お金使うの気持ちいいですね。 来年もたくさん散財したい。

ちょこっとサーバーを立てたいときのTerraformの構成を考える

この記事は、「Speee Advent Calendar 2016」の5日目です。
4日目は、id:nisshieeより、「Turbolinks再考」です。

今日は、Terraformの構成について再度考えたいと思います。


先日書いたブログで、hashcorpが公開しているTerraformのbest-practiseについて読み解きました。

takanamito.hateblo.jp

ブコメでもいくつかあった「つらそう」という意見
つらさにも種類があるとは思うのですが
僕が実際にベストプラクティスを読んでいて思ったのは

  • モジュールが2階層構造になっており、抽象化されたモジュールを読み解くのがしんどい
  • モジュール単位で変数定義が必要なため、3回変数宣言をしなければならないのがめんどくさい

という2点。

ただこれも、多くのリソースを抽象化して管理したり、ファイルの肥大化を防ぐ意味では有用であろうという結論を出していました。

実際にはオーバースペックだった

いざ使ってみると、仕事である程度の規模のインフラを管理する場合には役立つこのベストプラクティスも
個人で数台のインスタンスを立てて、とりあえずwebサービスが動く構成にするには
少しオーバーだなと感じることが多かったのです。

そもそも、Terraformを使ってAWSのインフラ管理を楽にしたいと思って導入しているのに

  • まずは必要なリソースをmoduleに切り出して
  • 変数定義をmoduleの数だけ書いて
  • terraform getやplanで動作の確認をして

と、ちょこっとインスタンスを立ち上げるだけの作業が非常に大きくなっていき
結果Terraformの準備に時間がかかる本末転倒な結果になってしまいました。

例えばマイクロな構成でEC2インスタンスだけ立てるならブラウザでポチポチやればいいじゃん。とも思ったのですが

運用するサービスが分かれている場合、最低限ネットワークは分離したかったりするので EC2 1台立てるのに必要な VPC, subnet, route table, gateway...etcを考えるとやはりTerraformを使ってコマンド1発で構築したい。

軽量Terraformテンプレートを製作

そこで

  • hashcorpのベストプラクティスほど大きくなく
  • ありがちな構成を整えた

Terraformのテンプレートを作り始めました。

github.com

構成はこのような感じ

├── micro
│   ├── micro.tf
│   └── terraform.tfvars
└── modules
    ├── compute
    │   └── ec2
    │       └── ec2.tf
    └── network
        ├── route_table
        │   └── route_table.tf
        ├── security_group
        │   └── security_group.tf
        ├── subnet
        │   └── subnet.tf
        └── vpc
            └── vpc.tf

このテンプレートで生成可能なのは「80番ポートだけ空いた、インターネットに疎通可能な1台のEC2インスタンス」です。
各リソースを操作可能なIAMユーザーを用意して、EC2用のキーペアだけ作成しておけばコマンド一発で立ち上がります。

読み始める場合は /micro/micro.tfからスタートし、各moduleをのぞいてもらえるとわかりやすいと思います。
※これからいくつも構成のテンプレートを用意しようと思っているので、最小構成の意味でmicroと命名しています。

この構成の利点は

  • 階層が減ることで各moduleの見通しが良くなる
  • 変数定義の回数を減らせる (micro.tfと各moduleの2回)

の2点です。

ベストプラクティスでは存在したcomputeモジュールなどの、1段階リソースを抽象化したモジュールを廃止し、直接リソースを定義したモジュールに変数を渡すことで 構成を1階層減らしました。
これによって構成がシンプルになり、小規模な環境を準備する際のコストが減らせるかと思います。

またベストプラクティスに比べて、Terraform初心者に読んでもらうときにも非常に優しくなっていますね。

反面、この構成だとPRO/STG/DEVのような開発環境に分けてコードを記述することには対応させていないのですが
その場合はmicroディレクトリの下に環境ごとのディレクトリを作って、tfファイルとtfvarsファイルを置けば対応可能かと思います。

この先の展望

このリポジトリは「個人がAWSでWebサービスを始めるときに使えるよくある構成のテンプレート集」化していこうと思います。

仕事をしていても感じるのですが
Webサービスをつくるときに「絶対するであろう作業」が自動化されていないことで、各個人の時間が吸い取られていくので
これを解決することで、より価値提供のための開発に集中できるはずです。

まずはよくある構成を充実させて、そのうちコンテナを使った構成などにも対応できればと思っています。

入社して3年が経ちそうなので振り返り

もうすぐ社会人になって丸3年。
いい機会なのでここまでやってきたことの棚卸しをしてみる。

1年目

同期より2ヶ月ほど早く入社し、いきなり新規サービスの立ち上げに参加させてもらった。
僕は2年目の先輩エンジニアの下について、ユーザーのコンテンツ投稿画面のフロントエンドを中心に開発をしていた。

このときAngularJSみたいなフレームワークの導入もできたのに「JSの勉強も兼ねてjQueryだけでやってみよっか」と大きなフレームワークなしで設計/実装にチャレンジさせてもらえたことにとても感謝している。
JSのオブジェクトや関数について理解を深めるきっかけになった。
この時期にJavaScriptパターンを読みまくっていた。

JavaScriptパターン ―優れたアプリケーションのための作法

JavaScriptパターン ―優れたアプリケーションのための作法

サーバーサイドもPHPJavaを使った基本的なwebサービス開発をしていて
学生時代には意識したことのなかったMySQLの基本的なクエリチューニング(といってもEXPLAIN程度のものだけど)も教わった。
ミドルウェアやインフラを意識した開発は初めてだったので新鮮なことが多くてすごく楽しかった記憶がある。

半年ほど経った9月頃には、チームを移ることになった。
次のチームでは海外向けメディアを扱っていて、僕は今に至るまでこのチームに在籍することになる。

1番最初のチームでは作業のほとんどがアプリケーション実装だったのに対し、今のチームではインフラ関連の作業をやることが多くなった。 少し責任範囲が広がった感じ。

当時、先輩が1人で6サイト運用しながら、さらに2サイトの新規開発をしていて 運用するだけで手一杯、アプリケーションにバグも埋もれていたりコードのコピペもあったりと直し放題の環境だったので 1チーム目のときに教わったことをそのままこのチームにも展開していった。

あげだすとキリがないけど
運用面ではJenkinsによる自動化やバッチ実行管理、リリースノートを含むドキュメントの整備、backlogで管理していたチケットの整理と、とにかく散らかってるものを全て整理していった。
アプリケーションに関してはまずコピペ脱却のために各種機能を役割ごとにクラスやモジュールに切り出していく作業をひたすらやっていた。またその過程で見つけた誰も知らないバグをひたすら潰してた。

チームメンバーが兼務だらけで、とにかく散らかっていて整理されてない状態だったことや
プロダクトマネージャーが(幸運なことに)裁量を与えて自由に動かせてくれるタイプの人だったことにより
開発/運用/その他もろもろのいろんな種類のタスクを自分で見つけ、優先順位をつけてつぶしていくコツをこの時期にかなり学べたと思う。

またミドルウェアを触る作業が増え、先輩からインフラ系作業を教わることができた。
MySQLのチューニングやLinuxカーネルチューニング、nginxの設定について勉強し始めたのがこの時期だった。
それ以来nginxが好きで、社内のQiita::Teamにnginxの設定に関する記事をよく書いていた。

また、この時期に勉強したことがISUCONでめちゃくちゃ役立っていて、教えてくれた先輩にはめちゃくちゃ感謝している。 takanamito.hateblo.jp

そういえば仕事をする上で相談することが苦手だった僕が下手なりに相談できるようになったのは、この時期にミドルウェアに関する相談をこの先輩が嫌がらず聞いてくれたおかげな気がする。

年が明けるころには大きなインフラ移設も行っていて
さくらVPSで動かしているメディアが成長していき、スケーラビリティと地理的な条件からAWSに移行することになった。

設計からサービス無停止での移行の実作業を1人でやることになった。
この作業はかなりきつくて、そもそもインフラはどうやって設計するものなのか、どう考えて組み立てていくのかなどなど
何がわからないのかもわからない状態だったと思う。
とにかく理解を深めるために、既存のインフラをAWS上で再現するために必要なリソースをリストアップして図に起こしていく作業をやっていた。

この時期にゼロからWebサービスを作る時に必要な

  • 自分の考える理想的な構成を描く
  • 現実的な条件をもとに松竹梅程度の選択肢に落とす
  • 選択肢のグラデーションの中から最適解を探す

みたいな考え方を学べた。

移行が終わってからは少し落ち着いたので、当時流行り始めていたリアクティブプログラミングの流れに乗ってriot.jsを触ってみたり
レコメンドエンジンに触れたりしていた。 takanamito.hateblo.jp

2年目

2年目はチームの開発サイドリーダーとなって、自分がメイン開発者としてサービス開発を進めることが多かった。 また会社がPHP, JavaからRubyScalaへ移行することになり、Railsでのアプリケーション開発の先陣を切ることになる。

全社的にテストの重要性を意識しはじめ、CircleCIの導入を始めたりとやっと少しナウみのある開発ができ始めた。
同時にmocha, chaiを使ったJSのテストも導入したりと、作ることに対しての余裕ができて
普段の開発に効果がありそうな、自分なりのプラスを取り入れることができるようになった気がする。

それまでどのチームもテストゼロ、誰が何を作ってるのかもわからないような状態だったので
この時の開発体制の大改革はとてもありがたかった。

チームの人数が増え始めたことで、イテレーション運用をより力を入れて回すことになり 開発スケジュール管理やディレクションに関して大きな時間を割いて関わることになる。

チームのエンジニアリーダーである自分が進捗管理をしつつ、ディレクションも手伝いつつ、自分でもアプリケーションを書いていたので
特にリリース間際の佳境に差し掛かった時期には仕事をする時間が増え、見事に腰を破壊された。

年末から年明けにかけてはFuelPHP -> Rails移行のプロジェクトもあり 数十万URLの301リダイレクト処理にビビりながらも特に大きな事故なく終えることができた。
このあたりから社内勉強会で話す機会を少し増やしたり、外の勉強会でLTをするようにした。 takanamito.hateblo.jp

3年目

2年目につくったサービスのトラフィックを伸ばすための改善、運用コストを下げるための施策を中心にやっている。

インフラ移設時に手動でコンソール画面をポチポチして立てていたAWSのインフラを TerraformとItamaeの導入を進めて自動化したり (Docker導入もやりたい) takanamito.hateblo.jp

A/Bテストをリリース速度重視で行うために
今まではmunin, nagiosでやっていた監視に加えて、Datadog, Sentryを使った監視や可視化の仕組みを導入したり

A/Bテストのためのログ解析要望も高まり、fluentdとelasticsearchを使ったログ蓄積基盤を作ってサービス改善のためのログを取り始めたり
その過程でけっこうメジャーなfluentdのプラグインやsunspotといったでかいgemにPR送ったりするOSSっぽいことも始めた。

効率化という文脈では、対象を自チームだけに絞らず
趣味で社内Gyazoサーバーを立てたり、サーバーレスHLS動画配信の仕組みを作ったりして
業務に関係ないことで新しい技術には触れるようにしている。(この取り組みが自分のチームに還元できるとうれしい) takanamito.hateblo.jp

所感

3年間webアプリケーション開発に関わってみて
新しい技術を学ぶのももちろんだけど、今ある環境や生活に非効率なものがないか見渡して
それを解決することが合っている気がしてきた。

  • nginx
  • S3, Lambdaなどのいわゆるサーバーレス系サービス
  • HLS

あたりの技術が自分の中ではしばらくホットで、全部に共通しているのが
「自分の実現したいことが楽に実現できる」ということ。

すごく頑張っていいコードが書けたときもうれしいけど、やりたいことに対して「◯◯使えば一瞬で終わるしみんなが楽だ」って気付いて実現できたときの喜びのほうが大きい。

チーム内でも、もっと効率化できるとこあるなぁと思いながらも
ここ1年くらいは開発以外の業務量が増えていたという事実もあり
最近はそういった仕事の量を相談して減らして、開発に集中させてもらっている。

インフラ作業が多く、特にサービスの特徴的にもフロントエンドの重要性が低いので
しばらく触れていないJSを中心にSPAにも触れていけると楽しくなりそう。

HLSでサーバーレス動画ストリーミング配信をする

家にある動画を再生するのに、いちいちデスクトップパソコンを立ち上げたり、NASっぽいものを構築するのもめんどくさくて
URLを生成してiPhoneとかのブラウザでシュッと見られるようにしたかった。

長い動画を再生するためにストリーミング配信したくて
手持ちのMaciOS系デバイスで再生するのだと、どうやらHLSが向いてそうだという結論に落ち着いた。

自宅にサーバーを置きたくないので (でかいし、うるさいしで邪魔)
クラウド環境でいろいろやってみることにした。

結果できたのが以下のようなもの。

f:id:takanamito:20161022175237p:plain:w350

動画視聴までのワークフロー

  • 手元にある動画ファイルをS3にアップロード
  • S3にファイルが置かれたのを検知してLambdaを起動
  • LambdaでElasticTranscoderにエンコードジョブを作成してアップした動画をエンコード
  • エンコードが完了したらファイルをS3に出力
  • S3のファイルのURLをSafariで開いて再生

必要な作業は以下の通り

  • ElasticTranscoder側の設定 (Pipeline, Preset)
  • Lambda Functionの作成

S3のPUTイベントを検知してElasticTranscoderにジョブを投げるLambda Functionを作ります。
基本的には以下の記事を参考に進めました。

qiita.com

ElasticTranscoderの設定

Presetの作成

動画をエンコードする際の設定を決めます。
今回はさほど画質にこだわっていなかったのでデフォルトで用意されている設定を使うことにしました。
1M ~ 1.5MくらいのPresetがHD周辺の解像度でエンコードしてくれたので、そのまま採用しています。
この際、IDというカラムに表示されているPreset IDをメモしておきます。

f:id:takanamito:20161022181254p:plain

Pipelineの作成

ElasticTranscoderの作業フローを設定していきます。
S3上のどのBucketにある動画を、どのBucketにエンコードして出力するのかを決めます。

基本的には2つのBucketを用意し、仮にA, BというBucketがあるとすると

Aに動画ファイルをアップロード -> Lamba Functionがジョブを投げる -> ElasticTranscoderがエンコード -> Bにエンコード結果のファイルを保存

という流れになります。

こちらも生成後のPipeline IDをメモしておきましょう。

Lambda Functionの作成

先程のQiitaの記事を参考に、Lambda Functionを作っていきます。

メモしていた2つのIDを変数に埋めてください。

var aws = require('aws-sdk');
var s3 = new aws.S3({apiVersion: '2006-03-01'});
var ets = new aws.ElasticTranscoder({apiVersion: '2012-09-25', region: 'ap-northeast-1'});

exports.handler = function(event, context) {
   console.log('Received event:');
   console.log(JSON.stringify(event, null, '  '));
   
   var bucket = event.Records[0].s3.bucket.name;
   var key = event.Records[0].s3.object.key;
   
   var pipelineId = 'xxxxxxx';
   var presetId = 'xxxxxx';
  
   var fileName = key.split('.')[0];
   
   ets.createJob({
     PipelineId: pipelineId,
     OutputKeyPrefix: fileName + '/',
     Input: {
       Key: key,
       FrameRate: 'auto',
       Resolution: 'auto',
       AspectRatio: 'auto',
       Interlaced: 'auto',
       Container: 'auto',
     },
     Outputs: [
       {
         Key: 'ts-720p',
         PresetId: presetId,
         Rotate: 'auto',
         SegmentDuration: "10"
       },
     ],
     Playlists: [
       {
         Format: 'HLSv3',
         Name: 'master',
         OutputKeys: [
           'ts-720p',
         ],
       },
     ],
   }, function(error, data) {
        if(error) {
            console.log(error);
            context.done('error',error);
        } else {
            console.log('Job submitted');
            context.done(null,'');
        }
    });
};

またTriggersも設定します。
今回はS3上の.mp4というSuffixのファイルのObjectCreatedByPutObjectCreatedByCompleteMultipartUploadイベントを検知して起動するように設定しています。

これでS3に動画がアップされると自動でエンコードが開始されるようになります。

動画の再生

エンコードが完了すると.m3u8ファイルが2種類と.tsファイルが大量にbucket上に生成されます。

f:id:takanamito:20161022182541p:plain

.m3u8ファイルは動画のプレイリストとしてのテキストファイルです。
HLSはAppleが仕様を作っているプロトコルということもあり、Safariであればこの.m3u8ファイルのURLを開くだけで動画配信が始まります。

S3のPolicyを編集してIP絞るなど
インターネットに広く公開しないような設定をお忘れなく。

所感

ほぼプログラムを書かずにストリーミング配信を実現することができるので非常に楽。

ただElasticTranscoderの料金がバツグンに高いので、気になる方は手元のマシンでffmpeg使うなりしてHLS形式にするところまでやってS3に上げるのがよさそう。

HLSがHTTP/1.1の上で動作するため考えることも少なく、基本的にS3に動画ファイルとプレイリストを置いて静的に配信できれば
あとはプレーヤー側がうまくつなげて再生してくれるため、とても楽にストリーミング再生が実現できます。

またRTMPなどのプロトコルと違い、配信用サーバーを置かずにすんだり
CDNを使うことで容易に配信負荷分散ができるので、そのうち仕事で使う場面もでてきそう。

実際こないだのAbemaTVのカンファレンスでも現場のおもしろい話が聞けたので今後もHLS注目していこうと思います。

AbemaTV Developer Conference 2016

iPhone7をお風呂に落として水没させるも、乾燥剤のシリカゲルで復活した ※iPhone12もいけるはず

f:id:takanamito:20161017200027j:plain:w350

お風呂に浸かりながらiPhone7触ってたら、見事に浴槽に落としました。

浴槽のふちに乾いたタオルを敷いて、iPhoneをその上に置いていたのですが
ふとした拍子に腕が当たってしまい「ボチャッ」という音で気がつく。

慌てて救出して(約1秒) 起動すると、さすが防水端末。余裕で起動したのでひと安心。

15~20分ほどお風呂でiPhoneを操作していて、のぼせてもいけないのでそろそろお風呂からあがることに。

しかし様子がおかしい

着替えてから再度iPhoneを触ると何かおかしい。
具体的には以下のような症状

  • 液晶上部にシミ
  • 電源、ホームボタン接触不良。勝手に押されたり、押しても反応しなかったり
  • レンズに水滴侵入
  • SIMスロット内部に水滴

先日話題になった記事
iPhone 7 Plusを、シャワー中に使ったり水ですすいだりしてたら、水没判定で有償交換となってしまった話 – mono-gadget – Medium

読んだばかりだったので一気に血の気が引く。

水没判定を食らうとアウトとのことだったので、どうやったら水没判定アウトなのか調べる。

f:id:takanamito:20161018182944p:plain:w350

iPhone や iPod が水濡れにより損傷した場合は保証対象外 - Apple サポート

僕の場合はSIMスロット内部に水滴がついていたので、半分あきらめてましたが
もちろんシールも赤で、完全にアウトでした。

修理費用も3万円を超えるとのことでかなり絶望。

シリカゲルを試す

スマートフォンが水没した場合、電源OFF状態でシリカゲルとともに密封作戦は何度か聞いたことがあったので
Amazonシリカゲルを買って試してみることに。

あわせ買い不要で、オーソドックスなやつを探しました。
お急ぎ便ですぐ届いてよかった。ありがとうAmazonプライム

復活ツールと称した謎セットも売られていて驚く

手頃なサイズのタッパーを用意して、シリカゲルを敷き詰め
その上に電源を落としてSIMスロットを抜いたiPhone7を寝かせます。
※SIMスロットを抜いたのは、端末内部の通気性をより増すためです。効くのかわかりません。

f:id:takanamito:20161017200203j:plain:w350

さらに上からシリカゲルをかぶせます。

f:id:takanamito:20161017200225j:plain:w350

この状態で、蓋を閉め密封して一晩放置。

翌朝

タッパーから取り出し起動してみると、ほぼ全ての症状が改善していました。
よかったよかった。

所感

お風呂で使うやつが悪いけど、もうちょい頑張って水を防いでくれると助かります。

あとシリカゲル常備はマジでしといたほうがいいと思った。
僕の場合は時間経過とともに症状が重くなっていったので
水没 → 電源OFF → シリカゲルの対応スピードで被害範囲がけっこう変わってきそう。