MIXIには、探究心溢れるエンジニアがたくさん在籍しています。
その探究心は業務で扱う技術に留まらず、趣味で書いているプログラムだったり、個人的に研究している言語だったりと、自身の気になった技術への追求も留まることを知りません。
そこで、社内のエンジニアに“好きな技術”について、思う存分に語ってもらうシリーズを始めました。
ルールはこの通り。
・業務で使っている技術でも、使われていない技術でもOK
・あくまでも個人的な見解で
・その技術のどこが面白いのか
・愛を込めて語り尽くしてもらう
第10回目は、新規事業のサーバーサイドに携わる三上に「Go」の魅力をたっぷりと語ってもらいました!
三上 隼人(みかみはやと)モンスト事業本部
MIXIへは2021年9月に入社し、現在は新規事業開発部横断推進グループでサーバー開発のサポートメイン。多種多様なプロジェクトや採用技術に四苦八苦しつつ、日々勉強しながら奮闘中。
Cのように速く、Cよりもシンプル?
━━まずはじめに、どのような業務に就かれているか教えて下さい。
主には新規プロジェクトでサーバー実装に関わる技術的なサポートを行っています。ゲームサーバーがメインですが、インゲーム・アウトゲーム両方の経験があるので、フレキシブルに対応していますね。
━━「Go」は人気な言語としてよく耳にしますが、実際どのようなものか教えて頂けますか?
「Go」はGoogleが開発し、2012年にリリースされたプログラミング言語で、D言語やRustなどの「Better C」というジャンルの一つとして位置づけられています。C言語のように処理が速く、かつC言語よりも扱いやすく設計されているのが特徴でしょうか。構造としてはC言語に似ていて、静的型付け言語にあたりますが、PythonやJavaScriptなどの動的型付け言語のような書きやすさもあります。
━━主にどのようなシーンで使われていますか?
大量のメッセージをさばいたり、ネットワークに関するライブラリが標準装備されていたりするので、サーバー構築に使われることが主だと思います。有名なOSSだとDockerやKubernetes、分散DBのCockroachDBやプッシュ配信システムGaurunなどで使われています。大量の処理をさばくプログラムを実装しやすいので、ゲームサーバーの実装に使われることもありますね。MIXIの新規事業でも実際に使っているプロダクトがありますし、他社でもゲームサーバーに使っている事例を耳にするようになりました。
━━主な特徴を詳しく教えてください。
特筆すべきところとしては「ライブラリの扱い」と「クロスプラットフォームへのサポート」の2点でしょうか。
ライブラリの扱い
CやC++の場合は依存ライブラリを準備するのに手間取ることがありますが、「Go」で苦労することはほとんどありません。ネットワーク周りであれば標準ライブラリだけでも充実していますし、外部ライブラリのインポートやカスタマイズも非常に簡単です。また、「Go」を実装されたOSSは多種多様で、「Go」に慣れているだけでさまざまな知見を吸収できる点もありがたいですね。
クロスプラットフォームへのサポート
オフィシャルでWindows、macOS、Linuxがサポートされているのに加えて、Android、iOS、WebAssemblyまで対応しています。クロスコンパイルは「Go」独自のものではないのですが、各プラットフォームに合わせて調整する必要がほとんどないので、使いやすい印象です。私が助けられているのは、特にエンジニアと非エンジニアでサポートツールを共有している場合。Linuxでも動かしつつ、Windowsでも動かしたいとなると、サポートツールを導入する前に環境構築をしてもらう手間が発生するものですが、「Go」だとそれが必要ない。ファイル一つ共有するだけで誰でもツールを実行できて、パフォーマンス上の問題も起きにくいです。プランナーのような非エンジニアと開発する上ではとても助かります。
読みやすいから追いやすい
━━三上さんが気に入っているのはどのような点ですか?
一言でいえば、可読性です。「Go」は今の言語に珍しいほどに機能を最小限に抑えていて、記述をシンプルに行えるように設計されているため、可読性が高いんです。時に「機能が少なすぎる」と言われるほどですが、「Go」を使った開発においては設計段階でそれを踏まえておけば特に問題はありません。また、コードフォーマッターが同梱されているので、コーディングスタイルをある程度統一することができます。標準のフォーマッターがあるというのは、複数のエンジニアで複雑なシステムを構築する際には特に大事なことだと思います。
「Go」で実装されたOSSが多様で知見を得やすいというのも、可読性が優れているおかげだと思います。私自身、様々なOSSのソースを読むことで理解を深めてきましたし、それによって技術も向上している実感があります。「Go」のOSSだとよりスムーズに把握することができ、理解すべきことに集中しやすい印象があります。「Go」自身も「Go」で実装されているので手軽に深掘りできます。
━━「Go」は実際の開発の中でも活躍していますか?
ずいぶん前の実績になってしまいますが、「Subversionで管理されている作業リポジトリのブランチに応じて、更新を適用するサーバーを自動で選別してほしい。開発ブランチなら開発サーバー、QAブランチならQAサーバーというように、作業しているブランチから判断して欲しい」という要望に応えられたのは「Go」ならではだと思います。
この要望はエンジニア職以外の方から上がっており、プロジェクトの状況として新たに複雑なワークフローを導入することが難しい段階でした。また「コミット前に確認を行いたい」というのも要件であったため、コミットを起点にCIで対応することも出来ませんでした。これに対して、Subversionからデータを抜き出して、要望通りの更新を行うツールを作成することにしました。SubversionはSQLiteでメタデータを管理しているため「Go」でデータベースのパーザを作成し、確認事項などを表示するGUIも整備しました。クロスプラットフォームビルドが手軽だったおかげで、作業者がWindows環境で使うツールと同じものを、LInux上で動作するCIでも利用することができました。
━━他にも、「Go」の良さを体感した出来事はありますか?
もともと私はC言語があまり得意ではなく、特にポインタの挙動に関しては分かったようで分かっていないような状況でした。C言語ではメモリを細かく操作するためにポインタという変数の扱いが肝になるのですが、問題箇所の特定に苦労することが多々ありました。ですが、「Go」の場合は処理系が適切に取り扱ってくれるため、ちょっとした間違いのデバッグに時間を使うということはありません。「Go」でさまざまな経験を重ねた後でC言語に戻ってきた時、以前はつまづいていた部分を考慮しながら実装できるようになっていました。わかりにくいかもしれませんが、安全運転装置のある車に乗るようになって車両感覚が身についたので、安全運転装置のない車でも感覚をつかめるようになった、という感じでしょうか。
━━なるほど!でも逆にまだ伸びしろのあるような部分もありますか?
望まれている機能としてgenericsやエラー処理がよく話題にのぼりますが、genericsはv1.18で導入されました。特に標準に取り込まれて欲しい機能は、エラー時のスタックトレースでしょうか。もちろん、自作したりOSSを使用したりすることも出来るのですがあまり充分に使えることもなく…標準機能として追加されると、エラー時に追いやすくなるので大変助かりますね。
━━では最後に、「Go」を使ってチャレンジしたいことや、次に気になっている「Go」以外の技術について教えて頂けますか?
まず、まだまだ「Go」で理解できていない部分があるので継続して深掘りしていきたいですね。深掘りしたところで今すぐ業務には活用できる知見は得られないかもしれませんが、意外なところでカチッとはまることがありますし。また、ゲーム開発への応用も試していきたいです。特にリアルタイム通信などは事例を耳にしますし、自分でも試作してみています。
「Go」以外で気になっている技術というと、「Better C」な言語が現在もたびたび発表されているので注目しています。課題意識は似通っていますがアプローチの仕方は全く異なっていますし、言語そのもの以外でもツールチェーンのみ活用してみるなどの展開があったりするので、今後の発展が楽しみです。