Non riesco a trovare una citazione nella documentazione, ma la mia esperienza suggerisce che l'infrastruttura di rete di EC2 in generale (che includerebbe RDS e probabilmente qualsiasi altro servizio AWS eseguito su macchine virtuali fornite per cliente, se non tutto AWS, e certamente non sembra essere limitato rigorosamente alle "istanze EC2") implementa l'ispezione dei pacchetti con stato e "dimenticherà" che una connessione TCP è valida dopo alcuni minuti di inattività assoluta... causando il comportamento che descrivi.
Le macchine su entrambe le estremità della connessione potrebbero essere convinte che la connessione sia ancora presente, ma la rete non consentirà il passaggio del traffico tra di loro, perché le sessioni TCP in un ambiente SPI non vengono rilevate, vengono create e possono solo essere creato quando la rete vede la connessione all'inizio (SYN, SYN/ACK, ACK ). Inizialmente ho riscontrato questo problema con i server MySQL in EC2 (non RDS), ma sarei molto sorpreso se la causa sottostante non fosse la stessa.
Esistono due possibili approcci per aggirare questo problema.
Se la tua macchina PHP è Linux, configura il kernel per mantenere attive le connessioni al livello 4. Questa modifica ti sarà invisibile nel senso che questi keepalive non cambieranno il valore nel Time
colonna in SHOW PROCESSLIST
per le connessioni in Sleep
perché non ripristinerà la quantità di tempo in cui la connessione è rimasta inattiva al livello 7 ... ma dovrebbe evitare i timeout dall'infrastruttura AWS se le librerie che gestiscono le connessioni MySQL stanno impostando correttamente le opzioni socket per trarne vantaggio.
http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive .html spiega come configurarlo in tempo reale e come renderlo persistente durante i riavvii.
In caso contrario, l'altra opzione è forzare MySQL a chiudere la connessione prima del timeout della rete in modo che la macchina PHP riconosca immediatamente che sta cercando di parlare su un socket chiuso. Può sembrare controintuitivo abbreviare un timeout piuttosto che allungarlo, ma accorciare il timeout dovrebbe far fallire il test ping molto rapidamente se una sessione è rimasta inattiva per troppo tempo, il che anche (essenzialmente) "risolve" il problema, presupponendo la sanità mentale nella libreria del client PHP. Una volta che l'applicazione è più occupata, è probabile che le connessioni rimarranno inattive abbastanza a lungo da raggiungere il timeout.
MySQL Server ha due diverse impostazioni di timeout di inattività: wait_timeout
(per sessioni non interattive, ovvero connessioni da codice, come PHP) e interactive_timeout
(dai browser di query e dal client della riga di comando) ma il server conosce solo la differenza perché la libreria client deve notificare al server quale tipo di connessione sta stabilendo. Supponendo che la tua libreria client utilizzi la configurazione corretta, allora wait_timeout
è quello che stai cercando. L'impostazione di un valore inferiore a 900 dovrebbe risolvere il problema se la modifica delle impostazioni keepalive TCP nel kernel Linux non lo fa. Si noti, tuttavia, che dopo aver apportato la modifica, verranno interessate solo le connessioni future:le connessioni già stabilite al momento della modifica saranno ancora in esecuzione con il valore corrente, che per impostazione predefinita è 8 ore (28800 secondi). Questi sono configurabili nel gruppo di parametri RDS per la tua istanza.
Ci sono spunti di comportamento simile nei documenti AWS qui , insieme alle impostazioni del registro di Windows che devono essere regolate per modificare i keep-alive TCP se stai eseguendo il server PHP su Windows, invece di Linux, come ho ipotizzato sopra... anche se l'articolo riguarda specificamente Redshift e le connessioni esterne a EC2 sembra ancora convalidare il problema di fondo come discusso sopra.