TabiTabiでCTOをしている藤原です。カバー写真は社員旅行で行った東武ワールドスクウェアでの写真です^^
今回はTabiTabiの現在(2017/09)の技術スタックと今後入社したら携われる技術領域についてお話したいと思います。
技術スタック
サーバーアプリケーション
技術:Ruby(2.3.3), Ruby on Rails(5.1), Unicorn, Nginx
本番はNginx -> Unicorn -> Railsの構成。
設計は軽量DDDを取り入れており、Formクラスやサービスクラス、バリューオブジェクトなど使ってます。大規模開発を想定しており、素朴な構成ではないですね。ただし、RailsのActive RecordがそもそもDDDのリポジトリの概念と相性が悪いため、相反する時はRailsの思想に寄せています。
テストは現在カバレッジ44%で数値を追ってるわけではないが50%をキープしたいなーと思ってます(batchとcrawlerを除けば60%ほど)グロースフェーズで80%、安定期で100%になるようにコントロールしていきます。サービスクラス、モデルは基本的には大体書いて、大事なところはリクエスト単位でviewも含めてテストを書く方針です。
クローリングもそこそこしており、大規模にクローリングするところはAWS LambdaでFaas設計にしています。スケーリングと価格面で良いです。
クライアントアプリケーション
フロントエンド:webpack, ES6, React, Redux, Thunk, ImmutableJs
管理画面はES6でReact + Redux + thunk + ImmutableJSで設計しています。割と大規模に開発してますが、変更などはしやすいなと感じています。ファイル数が多くなるので、ファイルのネーミングルールはもう少しちゃんとしておけばと思っております。
ユーザーページは管理画面と分けており、Typescriptや非同期処理のmiddleware、ロジックの書き方やエラー処理などもう少し改善した形で作ろうと現在進行中です。
アプリ制作も視野に入れているため、React Nativeとロジックやドメインを共有するように設計していく予定です。
目下の悩みはモデルをImmutableJSで作っており、RESTAPIと大体連動させているが、has_manyやbelongs_toも連動させた結果、子要素のAPIでも親要素を返す設計になっており(逆も)、返却量が多くなってるなあと感じています(has_many -> has_manyの子要素だと親の親まで返したり。。みなさんどういう設計にしてるんでしょうか?)
あと、バージョンアップがRailsのgemの関係でできてないのがヤバいなと思っており、こちらは現在対応中です。
データベース、ミドルウェア
データベース:MySQL, Redis, Elasticsearch
MySQLは制約を積極的につけていく方針でNULLl制約、外部キー制約、ユニーク制約は必要なところは必ずつけています。
indexも量が多くなりそうなテーブルやselect頻発するところには必ずつけており、後で火を吹かないようにしています。
Elasticsearchも検索で多用しており、マイグレーションや全文検索のチューニングあたりを現在整備中です。
ログ収集、分析、監視
ログ収集・分析:Fluentd, Redash, Sentry
監視:AWS Cloud Watch, New Relic
ログ収集はFluentd + Elasticsearch + Kibanaの通常構成です。
エラーログのアラートはSentryを使っております。
分析はRedashを使っており、MySQLのデータのみ見れます。ゆくゆくはログ基盤をDWHを使ってしっかり構築していく予定です。
監視はアプリケーションレイヤーはNew Relic、システムレイヤーはCloud Watchでアラート通知しています。ここも大きくなる段階で監視基盤や詳細なパフォーマンス計測できるように作っていく予定です。
環境構築
環境構築:Vagrant, Virtual Box, Chef, Terraform, Packer, Capistrano
開発環境はVagrant, Virtual Box, Chefで構築しており、本番はPacker, ChefでAMI作成して、TerraformでEC2やVPCなど必要なものを構築しています。
Chefの更新があるタイミングのみEC2をblue greenデプロイで切り替えてますが、それ以外はEC2の入れ替えはしていません。デプロイ周りは自動化やオートスケールも含めて改善の余地があります。
dockerなども触って検討しましたが、chefの乗り換えが大変なのとまだこなれてないので静観中です。
その他
その他:Github, Slack, CircleCI, Wrike, Kibela
CircleCIでは静的解析やテストなどを回しております。
コミュニケーションはSlack、タスク管理はWrike、情報共有はKibelaを使っています。
まとめ
SaaSやOSSを積極的に採用して、うまくインテグレーションすることに重きを置いてます。定番の組み合わせが好きなのと、スタートアップにしてはどちらかといえば固い設計に振れてるかもと思っております。定期的にリファクタや新技術の導入、バージョンアップできてるのは良いかなと思います。
入社したら携われる技術領域
サーバーサイドアプリケーション
インターネットビジネスの定番であるマッチングビジネスであり、旅行という分野はホテル、航空、観光、レストランでそれぞれ業界が異なり、そのドメインを整理して作っていくのは面白い題材かと思います!検索、在庫、予約、決済などマッチングビジネスで重要なドメインが一通り揃っており、検索は精度向上が求められ、決済や予約は正確性が求められと色んな要素が求められるところも奥が深いシステムかと思います。
また、チャットと言う古くて新しいUIでWebViewを使ったGUIとチャットのテンプレートを含む会話をうまく設計するのは新しいチャレンジかと思います。
クライアントアプリケーション
Javascriptのトレンドを取り入れており、Reactの大規模設計やReact Nativeを使ったアプリ開発ができるのが面白いポイントかと思います。オペレーター側のチャット画面ではチャットはもちろん、検索や予約管理、タグ付けなどをしており、今後はサジェスト機能やより使いやすい検索に力を入れていくため1ページで色んなことをできるようにしないといけません。また、モバイルファーストでアプリ、Web両方で同一技術でユーザーに使いやすいシステムを追求していくのも面白いポイントかと思います。
インフラ
コード化はほぼできてますが、デプロイ周りなどはまだまだ整理、自動化仕切れてません。
ログ基盤も現在はできてないですが、KPI抽出や検索、レコメンドも含めてどんどんデータをためて、使えるようにしていく予定です。
機械学習
現在は勉強だけしてる状態ですが、1年以内には積極的に導入していく予定です。
アプリ技術の市場規模が伸びて初期にiOSやAndroid開発に携わった人が今需要が強いように、機械学習の市場規模も今後10〜20年単位で見るとアプリの市場規模以上に伸びるとされているので、サーバーエンジニアなどで機械学習に手を出したいという人には今入社してチャット+自然言語処理やマッチングと言う機械学習の王道分野に投資するのは非常に理にかなったキャリア戦略だと思います!
弊社は段階的にデータをためていってるため、アルゴリズムも簡単なものから実施します。そのため、現在機械学習未経験でもキャッチアップして、簡単なものを開発しつつ徐々に難しい技術を学ぶのに適した環境かと思います。
まとめ
現在の技術スタックと今後1 ~ 2年までのチャレンジできる技術領域をお伝えしました。少しでもご興味がでれば嬉しいです。転職までは踏み切れないけど、週末だけ関わりたいなども歓迎しております。
最後まで見ていただきありがとうございました。