Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

프로덕션에서 Ruby 성능 문제를 디버그하는 방법

성능이 하나의 기능이라는 것을 알고 있습니다. 그리고 개발 과정에서 많은 성능 문제를 찾아 수정할 수 있습니다.

하지만 프로덕션에서만 나타나는 속도 저하의 경우는 어떻습니까? 코드의 모든 라인에 로그 메시지를 추가해야 합니까? 그것은 단지 일을 더 느리게 할 것입니다! 아니면 어떤 스틱을 확인하기 위해 수많은 "아마도 이것이 고칠 수 있습니다" 커밋을 발송합니까?

분석을 위해 코드를 망칠 필요는 없습니다. 대신 rbtrace를 시도하십시오. -ing.

실행 중인 Ruby 앱 추적

rbtrace를 사용하면 코드를 추가하지 않고도 성능 문제를 감지하고, 다른 Ruby 프로세스 내에서 코드를 실행하고, 메서드 호출을 기록할 수 있습니다. gem "rbtrace"를 추가하기만 하면 됩니다. Gemfile에 .

Ruby의 메모리 누수 디버깅에 대한 Sam Saffron의 놀라운 게시물에서 rbtrace에 대해 배웠습니다(아직 확인하지 않은 경우 실제로 확인해야 함).

해당 게시물에서 Sam은 rbtrace를 사용하여 프로세스에서 사용된 모든 개체를 확인했습니다.

bundle exec rbtrace -p $SIDEKIQ_PID -e 'Thread.new{GC.start;require "objspace";io=File.open("/tmp/ruby-heap.dump", "w"); ObjectSpace.dump_all(output: io); io.close}'

대단합니다. 하지만 할 수 있는 일이 훨씬 더 많습니다.

rbtrace로 무엇을 할 수 있나요?

프로덕션에서 실행 중인 SQL 문(및 소요 시간)을 보고 싶었던 적이 있습니까?

~/Source/testapps/rbtrace jweiss$ rbtrace -p $RAILS_PID --methods "ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#execute_and_clear(sql)"             
*** attached to process 7897
ActiveRecord::ConnectionAdapters::PostgreSQLAdapter#execute_and_clear(sql="SELECT  \"articles\".* FROM \"articles\" WHERE \"articles\".\"id\" = $1 LIMIT 1") <0.002631>

2초 이상 걸리는 모든 메소드 호출은?

~/Source/testapps/rbtrace jweiss$ rbtrace -p $RAILS_PID --slow 2000
*** attached to process 8154
    Integer#times <2.463761>
        ArticlesController#create <2.558673>

특정 메소드가 호출될 때마다 알고 싶으십니까?

~/Source/testapps/rbtrace jweiss$ rbtrace -p $RAILS_PID --methods "ActiveRecord::Persistence#save" 
*** attached to process 8154
ActiveRecord::Persistence#save <0.010964>

앱이 실행 중인 스레드를 확인하시겠습니까?

~/Source/testapps/rbtrace jweiss$ rbtrace -p $RAILS_PID -e "Thread.list"
*** attached to process 8154
>> Thread.list
=> [#<Thread:0x007ff4fcc9a8a8@/usr/local/lib/ruby/gems/2.2.0/gems/puma-2.6.0/lib/puma/server.rb:269 sleep>, #<Thread:0x007ff4fcc9aa10@/usr/local/lib/ruby/gems/2.2.0/gems/puma-2.6.0/lib/puma/thread_pool.rb:148 sleep>, #<Thread:0x007ff4fcc9ab50@/usr/local/lib/ruby/gems/2.2.0/gems/puma-2.6.0/lib/puma/reactor.rb:104 sleep>, #<Thread:0x007ff4f98c0410 sleep>]

예, -e로 서버 내에서 Ruby 코드를 실행할 수 있습니다.

~/Source/testapps/rbtrace jweiss$ rbtrace -p $RAILS_PID -e "ActiveRecord::Base.connection_config"
*** attached to process 8154
>> ActiveRecord::Base.connection_config
=> {:adapter=>"postgresql", :pool=>5, :timeout=>5000, :database=>"rbtrace_test"}

그래, 알았어, 지금은 조금 무서워. 하지만 여전히 매우 시원한. (그리고 프로세스를 망칠 권한이 있는 사용자만이 rbtrace를 할 수 있으므로 괜찮을 것입니다.)

rbtrace는 스테이징 및 프로덕션에서 Ruby 프로세스를 검사할 수 있는 수많은 도구를 제공합니다. 프로세스가 메모리를 어떻게 사용(또는 남용)하는지 확인하고, 느린 함수 호출을 추적하고, Ruby 코드를 실행할 수도 있습니다.

문제를 해결하기 위해 수많은 테스트 커밋과 로그 메시지를 만들 필요가 없습니다. 서버에 접속하여 데이터를 가져온 다음 다시 나갈 수 있습니다. 내가 완전히 아니더라도 아직 프로덕션 환경에서 편안하게 사용할 수 있지만 테스트 환경에서도 도움이 될 것이라고 확신합니다.

당신은 어떤가요? rbtrace를 무엇에 사용할 수 있습니까?