スタートアップがRailsからGoに移行した話（インフラ・デプロイ周り編）

# はじめに
GraffityというARを使った落書き通話アプリを作っているむーつんといいます。
好きな言語はJavaScriptなサーバサイドエンジニアです。

弊社のAPIは元々Railsで出来ており、以下のような構成でした。

<img src="https://qiita-image-store.s3.amazonaws.com/0/243926/b1ccbf93-47a8-6b9e-8964-b939736e594d.png" width="400px"/>


ここにはスケーラビリティは考慮されておらず、同じインスタンスをコピーしてALBに振り分けてもらうという粗末なものでした。（スピード感が求められるスタートアップにおいてはこれで良いのかも）

しかし、Graffityは過去にZIP!で取り上げて頂いたり、弊社代表の森本(以降Totti)がJ-Waveでラジオ出演するなどメディアへの露出が増える中、これではいつ大量アクセスでサーバがダウンするかわからず不安です。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">ラジオ初出演！本日のJWAVE8:30〜9:00までARの未来について別所さんと話しました:) 森本節炸裂してるのですが、内容は面白いので是非！<br>もっとARの未来をわかりやすくビジョナリー伝えよう！貴重な機会ありがとうございました！<a href="https://twitter.com/hashtag/JWAVE?src=hash&amp;ref_src=twsrc%5Etfw">#JWAVE</a> <a href="https://t.co/ozh0j4SPC7">pic.twitter.com/ozh0j4SPC7</a></p>&mdash; ᴛᴏᴛᴛɪ (@ok_totti) <a href="https://twitter.com/ok_totti/status/1014669190945337345?ref_src=twsrc%5Etfw">2018年7月5日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>


# Totti「むーつん、Goに興味ある？」
---それは突然訪れました。
森本の兼ねてからの友人のI氏（インターンでUSの某大手SNSで働いた実績がありとても優秀と聞いていた）がサーバサイドの業務にコミットしてくれることになり、彼がGoに興味があった事と森本がGoに対して持っていた可能性から僕にサーバの開発をGoに移行した方がいいのではないかと打診があったのです。

Goのコミュニティの活発さは感じていましたし、前述のような課題感からRailsからGoに移行することを決めました。

# さて、Goに移行するぞい
Goに移行するに当たって、以下の要素を重要視しました。

- ***マイクロサービスアーキテクチャ***
    - PMF達成に向け、多くのプロトタイプを追加・削除しやすい
    - サービス間通信が行える
- ***Infrastructure as Code***
    - マネジメントコンソールを触らずともインフラが構築できる
- ***CI環境(デプロイ、テスト)***
    - ダウンタイムのないデプロイが簡単に行える
    - 自動テストを実行できる

最終的には以下のような構成になりました。

<img src="https://qiita-image-store.s3.amazonaws.com/0/243926/eeb4c6c2-7964-cded-3b56-b918e7fcc106.png" width="600px"/>

GraffityはPMF達成に向けて仮説検証を進めているフェーズです。
今後多くのプロトタイプが生まれ、破棄されていくことを想定し、コアな機能（ユーザ管理、Worker）と各APIを疎結合することでリスクなく運用できると考えました。

また、インフラ環境は[Terraform](https://www.terraform.io/)にてコード化されており、マネジメントコンソールから操作することなくコードベースで構築できるようになりました。これにより、人為的操作により環境が壊れたりするリスクを抑えることができそうです。

デプロイは[ecs-deploy](https://github.com/silinternational/ecs-deploy)を用いて行われ、

1. 稼働中のサーバ（Blue）とは別のサーバ（Green）を起動する(AutoScalingGroupのMax/MinSizeを0->1以上に変更する)
2. Greenにecs-deployを用いてECRからイメージをデプロイ
3. テスト用サブドメインにRoute53にてGreenのロードバランサに接続
4. テストコードが走る
5. テストが問題なければデプロイしたいドメインに対してGreenのロードバランサを接続（Blue -> Greenにスイッチ）
6. Blueサーバを停止する（AutoScalingGroupのMax/MinSizeを0に変更する）

上記コードをpythonでスクリプト化され、makeコマンドとして実行できるようになっています。

ポイントとしては、***ELBに対するRoute53のTTLが60秒***のため、5が完了後、60秒以内にBlueサーバを停止してしまうと、Route53はまだBlueに接続してしまうため接続エラーとなってしまいます。
なので、スクリプト内で5の後に80秒ほどスリープしてから6を実行するように調整しました。

# で、結局Goにしてよかったの？
それは僕にもわかりません。
というかこれから分かってくるだろうかと思っています。

間違いなく、マイクロサービス化やなどのインフラ環境は資産になり得るポイントだと思いますが、GoにしたことによってどれくらいAPIのレスポンスが改善したか、生産性が向上したかはこれから運用していく中で感じることでしょう。
今後、分かってきたタイミングで比較してまとめようかと思います。

それ以上に大きなメリットとしては、将来的な移行コストの削減かなと思っています。
今後会社の規模が拡大し、一緒に働くメンバーも増えてくる中で言語や開発環境をリプレイスすることはかなりの重いタスクになる事は想像しやすい事だと思います。

今後Go2のリリースも控えているので、開発コミュニティはますます活発になっていく事でしょう。
弊社Graffityもその勢いに乗れるよう頑張ります。

#　おわりに
Graffityはビデオ通話をしながらAR落書きが楽しめるアプリです。
みんなで書いた落書きを動画で保存してシェアしましょう！！

https://itunes.apple.com/app/apple-store/id1277452876?mt=8
![graffity](https://qiita-image-store.s3.amazonaws.com/0/243926/e90f3f89-dac1-e844-a97e-3b6bfcc3dc10.png)

Graffity Tech Blog
https://tech.graffity.jp/entry/2018/08/01/164651