Gewusst wie: Debuggen von Schienen-Verbindungs-pool-Nutzung?

Bin ich in Probleme laufen mit Sidekiq Arbeitnehmer.

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

Ich bin nach Empfehlungen über die Verwendung von ActiveRecord::ConnectionTimeoutError und einen ausreichend großen Verbindungs-pool.

Möchte ich herausfinden, ob ich bin anstrengend connection pool. Ich bin Protokollierung size und connections.length aus ActiveRecord::Base.connection_pool, aber Sie bleiben auf einem Konstanten Größe = 100 verbindungen.Länge = 5. Das deutet darauf hin, dass dies nicht ein Ressource-Leck-Problem.

Mein MySQL-server ist so konfiguriert, dass bis zu 400 gleichzeitige verbindungen.

Mein Job endete so Aussehen:

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

Ist das der richtige Weg, um zu diagnostizieren, was die Ursache HIERFÜR, ob es Ressourcen-Hunger oder Leckage? Gibt es andere Techniken, die ich verwenden können, um herauszufinden, warum dies passiert ist?

  • Was ist die Größe des verbindungspools der Definition in Ihrer database.yml? Wie viele sidekiq worker-threads, die Sie benutzen?
  • Pool ist definiert als 100, wie gezeigt, in connection_pool.Größe, 25 beschäftigte.
InformationsquelleAutor Joe | 2016-04-11



2 Replies
  1. 2

    Diese ActiveRecord::ConnectionTimeoutError kann meiner Meinung nach vorkommen in nur ein Szenario – wenn es so viele threads nutzen wollen, die DB-verbindungen, dass der pool erschöpft ist und auch warten auf eine freie Verbindung nicht hilft (wie gelernt aus der source code).

    In Ihrem Fall ist es seltsam. Verwenden Sie nur 25 worker-threads, aber der pool ist zu 100 verbindungen, es gibt also genügend reserve. Ich habe immer noch den Verdacht, dass Sie müssen threads Laich irgendwo. Vielleicht tun Sie etwas threading in Ihren jobs? Vielleicht haben Sie ein Schmuckstück, welches threads erstellt, die in Ihren jobs?

    Sowieso, wenn Sie sind in der Lage zu reproduzieren die Ausnahme, würde ich vorschlagen, es zu fangen und erhalten die Auflistung aller threads in dem moment geschieht es, so etwas wie dieses:

    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

    Erwarte ich 100 oder mehr threads, und Sie sollten sehen, wo genau Sie stecken geblieben sind, aus dem backtrace.

    • Brillante Dank. Ich werde versuchen, dass. Ich bin nicht drehen bis alle threads selbst, aber wer weiß, was andere Bibliotheken tun!
    • Haben Sie noch nichts?
    • Nein. Ich reduzierte die Anzahl der sidekiq Arbeitnehmer und haben keine Fehler. Das wird in der langfristigen Untersuchung-Liste. Vielen Dank für die überprüfung.
  2. 1

    Versuchen ActiveRecord::ConnectionAdapters::ConnectionPool#stat

    ActiveRecord::Base.connection_pool.stat 
    # => { size: 15, connections: 1, busy: 1, dead: 0, idle: 0, waiting: 0, checkout_timeout: 5 }

    Vom connection_adapters/abstract/connection_pool.rb in activerecord 5.2.2.1.

    • Vielen Dank für Ihre Antwort. Leider bin ich nicht mehr in der Lage, dieses zu versuchen.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.