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’をご覧ください。