The Go Blog
GoでStatHatを構築する
はじめに
私の名前はパトリック・クロスビーで、Numerotronという会社の創業者です。私たちは最近StatHatをリリースしました。この記事は、StatHatの開発にGoを選んだ理由と、Goの具体的な使用方法について書かれています。
StatHatは、コード内の統計情報やイベントを追跡するためのツールです。HTMLデザイナーからバックエンドエンジニアまで、誰でも簡単にStatHatを使用できます。HTML、JavaScript、Go、その他12種類の言語からの統計情報の送信に対応しています。
数値をStatHatに送信すると、美しく、完全に埋め込み可能なデータグラフが生成されます。StatHatは、指定されたトリガーが発生したときにアラートを送信し、毎日のメールレポートを送信するなど、さまざまな機能を提供します。したがって、アプリケーションの追跡ツールやレポートツールを作成する時間を費やす代わりに、コードに集中できます。あなたが実際の作業を行っている間、StatHatは山頂の巣にいるワシのように、あるいはメスを片手に待機するベビーシッターのように、鋭く警戒し続けます。
ニューヨーク、シカゴ、サンフランシスコの気温を示すStatHatグラフの例です。
アーキテクチャの概要
StatHatは、主に2つのサービスで構成されています。受信統計/イベントAPI呼び出しと、統計の表示および分析を行うWebアプリケーションです。データ収集とデータインタラクションを分離するために、これらを可能な限り別々に保ちたいと考えました。これには多くの理由がありますが、主要な理由の1つは、大量の自動化されたAPI HTTPリクエストを処理すると予想されるため、人間が操作するWebアプリケーションとは異なる最適化戦略がAPIサービスに必要になるためです。
Webアプリケーションサービスは多層構造です。Webサーバーはすべてのリクエストを処理し、それらをインターアクター層に送信します。単純なタスクの場合、インターアクターが必要なデータを生成します。複雑なタスクの場合、インターアクターは複数のアプリケーションサーバーに依存して、グラフの生成やデータセットの分析などのタスクを処理します。インターアクターの処理が完了すると、Webサーバーは結果をプレゼンターに送信します。プレゼンターは、HTMLまたはJSONでHTTPリクエストに応答します。サービスの需要が時間とともに増加および変化するにつれて、Web、API、アプリケーションサーバー、およびデータベースを水平方向にスケーリングできます。各アプリケーションサーバーには複数のコピーが実行されているため、単一障害点はありません。インターアクター層により、http、コマンドライン、自動テスト、モバイルAPIなど、システムへのさまざまなインターフェースを持つことができます。StatHatはデータストレージにMySQLを使用しています。
Goを選ぶ
StatHatを設計した際、開発ツールのチェックリストとして以下のような項目を挙げました。
-
バックエンドとフロントエンドシステムで同じプログラミング言語を使用する
-
優れた高速なHTMLテンプレートシステム
-
多くの試行錯誤のための高速な起動、再コンパイル、テスト
-
1台のマシンで多数の接続
-
アプリケーションレベルの並行処理を扱うための言語ツール
-
高いパフォーマンス
-
階層間での通信のための堅牢なRPC層
-
豊富なライブラリ
-
オープンソース
私たちは多くの人気のある、またそうでもないウェブテクノロジーを評価し、最終的にGoで開発することを選択しました。
2009年11月にGoがリリースされたとき、私はすぐにインストールし、その高速なコンパイル時間、ゴルーチン、チャネル、ガベージコレクション、そして利用可能なすべてのパッケージに魅了されました。特に、アプリケーションが使用するコードの行数が非常に少ないことに感銘を受けました。すぐに、クエリを入力すると5つの外国語辞書を並行して検索するLangalotというウェブアプリを作成する実験をしました。それは驚くほど速かったです。私はそれをオンラインに公開し、2010年2月から稼働しています。
以下のセクションでは、GoがStatHatの要件をどのように満たし、私たちの問題を解決するためにGoを使用した経験について詳しく説明します。
ランタイム
私たちはAPIとウェブアプリサーバーに標準のGoのhttpパッケージを使用しています。すべてのリクエストはまずNginxを通過し、ファイル以外のリクエストはGoを搭載したhttpサーバーにプロキシされます。バックエンドサーバーはすべてGoで記述されており、rpcパッケージを使用してフロントエンドと通信します。
テンプレート
標準のテンプレートパッケージを使用してテンプレートシステムを構築しました。私たちのシステムは、レイアウト、一般的なフォーマット関数、および開発中にテンプレートをオンザフライで再コンパイルする機能を追加しています。Goのテンプレートのパフォーマンスと機能には非常に満足しています。
試行錯誤
以前の仕事で、私はC++で書かれた「Throne of Darkness」というビデオゲームに取り組んでいました。いくつかヘッダーファイルがあり、それらを修正するとシステム全体の再構築が必要で、20〜30分かかりました。もし誰かが`Character.h`を変更しようものなら、他のすべてのプログラマーの怒りにさらされました。この苦痛に加えて、開発時間も大幅に遅くなりました。
それ以来、私は常に、高速で頻繁な試行錯誤を可能にするテクノロジーを選ぶようにしてきました。Goでは、コンパイル時間は問題になりません。システム全体を数分ではなく数秒で再コンパイルできます。開発用ウェブサーバーは瞬時に起動し、テストは数秒で完了します。前述のとおり、テンプレートは変更されると再コンパイルされます。その結果、StatHatシステムは非常に扱いやすく、コンパイラがボトルネックになることはありません。
RPC
StatHatは多層システムであるため、すべての通信が標準的になるようにRPC層を設けたいと考えていました。Goでは、rpcパッケージとGoオブジェクトのエンコードにはgobパッケージを使用しています。Goでは、RPCサーバーはGoオブジェクトを受け取り、その公開メソッドを登録するだけです。中間的なインターフェース記述言語は必要ありません。非常に使いやすく、コアアプリケーションサーバーの多くは300行以下のコードで記述されています。
ライブラリ
SSL、データベースドライバー、JSON/XMLパーサーなどのライブラリを再記述するのに時間を費やしたくありません。Goはまだ新しい言語ですが、多くのシステムパッケージと増え続けるユーザー提供パッケージがあります。いくつかの例外を除けば、必要なものはすべてGoパッケージで見つけることができました。
オープンソース
私たちの経験では、オープンソースツールを使用することは非常に貴重でした。もし何か問題が発生した場合、あらゆるレイヤーでソースを調べて、ブラックボックスがないことは非常に役立ちます。言語、ウェブサーバー、パッケージ、ツールのコードがあることで、システムの各部分がどのように機能するかを理解できます。Goのすべてはオープンソースです。Goのコードベースでは、パッケージや言語機能の使用方法に関する素晴らしい例が示されているため、頻繁にテストを読んでいます。
パフォーマンス
人々はデータの最新分析のためにStatHatに依存しており、システムは可能な限り応答性が高い必要があります。私たちのテストでは、Goのパフォーマンスはほとんどの競合他社を圧倒しました。Rails、Sinatra、OpenResty、Nodeと比較してテストしました。StatHatは、リクエストに関するあらゆる種類のパフォーマンス指標、特定のタスクの実行時間、使用メモリ量などを追跡することで、常に自己監視してきました。このため、さまざまなテクノロジーを簡単に評価できました。また、Goのテストパッケージのベンチマークパフォーマンステスト機能も活用しました。
アプリケーションレベルの並行処理
以前はOkCupidのCTOを務めていました。そこでOKWSを使用した経験から、特に動的なWebアプリケーションにおいて、非同期プログラミングの重要性を学びました。データベースからユーザーを読み込み、次にその統計情報を見つけ、次にアラートを見つける、といったことを同期的に行うべきではありません。これらはすべて並行して行うべきですが、驚くべきことに、多くの人気のあるフレームワークには非同期サポートがありません。Goは、コールバック地獄なしで言語レベルでこれをサポートしています。StatHatは、複数の関数を並行して実行するためにゴルーチンを、ゴルーチン間でデータを共有するためにチャネルを extensively 使用しています。
ホスティングとデプロイメント
StatHatはAmazonのEC2サーバーで稼働しています。私たちのサーバーはいくつかのタイプに分けられています。
-
API
-
Web
-
アプリケーションサーバー
-
データベース
各タイプのサーバーは少なくとも2台あり、高可用性を実現するために異なるゾーンに配置されています。新しいサーバーを追加するのに数分しかかかりません。
デプロイのために、まずシステム全体をタイムスタンプ付きディレクトリにビルドします。私たちのパッケージングスクリプトはGoアプリケーションをビルドし、CSSファイルとJSファイルを圧縮し、すべてのスクリプトと設定ファイルをコピーします。このディレクトリはすべてのサーバーに配布され、すべて同じ配布物を持つことになります。各サーバー上のスクリプトは、そのEC2タグをクエリして、実行すべきものを決定し、サービスを開始/停止/再起動します。私たちは頻繁にサーバーの一部にのみデプロイします。
詳細
StatHatの詳細については、stathat.comをご覧ください。私たちが書いたGoコードの一部を公開しています。すべてのオープンソースStatHatプロジェクトについては、www.stathat.com/srcをご覧ください。
Goの詳細については、golang.orgをご覧ください。
次の記事: Goコミュニティを知る
前の記事: ゼロからGoへ:24時間でGoogleホームページに公開
ブログインデックス