Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Làm chủ debug hiệu năng Ruby trong production: Kỹ thuật chứng minh

Bạn biết hiệu năng là một tính năng. Và nhiều vấn đề hiệu năng có thể tìm thấy và sửa trong development.

Nhưng những sự chậm chỉ xuất hiện trong production thì sao? Bạn có phải thêm log message vào mỗi dòng mã? Đó chỉ làm chậm mọi thứ hơn! Hay bạn ship hàng tá commit nhỏ "có lẽ cái này sửa nó" để xem cái gì dính?

Bạn không phải phá hoại mã để phân tích nó. Thay vào đó, hãy thử rbtrace-ing nó.

Trace ứng dụng Ruby đang chạy

Với rbtrace, bạn có thể phát hiện vấn đề hiệu năng, chạy mã bên trong process Ruby khác, và log lời gọi phương thức mà không phải thêm bất kỳ mã nào. Chỉ cần thêm gem "rbtrace" vào Gemfile.

Tôi biết rbtrace từ bài đăng tuyệt vời của Sam Saffron về debug rò rỉ bộ nhớ trong Ruby (bạn thực sự nên xem, nếu chưa).

Trong bài đó, Sam dùng rbtrace để thấy tất cả đối tượng process 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 tuyệt vời. Nhưng có nhiều hơn nữa bạn có thể làm.

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

Bao giờ muốn thấy câu lệnh SQL bạn đang chạy trong production (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ả lời gọi phương thức mất 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 cụ thể được gọi?

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

Xem thread nào ứ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>]

Ừ, với -e bạn có thể chạy mã Ruby bên trong server:

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

Ừ, ổn, bây giờ tôi hơi sợ. Nhưng đó vẫn rất cool. (Và chỉ user có quyền can thiệp process mới rbtrace được nó, nên nó có thể OK).

rbtrace cho bạn ton công cụ để kiểm tra process Ruby trong staging và production. Bạn có thể thấy process của bạn đang dùng (hoặc lạm dụng) bộ nhớ như thế nào, trace lời gọi hàm chậm, và thậm chí thực thi mã Ruby.

Bạn không phải tạo ton commit test và log message để sửa vấn đề. Bạn chỉ cần nhảy lên server, lấy dữ liệu, và nhảy ra. Và ngay cả khi tôi không hoàn toàn thoải mái dùng nó trong production, tôi chắc nó sẽ giúp trong môi trường test.

Còn bạn? Bạn có thể dùng rbtrace cho gì?