Rails의 분산 요청 추적

microservices 패턴은 논쟁의 여지가 많은 주제입니다. 장단점은 포럼, 블로그, 팟캐스트, 소셜 미디어 및 문자 그대로 모든 곳에서 열띤 토론을 벌입니다. 우리는 다른 날에 그 논쟁을 건너뛸 것입니다. 순수 Ruby on Rails 세계의 마이크로서비스 아키텍처에서 더 나은 요청 추적을 가능하게 하는 방법에 대해 자세히 살펴보겠습니다. 분산 추적/디버깅은 마이크로서비스 아키텍처에서 가장 큰 과제 중 하나입니다.

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



모든 외부 마이크로 서비스를 호출할 때 이점을 위해 동일한 헤더를 사용합니다.

rails의 ActionDispatch::Request 모듈은 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

모든 최신 웹 프레임워크는 이 헤더를 존중하고 요청 수준 UUID를 설정하는 데 사용합니다. Rails에서 이것은 ActionDispatch::RequestId 미들웨어에 의해 처리됩니다.

또한 이러한 요청 uuid를 사용하려면 애플리케이션 수준 태그 로깅을 설정해야 합니다.

# config/application.rb
config.log_tags = [ :uuid ]

위의 구현 후 로그는 요청 uuid에 태그가 지정되고 아래의 로그 스니펫처럼 보이기 시작합니다.



위의 설정을 사용하면 모든 마이크로 서비스를 통과하는 모든 요청이 동일한request-id 집합을 가지므로 쉽게 요청을 추적하고 모든 애플리케이션 문제를 쉽게 디버깅할 수 있습니다.

좋은 웹페이지 즐겨찾기