2016-04-11 12 views
5

Tôi đang gặp sự cố với nhân viên Sidekiq.Làm cách nào để gỡ lỗi việc sử dụng hồ bơi kết nối Rails?

ActiveRecord::ConnectionTimeoutError: could not obtain a database connection within 5.000 seconds (waited 5.000 seconds) 

Tôi đang làm theo các đề xuất về việc sử dụng ActiveRecord::ConnectionTimeoutError và hồ bơi kết nối phù hợp lớn.

Tôi muốn tìm hiểu xem tôi có đang cạn kiệt hồ bơi kết nối hay không. Tôi đang đăng nhập sizeconnections.length từ ActiveRecord::Base.connection_pool, nhưng chúng giữ nguyên kích thước = 100 kết nối.length = 5. Điều này cho thấy đây không phải là vấn đề về rò rỉ tài nguyên.

Máy chủ MySQL của tôi được định cấu hình để cho phép tối đa 400 kết nối đồng thời.

việc của tôi đã kết thúc như thế này:

class MyJob < ActiveJob::Base 
    queue_as :default  
    rescue_from StandardError do |exception| 
    # clear connections on exception. Not sure if this is a good idea or not. 
    ActiveRecord::Base.clear_active_connections!  
    end 

    def perform() 
    logger.info "size" 
    logger.info ActiveRecord::Base.connection_pool.instance_eval { @size } 
    logger.info "connections" 
    logger.info ActiveRecord::Base.connection_pool.instance_eval { @connections }.length 

    # Ensure connections come from connection pool. 
    ActiveRecord::Base.connection_pool.with_connection do |conn| 
     # do stuff 
    end 
    end 
end 

Đây có phải là cách đúng đắn để chẩn đoán những gì đang gây ra điều này, cho dù đó là nạn đói tài nguyên hoặc rò rỉ? Có những kỹ thuật nào khác mà tôi có thể sử dụng để giải thích tại sao điều này xảy ra không?

+0

Kích thước của nhóm kết nối được xác định trong 'database.yml' của bạn là gì? Bạn sử dụng bao nhiêu chủ đề công nhân sidekiq? – BoraMa

+0

Bể bơi được định nghĩa là 100, như được hiển thị trong connection_pool.size, 25 công nhân. – Joe

Trả lời

2

ActiveRecord::ConnectionTimeoutError này có thể theo ý kiến ​​của tôi xảy ra chỉ trong một kịch bản - khi có rất nhiều chủ đề muốn sử dụng các kết nối DB rằng hồ bơi là kiệt sức và thậm chí chờ đợi một kết nối miễn phí không giúp (như học từ source code).

Trong trường hợp của bạn, nó thật kỳ lạ. Bạn chỉ sử dụng 25 luồng công nhân nhưng hồ bơi được đặt thành 100 kết nối, do đó, có rất nhiều khoản dự trữ. Tôi vẫn nghi ngờ rằng bạn phải có chủ đề sinh sản ở đâu đó. Có lẽ bạn làm một số luồng trong công việc của bạn? Có lẽ bạn sử dụng một viên đá quý tạo ra các chủ đề trong công việc của bạn?

Dù sao, nếu bạn có khả năng tái tạo các ngoại lệ, tôi sẽ đề nghị để bắt nó và có được danh sách của tất cả các chủ đề tại thời điểm nó xảy ra, một cái gì đó như thế này:

begin 
    # job stuff...  
rescue ActiveRecord::ConnectionTimeoutError 
    puts "listing #{Thread.list.count} threads:" 
    Thread.list.each_with_index do |t,i| 
    puts "---- thread #{i}: #{t.inspect}" 
    puts t.backtrace.take(5) 
    end 
end 

Tôi hy vọng sẽ có 100 hoặc nhiều chủ đề và bạn sẽ thấy chính xác nơi họ đang mắc kẹt từ backtrace.

+0

Cảm ơn rực rỡ. Tôi sẽ thử xem. Tôi không tự xoay xở bất kỳ chủ đề nào nhưng lại biết những thư viện khác đang làm gì! – Joe

+0

Bạn đã tìm thấy gì chưa? – BoraMa

+1

No. Tôi đã giảm số lượng nhân viên phụ và không có lỗi. Điều này sẽ nằm trong danh sách điều tra dài hạn. Cảm ơn vì đã kiểm tra. – Joe

Các vấn đề liên quan