Saya tidak dapat menemukan kutipan dalam dokumentasi, tetapi pengalaman saya menunjukkan bahwa infrastruktur jaringan EC2 secara umum (yang akan mencakup RDS dan kemungkinan layanan AWS lainnya yang berjalan pada mesin virtual yang disediakan per pelanggan, jika tidak semua AWS, dan tentu saja tampaknya tidak terbatas hanya pada "instans EC2") mengimplementasikan inspeksi paket stateful, dan akan "melupakan" bahwa koneksi TCP valid setelah beberapa menit benar-benar menganggur... menyebabkan perilaku yang Anda gambarkan.
Mesin di kedua ujung koneksi mungkin yakin bahwa koneksi masih ada, tetapi jaringan tidak akan mengizinkan lalu lintas lewat di antara mereka, karena sesi TCP di lingkungan SPI tidak ditemukan, mereka dibuat, dan hanya dapat dibuat ketika jaringan melihat koneksi di awal (SYN, SYN/ACK, ACK ). Saya awalnya mengalami masalah ini dengan server MySQL di EC2 (bukan RDS) tetapi akan sangat terkejut jika penyebab dasarnya tidak sama.
Ada dua pendekatan yang mungkin untuk mengatasi hal ini.
Jika mesin PHP Anda adalah Linux, konfigurasikan kernel untuk menjaga koneksi tetap hidup di lapisan 4. Perubahan ini tidak akan terlihat oleh Anda dalam arti bahwa keepalives ini tidak akan mengubah nilai dalam Time
kolom di SHOW PROCESSLIST
untuk koneksi di Sleep
karena itu tidak akan mengatur ulang jumlah waktu koneksi menganggur di lapisan 7 ... tetapi itu harus menghindari batas waktu dari infrastruktur AWS jika perpustakaan yang mengelola koneksi MySQL mengatur opsi soket dengan benar untuk memanfaatkannya.
http://tldp.org/HOWTO/TCP-Keepalive-HOWTO/usingkeepalive .html menjelaskan cara menyiapkannya secara langsung, dan cara membuatnya tetap ada di seluruh reboot.
Jika gagal, opsi lainnya adalah memaksa MySQL untuk menutup koneksi lebih cepat dari batas waktu jaringan sehingga mesin PHP akan segera mengenali bahwa ia mencoba berbicara pada soket tertutup. Mungkin terdengar kontra-intuitif untuk mempersingkat batas waktu daripada memperpanjangnya, tetapi memperpendek batas waktu akan menyebabkan tes ping Anda gagal dengan sangat cepat jika suatu sesi terlalu lama menganggur, yang juga (pada dasarnya) "memecahkan" masalah, dengan asumsi kewarasan di perpustakaan klien PHP. Setelah aplikasi Anda lebih sibuk, koneksi mungkin jarang menganggur cukup lama untuk mencapai batas waktu.
Server MySQL memiliki dua pengaturan waktu tunggu idle yang berbeda: wait_timeout
(untuk sesi non-interaktif, yaitu, koneksi dari kode, seperti PHP) dan interactive_timeout
(dari browser kueri dan klien baris perintah) tetapi server hanya mengetahui perbedaannya karena pustaka klien harus memberi tahu server jenis koneksi apa yang dibuatnya. Dengan asumsi pustaka klien Anda menggunakan penyiapan yang benar, lalu wait_timeout
dia yang kamu cari. Menyetel ini ke nilai di bawah 900 akan menyelesaikan masalah jika mengubah pengaturan TCP keepalive di kernel Linux tidak. Namun, perhatikan bahwa setelah melakukan perubahan, hanya koneksi di masa mendatang yang akan terpengaruh -- koneksi yang sudah dibuat saat perubahan dibuat akan tetap berjalan dengan nilai saat ini, yang defaultnya adalah 8 jam (28800 detik). Ini dapat dikonfigurasi di Grup Parameter RDS untuk instans Anda.
Ada petunjuk perilaku serupa di dokumen AWS di sini , bersama dengan pengaturan registri Windows yang perlu disesuaikan untuk mengubah TCP keepalives jika Anda menjalankan server PHP di Windows, bukan Linux, seperti yang saya asumsikan di atas ... meskipun artikel ini secara khusus tentang Redshift dan koneksi eksternal ke EC2 tampaknya masih memvalidasi masalah mendasar seperti yang dibahas di atas.