Railsにおける分散要求追跡


The microservices パターンは非常に議論のトピックです.長所と短所は、フォーラム、ブログ、ポッドキャスト、ソーシャルメディアの上で、そして、文字通り他の至る所で熱く議論されます.私たちは別の日にその引数を飛ばします.どのように、我々はより純粋なRuby on Rails WorldのMicroServiceアーキテクチャでより良いリクエスト追跡を可能にするかについて飛び込みましょう.分散追跡/デバッグは,マイクロサービスアーキテクチャにおける最大の課題の一つである.
The X-Request-ID は標準のHTTPヘッダです.ブログ投稿で定義されているヘッダは以下の通りです.

A unique request ID, represented by a UUID, is generated at each HTTP request received by the platform routing servers. It is added to the request which is passed to your application containers.
If the X-Request-ID header is already defined by the client, it won’t be overridden except if it doesn’t respect the following format:
20-128 alphanumerical characters and the symbols +, =, / and -.


ここで注目すべき重要な点は、

If the X-Request-ID header is already defined by the client, it won’t be overridden


すべての外部のマイクロサービスを呼び出すとき、我々は同じヘッダーを我々の利点に使用します.
The ActionDispatch::Request Railsモジュールはuuid 利用可能なメソッドrequest オブジェクト.これをコントローラで使用できます.
class ApplicationController < ActionController::Base
  before_action :set_thread_data

  private
  def set_thread_data
    Thread.current[:uuid] = request.uuid
  end
end
次に、これを活用することができますThread 我々のマイクロサービスに要求をするプロキシクラスからの文脈.
class ServiceProxy
  attr_reader :headers, :params, :method, :url, :handler

  def initialize(headers:, params:, method:, url:, handler:)
    @headers = headers
    @params = params
    @method = method
    @url = url
    @handler = handler
  end

  def make_request
    circuit.run do
      RestClient::Request.execute(
        method: method, url: url, payload: params, 
        headers: headers, read_timeout: CircuitConstants[handler][:read_timeout],
        open_timeout: CircuitConstants[handler][:open_timeout]
      )
    end
  end

  private
  def circuit
    Circuitbox.circuit(handler, CircuitConstants[handler])
  end

  def headers
    @headers_with_request_id ||= begin
      return @headers unless @headers.is_a?(Hash)
      @headers['X-Request-Id'] = Thread.current[:uuid]
      @headers  
    end
  end
end
すべての最新のWebフレームワークは、このヘッダーを尊重し、要求レベルUUIDを設定するために使用します.Railsでは、これは ActionDispatch::RequestId ミドルウェア
また、これらの要求UUIDを利用するためにアプリケーションレベルのタグ付けを設定する必要があります.
# config/application.rb
config.log_tags = [ :uuid ]
上記を実装した後、ログはリクエストuuidにタグ付けされ、以下のログスニペットのようになります.

上記のセットアップで、すべてのマイクロサービスを通して流れるすべての要求は、同じですrequest-id 簡単にリクエストをトレースし、順番に、すべてのアプリケーションの問題を、簡単にデバッグ可能に設定します.