OpenVPN lewat TCP macet: rto_min tidak memperbaiki blokir di kepala antrean
Aliran bita luar mengirimkan secara berurutan, jadi satu segmen yang hilang dapat menghentikan setiap aliran dalam. Timer dalam yang lebih panjang mengubah jam, bukan batasan itu.
Shell interaktif di atas terowongan membeku beberapa detik saat penyalinan berkas berjalan, lalu pulih seolah tidak terjadi apa-apa. Hanya unduhan yang bermasalah, tetapi shell juga menunggu, dan keduanya pulih pada saat yang sama. Pola itu adalah tanda satu aliran andal yang membawa banyak percakapan, dan pola itu bertahan pada hampir semua perubahan penyetelan yang orang coba lebih dulu.
Gejala ini layak dibaca dengan cermat karena menunjuk pada mekanisme, bukan pada pengaturan: jeda itu dibagi, jadi penyebabnya dibagi, dan objek yang dibagi adalah koneksi luar. Semua hal lain di log tampak normal saat itu terjadi.
Gejala: semuanya berhenti sekaligus
Dua koneksi dalam yang macet bersamaan adalah petunjuknya. Unduhan lambat dan shell lambat adalah percakapan TCP terpisah dengan nomor urut dan status kemacetan terpisah, jadi gangguan pada salah satunya seharusnya tidak menyentuh yang lain. Ketika keduanya berhenti serempak, ada sesuatu di atasnya yang mengurutkan bita mereka.
Sesuatu itu adalah transport terowongan. Dalam mode TCP, OpenVPN menulis paket yang dienkapsulasi ke satu koneksi TCP ke peer, dan kontrak TCP adalah pengiriman berurutan dari satu aliran bita. Bita berikutnya tidak diserahkan ke aplikasi sebelum yang hilang, apa pun percakapan dalam yang menjadi asalnya.
Perhatikan apa yang tidak dikatakan gejala ini. Ini tidak mengatakan jalurnya rusak, servernya kelebihan beban, atau ciphernya lambat. Itu menghasilkan bentuk lain: throughput rendah merata, timeout, atau kegagalan yang memengaruhi satu arah. Jeda bersama yang berakhir ketika satu segmen hilang dikirim ulang secara khusus merupakan efek pengurutan.
Satu aliran bita luar, banyak percakapan dalam
Bayangkan terowongan membawa unduhan dan shell pada saat yang sama. Satu segmen koneksi luar hilang. Segmen berikutnya dapat tiba di host penerima, dan tumpukan TCP penerima akan mengakuinya, tetapi tidak dapat menyerahkannya ke atas sampai celah itu terisi. Karena itu OpenVPN tidak punya apa pun untuk dibaca bagi shell, meskipun bita shell itu sendiri sudah lama tiba.
Ini adalah blokir di kepala antrean di dalam satu koneksi, dan itu tidak menuntut kedua aplikasi berbagi koneksi dalam. Mereka berbagi yang luar, dan itu cukup.
Efek orde kedua membuatnya lebih buruk. Pengirim dalam yang tidak melihat pengakuan dapat mengirim ulang data yang sudah coba dikirimkan lapisan luar. Pengiriman ulang itu menjadi lalu lintas terowongan tambahan pada jalur yang baru saja membuktikan bahwa ia bisa kehilangan segmen, sehingga pekerjaan pemulihan bersaing dengan pemulihan yang penting.
Tidak satu pun dari ini menjamin keruntuhan. Pada jalur bersih dengan perjalanan pulang-pergi pendek dan antrean lapang, susunan ini bisa sangat terpakai selama bertahun-tahun. Kegagalan muncul ketika kehilangan, tunda, dan kedalaman antrean bertemu, itulah sebabnya laporan mengelompok di sekitar uplink yang padat dan tautan seluler, bukan di kantor yang berkecukupan.
Mengapa timer dalam yang lebih panjang tidak dapat membantu
Menaikkan timeout pengiriman ulang minimum pada suatu rute, dengan rto_min, menunda pengiriman ulang berbasis timer untuk lalu lintas TCP yang dibuat secara lokal yang memakai rute itu. Itu adalah tombol nyata dengan efek nyata, dan ia menangani masalah orde kedua, bukan yang pertama.
ip route show
ip route show cache 2>/dev/null | head
ss -tin dst 10.70.0.1
Yang tidak dapat dilakukannya adalah melepaskan bita luar tanpa urutan, memulihkan segmen yang hilang lebih cepat, atau membuat server aplikasi jauh memakai timer yang sama. Tumpukan penerima tetap mengirimkan berurutan, dan pengirim di ujung jauh tetap memakai pengukuran pulang-pergi miliknya sendiri.
Ia juga tidak mematikan setiap mekanisme pemulihan kehilangan lainnya. Ketika kehilangan nyata menuntut pemulihan berbasis timer, minimum yang lebih besar membuat aplikasi menunggu lebih lama sebelum bertindak, yang merupakan kebalikan dari yang dibutuhkan sesi peka latensi.
Batas bawah tetap dua belas detik muncul dalam saran tentang topik ini seolah keberadaan terowongan TCP menyiratkannya. Timer pengiriman ulang yang dijelaskan di RFC 6298 berasal dari waktu pulang-pergi terukur dengan backoff eksponensial, jadi batas bawah konstan adalah pilihan kebijakan untuk jalur tertentu, bukan persyaratan protokol. Diterapkan secara luas, ia menyembunyikan gejala sekaligus mengubah pemulihan bagi setiap aliran yang dicakup rute itu.
Apa yang dilakukan dan tidak dilakukan tcp-nodelay
Opsi terowongan yang mematikan penyangga gaya Nagle pada soket transport punya tujuan sempit: menghentikan tulisan kecil menunggu data lebih banyak sebelum dikirim. Itu membantu lalu lintas interaktif menghindari tunda tambahan pada jalur yang sebaliknya sehat.
Ia tidak mengubah transport menjadi tak berurutan, dan tidak mempersingkat pemulihan setelah segmen hilang. Shell yang berhenti karena timeout pengiriman ulang akan tetap berhenti dengan opsi itu aktif, karena opsi itu tidak pernah menyentuh aturan pengurutan.
Mudah mencampuradukkan keduanya karena keduanya dijelaskan sebagai perbaikan latensi. Yang satu menghapus tunggu buatan yang diperkenalkan penyangga, yang lain menuntut perubahan atas apa yang dijamin transport, dan tidak ada opsi soket yang melakukannya.
Cara membandingkan transport secara adil
Jika operator mengizinkan dan kedua layanan ada, bandingkan layanan UDP dan layanan TCP yang membawa beban kerja sama melalui jalur akses yang sama ke server yang sama. Mengganti negara, penyedia, atau generasi server antara dua uji memasukkan variabel yang akan mendominasi hasil.
Perhatikan jeda bersama, bukan angka throughput. Beberapa aplikasi dalam yang macet bersamaan selama kehilangan luar adalah pengamatan yang mengenali blokir di kepala antrean; satu angka uji kecepatan yang lebih rendah tidak.
Tangkapan resmi pada antarmuka terowongan dan pada antarmuka fisik memisahkan kedua lapisan dengan bersih, karena pengiriman ulang dalam dan luar termasuk koneksi berbeda dengan ruang nomor urut berbeda. Melihat pengiriman ulang dalam sementara aliran luar menunjukkan celah adalah bukti langsung.
Beralih ke UDP menghapus aliran andal tambahan dan membiarkan TCP dalam melakukan pemulihannya sendiri. Itu tidak menjanjikan kehilangan nol atau latensi rendah, dan uplink yang jenuh, antrean kebesaran, atau masalah MTU tetap perlu diperbaiki. Lalu lintas di luar terowongan tidak pernah tertahan di belakang celah nomor urut terowongan, meskipun dapat tetap menderita ketika kedua jalur berbagi satu tautan yang padat, penyempitan bersama itu pun layak diselidiki sendiri daripada dilipat ke dalam yang ini.