Singed, Ruby 및 Rails 애플리케이션용 프로파일러 프런트 엔드

May 09 2023
Ruby 코드 블록, 특정 웹 요청 또는 특정 컨트롤러 작업이 왜 그렇게 느리게 실행되는지 이해하고 싶은 자신을 발견한 적이 있습니까? 과거에 speedscope와 같은 프로파일링 도구를 사용했지만 번거로웠거나 사용 방법을 알아내려고 시도했지만 실패했을 수 있습니다. Josh Nichols(일명 @technicalpickles)가 작성한 Gusto의 새로운 프로파일링 프런트엔드인 Singed를 소개합니다.

Ruby 코드 블록, 특정 웹 요청 또는 특정 컨트롤러 작업이 왜 그렇게 느리게 실행되는지 이해하고 싶은 자신을 발견한 적이 있습니까? 과거에 speedscope와 같은 프로파일링 도구를 사용했지만 번거로웠거나 사용 방법을 알아내려고 시도했지만 실패했을 수 있습니다.

플레임그래프: 아무거나… 그게 다야!

Josh Nichols(일명 @technicalpickles) 가 작성한 Gusto의 새로운 프로파일링 프런트엔드인 Singed를 소개합니다 . Singed는 몇 가지 도구( stackprof , rbspy , speedscope ) 에 대한 스위스-아미-나이프 프런트엔드로 제작되어 화염 그래프를 쉽게 캡처하고 볼 수 있도록 도와줍니다. .

왜 또 다른 프로파일링 도구인가?

Singed는 어디에서나 사용할 수 있는 커널에 새로운 메서드를 추가합니다.

flamegraph {
  # your code here
}

기본적으로 플레임그래프를 보고자 하는 대부분의 Ruby 개발자는 stackprof 의 우수하고 사용하기 쉬운 프런트엔드인 rack-mini-profiler 를 사용합니다 . URL 끝에 ?pp=flamegraph를 추가하기만 하면 브라우저에서 Flamegraph가 열립니다.

그러나 우리는 종종 브라우저의 탐색 모음에 있는 현재 URL이 아닌 항목을 프로파일링하려고 합니다.

예를 들어 Apollo와 같은 게이트웨이를 통해 생성되는 GraphQL 요청을 프로파일링할 수 있습니다. Apollo Gateway가 요청하는 데 사용하는 URL을 쉽게 찾을 수 없을 수 있으므로 복제하고 랙 미니 프로파일러를 사용하여 화염 그래프를 캡처하는 것이 어렵습니다.

또는 Ruby 코드 블록이나 백그라운드 작업 또는 테스트를 프로파일링하고 싶을 수도 있습니다. 이 작업을 수행하기 위해 자신의 코드를 작성하고 stackprof를 직접 호출할 수 있지만 출력을 파일로 리디렉션하는 데는 수십 줄의 상용구가 필요하며 여전히 브라우저에서 수동으로 열어야 합니다.

Speedscope, Stackprof 및 rbspy를 사용하는 이유는 무엇입니까?

Singed는 기본적으로 다음 세 가지 도구를 감싸는 래퍼입니다.

  • 화염 그래프 시각화 장치인 Speedscope .
  • Ruby용 샘플링 프로파일러인 stackprof .
  • rbspy , Rust로 작성된 Ruby용 또 다른 샘플링 프로파일러.
Speedscope의 비주얼라이저는 아름답고 매우 빠르며 큰 프로필에서도 마찬가지입니다.

stackprof는 Ruby용 샘플링 프로파일러입니다. 이는 Ruby VM용 C 확장으로서 Ruby 프로세스와 동시에 "시작"되어야 합니다. rbspy는 다르게 작동합니다. 실제로는 sudo 권한을 사용하여 외부에서 Ruby 프로세스의 메모리를 읽습니다. 따라서 언제든지 Ruby 프로세스에 연결할 수 있으므로 Singed는 이를 사용하여 CLI에서 Ruby 프로세스를 프로파일링합니다.

stackprof 및 rbspy와 같은 샘플링 프로파일러는 더 큰 코드베이스로 상당히 잘 확장되기 때문에 훌륭한 선택입니다. ruby-prof 와 같은 추적 프로파일러는 애플리케이션 실행과 관련된 막대한 양의 코드로 인해 Gusto 규모에서 실패하는 경향이 있습니다.

마지막으로 stackprof와 rbspy는 커뮤니티에서 많은 지원을 받고 있습니다. 예를 들어 새 Ruby 버전을 지원하기 위해 자체적으로 프로파일러를 업그레이드할 필요가 없습니다.

빠른 기능 둘러보기

Singed가 실제로 무엇을 할 수 있는지 간단히 살펴보겠습니다. Singed를 사용하는 가장 좋은 방법 중 하나는 Rails 앱에서 간단한 코드 블록을 프로파일링하는 것입니다.

예를 들어 MyWorker라는 백그라운드 작업을 프로파일링하고 싶다고 가정해 보겠습니다. myprofile.rb라는 파일을 만들어 Rails 애플리케이션 루트에 넣은 다음 다음을 추가합니다.

user = User.first
flamegraph { MyWorker.new.perform(user) }

bin/rails runner myprofile.rb

프로파일과 관련하여 자주 발생하는 또 다른 문제는 코드 조각을 프로파일링하는 데 필요한 상태를 설정하는 것이 때때로 매우 복잡하다는 것입니다. 매우 구체적인 데이터베이스 상태가 필요하거나 많은 코드를 먼저 실행해야 할 수도 있습니다. 종종 이 설정은 테스트에 이미 존재합니다.

Singed를 사용하면 테스트 프로파일링이 정말 쉬워집니다. 이는 물론 테스트 스위트를 프로파일링하고 최적화할 수 있음을 의미하지만 실제로는 많은 특정 설정이 필요한 코드를 프로파일링하는 데 더 유용합니다.

require 'singed/rspec'
RSpec.describe YourClass do
  it "is slow :(", flamegraph: true do
    # your code here
  end
end

Singed의 또 다른 사용 사례는 프로파일링 요청입니다. Gusto에는 Rails 백엔드에 요청하는 GraphQL 게이트웨이(Apollo)가 있습니다. 때로는 이러한 요청을 프로파일링하고 싶지만, Apollo 백엔드가 Rails로 보내는 URL과 요청 본문을 모르기 때문에 rack-mini-profiler로는 그렇게 하기가 매우 어렵습니다. 대신 Singed에서 제가 하는 일은 다음과 같습니다.

  • 프런트엔드에서 GraphQL 백엔드 요청을 트리거합니다.
  • Chrome DevTools에서 해당 요청을 "가져오기"로 복사합니다. 이를 통해 Javascript 콘솔에 붙여넣고 필요에 따라 이 하나의 GraphQL 요청을 트리거할 수 있습니다.
  • 백엔드 서버를 중지했다가 다시 시작합니다. 이번에는 SINGED_MIDDLEWARE_ALWAYS_CAPTURE=1 환경 변수를 추가합니다.
  • Javascript 콘솔에서 요청을 다시 트리거합니다.

Rails 애플리케이션 부팅을 쉽게 프로파일링할 수도 있습니다.

bundle binstub singed
bin/singed -- bin/rails runner 'true'

용도가 많은 프로파일러 프런트엔드

Singed를 시도해 보셨기를 바랍니다. 여기 Gusto에서 거의 매일 사용합니다.

이 내용이 흥미로웠다면 GitHub 에서 확인하십시오 .