a) Heb ik de before_fork / after_fork-configuratie nodig zoals inUnicorn, aangezien de Cluster-werknemers gevorkt zijn?
Normaal gesproken niet, maar aangezien je preload_app
. gebruikt , ja. Door de app vooraf te laden, wordt een instantie in gebruik genomen en wordt vervolgens de geheugenruimte voor de werkers gevorkt; het resultaat is dat uw initializers maar één keer worden uitgevoerd (mogelijk door db-verbindingen en dergelijke toe te wijzen). In dit geval is uw on_worker_boot
code geschikt is. Als u preload_app
niet gebruikt , dan start elke worker zichzelf op, in welk geval het gebruik van een initializer ideaal zou zijn voor het opzetten van de aangepaste verbinding zoals u doet. Sterker nog, zonder preload_app
, je on_worker_boot
blok zou een foutmelding geven omdat ActiveRecord en vrienden op dat moment niet eens worden geladen.
b) Hoe pas ik mijn aantal threads aan, afhankelijk van mijn toepassing - wat zou de reden zijn om het te laten vallen? / In welke gevallen zou het verschil maken? Is 0:16 niet al geoptimaliseerd?
Op Heroku (en mijn testen) kom je het beste overeen met je min
/max
threads, met max
<=DB_POOL
instelling. De min
threads stelt uw toepassing in staat om bronnen te laten draaien wanneer deze niet worden belast, wat normaal gesproken geweldig is om bronnen op de server vrij te maken, maar waarschijnlijk minder nodig op Heroku; dat dyno al is toegewijd aan het bedienen van webverzoeken, kan ze net zo goed klaar hebben staan. Tijdens het instellen van uw max
threads <=uw DB_POOL
omgevingsvariabele is niet vereist, u loopt het risico al uw databaseverbindingen in de pool te verbruiken, dan heeft u een thread die een verbinding wil maar deze niet kan krijgen, en u kunt de oude "ActiveRecord::ConnectionTimeoutError - kon niet verkrijg binnen 5 seconden een databaseverbinding." fout. Dit hangt echter af van uw toepassing, u zou heel goed max
. kunnen hebben> DB_POOL
en het komt goed. Ik zou zeggen uw DB_POOL
moet minimaal gelijk zijn aan uw min
threads-waarde, ook al worden uw verbindingen niet gretig geladen (5:5-threads openen geen 5 verbindingen als uw app nooit de database bereikt).
c) De Heroku-database staat 500 verbindingen toe. Wat zou een goede waarde zijn voor DB_POOL, afhankelijk van het aantal threads, worker en dyno's? - Heeft elke thread per worker per dyno een enkele DB-verbinding nodig bij parallel werken?
De productielaag staat 500 toe, om duidelijk te zijn :)
Elke thread per worker per dyno kon een verbinding verbruiken, afhankelijk van of ze allemaal tegelijkertijd toegang proberen te krijgen tot de database. Meestal worden de verbindingen opnieuw gebruikt zodra ze klaar zijn, maar zoals ik al zei in b)
, als je threads groter zijn dan je pool kun je een slechte tijd hebben. De verbindingen worden hergebruikt, dit wordt allemaal afgehandeld door ActiveRecord, maar soms niet ideaal. Soms worden verbindingen inactief of vallen ze weg, en daarom wordt aangeraden de Reaper in te schakelen om dode verbindingen te detecteren en terug te winnen.