Computer >> Máy Tính >  >> Lập trình >> Ruby

Cách gỡ lỗi các vấn đề về hiệu suất của Ruby trong sản xuất

Bạn biết rằng hiệu suất là một tính năng. Và rất nhiều vấn đề về hiệu suất có thể được tìm thấy và khắc phục trong quá trình phát triển.

Nhưng còn những lỗi chậm chỉ hiển thị trong quá trình sản xuất thì sao? Bạn có phải thêm thông báo nhật ký vào mỗi dòng mã không? Điều đó sẽ chỉ làm mọi thứ chậm lại hơn nữa! Hay bạn gửi hàng tấn nhỏ "có thể cái này sửa được nó" cam kết xem có gì dính không?

Bạn không cần phải hủy mã của mình để phân tích nó. Thay vào đó, hãy thử rbtrace -ing nó.

Theo dõi ứng dụng Ruby đang chạy của bạn

Với rbtrace, bạn có thể phát hiện các vấn đề về hiệu suất, chạy mã bên trong một quy trình Ruby khác và ghi nhật ký các cuộc gọi phương thức mà không cần phải thêm bất kỳ mã nào. Chỉ cần thêm gem "rbtrace" vào Gemfile của bạn .

Tôi đã biết về rbtrace từ bài đăng tuyệt vời của Sam Saffron về cách gỡ lỗi rò rỉ bộ nhớ trong Ruby (bạn thực sự nên kiểm tra nếu chưa làm như vậy).

Trong bài đăng đó, Sam đã sử dụng rbtrace để xem tất cả các đối tượng mà một quy trình đã sử dụng:

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}'

Điều này thật tuyệt. Nhưng còn rất nhiều điều bạn có thể làm.

Bạn có thể làm gì với rbtrace?

Bạn đã bao giờ muốn xem các câu lệnh SQL mà bạn đang chạy trong phiên bản sản xuất (và chúng mất bao lâu)?

~/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>

Tất cả các lệnh gọi phương thức kéo dài hơn 2 giây?

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

Bạn có muốn biết mỗi khi một phương thức nhất định được gọi không?

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

Xem chuỗi ứng dụng của bạn đang chạy?

~/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>]

Đúng, với -e bạn có thể chạy mã Ruby bên trong máy chủ của mình:

~/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"}

Ừ, được rồi, giờ tôi hơi sợ. Nhưng điều đó vẫn rất mát mẻ. (Và chỉ những người dùng có quyền gây rối với quy trình mới có thể truy xuất nó, vì vậy có thể ổn).

rbtrace cung cấp cho bạn rất nhiều công cụ để kiểm tra các quy trình Ruby của bạn trong quá trình dàn dựng và sản xuất. Bạn có thể xem cách các quy trình của mình đang sử dụng (hoặc lạm dụng) bộ nhớ, theo dõi các lệnh gọi hàm chậm và thậm chí thực thi mã Ruby.

Bạn không phải tạo hàng tấn cam kết kiểm tra và thông báo nhật ký để khắc phục sự cố. Bạn chỉ có thể truy cập vào máy chủ, lấy một số dữ liệu và quay lại. Và ngay cả khi tôi không hoàn toàn cảm thấy thoải mái khi sử dụng nó trong sản xuất, tôi chắc chắn rằng nó thậm chí sẽ giúp ích trong môi trường thử nghiệm của chúng tôi.

Còn bạn thì sao? Bạn có thể sử dụng rbtrace để làm gì?