技術的負債に窮する
弊社ナイルは、「Appliv」というスマートフォンアプリを見つけやすくするWebサービスを、2012年8月より運営しています。現在、世界10か国で展開しており、規模としては国内のWeb版だけで月間600万UU(ユニークユーザー)となっています。iOSアプリ版、Androidアプリ版も提供しており、サービスリリース後わずか1年で300万ダウンロードを突破しました。
Appilvの開発はPHPで進めてきました。しかし、サービスの規模が大きくなるに従ってエンジニアの数が増え、2014年からはiOSアプリの開発がスタートしてPHP以外の言語で開発する必要性が生まれる中で、PHPを使って既存のコードを拡張していくことに対する問題が表面化してきました。
問題の1つは、コードの重複です。開発はプロダクトごとにリポジトリを分けて行っていましたが、いつの間にか、各プロダクトで似たようなものを重複して実装していたのです。「プロダクト間でコピーし合う」という解決方法では無理があったため、その後、サブモジュールを導入してコードを共通化しました。
ところが今度は、サブモジュールを誰が更新するのか、更新された内容をどう把握し対応するのかが問題となりました。さらに、どのプロダクトがどのサブモジュールを使用しているかを可視化できず、結果として、消してよいのかどうかも判断できない謎のコードが技術的負債として数多く残ってしまいました。
安全性やスケーラビリティへの懸念
さらに、サービスが拡大するにつれ、PHPで実装されていることによる安全性やスケーラビリティの確保の難しさも、無視できなくなっていきました。
PHPプログラムのエラーは、実行するまで気づくことができません。よく実行される処理ならば開発中に気づきますが、稀にしか発生しないパターンや重たくて気軽に試せない処理にエラーが紛れ込んでいる場合、発見が遅れて、デバッグは面倒なものになります。また、PHPには変数宣言も型もないため、意図しないオブジェクトの書き換えが起こりえます。これが「キャッシュのキーに使っているオブジェクトが途中で書き換えられてしまい、キャッシュとして機能しない」といった発見の難しいバグを誘発します。
また、PHPでは処理の並列化が容易ではなく、スケーラビリティが低いこともサービスが拡大する中で大きな問題となりました。バッチサーバーを増やして同時に実行するといった対策で解消できる場合もありますが、そうすると今度は無駄な処理が発生したり、処理が重複したりとまた別の問題を引き起こしました。
開発者の確保も大きな問題に
問題はプロダクトの管理以外に、人的リソースの確保にもありました。1つは、Swift(当時はObjective-C)やJava(Android SDK)でスマートフォンのネイティブアプリを開発する人材の不足です。これらの言語とPHPでは言語としての隔たりが大きいため、スキルコンバートが難しく時間がかかります。ネイティブアプリのほうに人員を投入したくても社内だけでは間に合わず、外注に頼らざるを得ませんでした。
エンジニア採用も容易ではありません。何かをきっかけとして記憶に残る会社にならなくては、応募してもらえないからです。そこで弊社全体の方向性として「技術力を高め、それを売りにしていこう」という動きを本格化させました。その際に意識したのが「何かで一番を目指す」という点です。記憶に残る会社になる以外にも、在籍するエンジニアのやりがい向上にもつながります。
そうした中、開発者の間でちらほら話題に上るようになってきていたのがScalaでした。「次のプログラミングパラダイムになるのではないか?」というところから、弊社はScalaに賭けることにしました。2015年、開発の主軸言語をPHPからScalaへと切り替え、Applivもマイクロサービス化することが決まりました。
なぜScalaを採用したのか
もちろん、Scala以外の選択肢もありました。あえてScalaを選んだのは、次のようなメリットがあったからです。
1. Javaの資源やノウハウが使える
ScalaはJVM上で動作し、既存のJavaのプログラムと容易に連携させることができます。仮にScalaとして良いライブラリなどが見つからない場合でも、Javaのライブラリを取り込んで使えます。
2. 型推論や簡略化のためのシンタックスが充実しており、ドメインモデルを忠実に実装しやすい
Applivの実装はすでに複雑化しており、ドメインモデルを意識して再構築することが課題とされていました。PHPでもできたかもしれませんが、Scalaであればより実装しやすいのではないか、という期待がありました。
3. 静的型付けであり、イミュータブルな実装でアプリケーションの安全性を担保しやすい
PHPは動的型付けのため、変数の値がInt
なのかString
なのかわかりません。それが原因で起こるバグにはちょくちょく悩まされていました。Scalaは静的型付けなので、そうしたバグは回避できます。さらに、Scalaにはイミュータブル(オブジェクトの書き換え不可)な実装を採用することで、アプリケーションの安全性を担保しやすいという優位点があります。PHPではイミュータブルなオブジェクトを自然には扱えず、うっかり書き換えてしまうこともありました。
4. 処理の並列化が容易でスケーラビリティにも優れる
Scalaは、ActorやFutureを提供するフレームワーク「Akka[1]」によって、処理の並列化が容易なことも魅力です。アプリケーションのスケーラビリティにも優れています。PHPではスレッドが扱えません。いちおうプロセスforkはあるものの、使いやすいとは言い難いものです。データベース操作の完了を待たずにユーザーに応答を返したい場合や、重たいバッチ処理を実行する場合など処理の並列化が容易であればもっと改善できるポイントがいくらでもありました。
これらを踏まえてScalaへの移行が決まり、それを社内で共有したのは、2015年3月末のことでした。
注
[1]: ScalaおよびJava向けの並列・分散処理フレームワーク。アクターモデルを使った並行処理などを可能にする。