- 1.
git clone
およびgit push
over HTTP に依存しています。 - 2.CIランナーのロングポーリング
- 3.ファイルのアップロードとダウンロード
- 4.ウェブソケットプロキシ
- 簡単な説明(Workhorseの仕組み)
Workhorse に依存する機能
Workhorse 自体は機能ではありませんが、Workhorse なしでは効率的に動作しない GitLab の機能がいくつかあります。
GitLab.comの2020Q3では、Railsアプリケーションのスレッドが平均して約200MBのRSSを使用しているのに対し、Workhorseのゴルーチンでは約200KBであることを見てみましょう。
Workhorseに依存している機能の例:
1. git clone
およびgit push
over HTTP に依存しています。
Gitクローン、プル、プッシュが遅いのは、大量のデータを転送するためと、GitLab側でそれぞれCPUに負荷がかかるためです。Workhorseがなければ、GitリポジトリへのHTTPアクセスはアプリケーションへの通常のウェブアクセスと競合することになり、Railsアプリケーションサーバーを大幅に増やす必要がありました。
2.CIランナーのロングポーリング
GitLab CI RunnerはGitLabサーバをポーリングして新しいCIジョブを取得します。WorkhorseはCIランナーが座って新しいCIジョブを待つ “待合室 “のような役割を果たします。Goの効率性のおかげで、私たちは少ないコストでたくさんのRunnerを待合室に入れることができます。この待合室の仕組みがなければ、Railsサーバーの容量をもっと増やさなければならないでしょう。
3.ファイルのアップロードとダウンロード
ファイルのアップロードとダウンロードが遅いのは、ファイルが大きいためか、ユーザーの接続が遅いためです。WorkhorseはRailsの遅い部分を処理できます。これにより、CIアーティファクト、パッケージリポジトリ、LFSオブジェクトなどの機能の効率が向上します。
4.ウェブソケットプロキシ
ウェブターミナルのような機能では、ユーザーのウェブブラウザとインターネットから直接アクセスできないGitLab内部のコンテナとの間で長時間の接続が必要です。Railsアプリケーションのスレッドをこのような接続のプロキシに充てると、Workhorseに後処理をさせるよりもずっと多くのメモリが必要になります。
簡単な説明(Workhorseの仕組み)
- 例えば、JavaScriptファイルやCSSファイルはディスクから直接提供されます。
- WorkhorseはRailsから送信されたレスポンスを変更することができます: 例えばRailsで
send_file
、GitLab Workhorseはディスク上のファイルを開き、その内容をレスポンスボディとしてクライアントに送信します。 - Workhorse は Rails に権限を求めた後、リクエストを引き継ぐことができます。例:
git clone
の処理。 - WorkhorseはリクエストをRailsに渡す前に修正することができます。例: GitのLFSアップロードを処理するとき WorkhorseはまずRailsに権限を求め、次にリクエストボディを一時ファイルに保存し、ファイルパスを含む修正されたリクエストをRailsに送信します。
- WorkhorseはRailsの長期間のWebSocket接続を管理できます。例: 環境のターミナルWebSocketの処理。
- WorkhorseはPostgreSQLには接続せず、Railsと(オプションで)Redisにのみ接続します。
- Workhorseに到達するすべてのリクエストは、まずNGINXやApacheなどのアップストリームプロキシを通過すると仮定します。
- Workhorse はアイドル状態のクライアント接続をクリーンアップしません。
- RailsへのリクエストはすべてWorkhorseを経由すると仮定します。
詳しくは‘A brief history of GitLab Workhorse’をご覧ください。