Mobil Proxy Üzerinden Uzun Bağlantılar Neden Kopar? (Çözüm Rehberi)
Makale içeriği
- Giriş: i̇ndirme yarıda kesiliyor, kısa istekler geçiyor
- Temeller: mobil proxy üzerinden bağlantı nasıl çalışır
- Derinlemesine inceleme: bağlantıyı kim koparabilir ve tam olarak kimin kopardığını nasıl anlarsınız?
- Keep-alive ve idle timeout: yolda üç zaman aşımı vardır, kazanan en kısa olanıdır
- Tcp keepalive vs http keep-alive: farklı mekanizmalar, ikisi de gerekli
- Mtu ve parçalanma: hücresel ağlarda paketler neden daha küçük?
- Baz istasyonu değişimi ve ağlar arası geçiş: tcp neden bunu kaldıramaz?
- Python pratiği: kaldığı yerden devam eden ve zaman aşımlı dayanıklı istemci
- Node.js pratiği: dayanıklı http ajanı ve akış (streaming)
- Yaygın hatalar: yapmamanız gerekenler
- Teşhis ve dayanıklılık oluşturma araçları ve kaynakları
- Vaka örnekleri ve sonuçlar: bu pratikte nasıl işliyor?
- Sss: mobil ağlarda bağlantı kopmaları hakkında sık sorulan sorular
- Sonuç: bağlantı geçicidir, ama veriler yerine ulaşmalı
Tanıdık bir tablo: kısa istekler kırlangıç gibi uçup gidiyor, ama mobil proxy üzerinden büyük bir yükleme başlattığınızda veya iri bir dosya indirmeye kalktığınızda bağlantı tam ortasında kopuyor. Dosya yüzde 40'ta, sonra sessizlik. İsteği tekrarlamak bazen işe yarıyor, bazen yaramıyor. En can sıkıcısı da şu: loglar sessiz, sunucu bir şekilde yaşıyor, ama veriler ulaşmıyor. Eğer bunları yaşadıysanız, doğru adrese geldiniz.
Bu makale yanıt kodlarıyla veya HTTP düzeyindeki tekrar mantığıyla ilgili değil (429 ve üstel geri çekilme hakkında ayrı bir yazı var, ona da değineceğiz). Burada taşıma katmanını inceliyoruz: TCP neden kopar, bağlantıyı tam olarak kim keser, paketin yolculuğundaki üç farklı zaman aşımı nasıl çalışır, MTU nedir ve hücresel ağlarda parçalanma nasıl olur, baz istasyonu değişimi neden uzun oturumları öldürür. En önemlisi de tüm bunlara dayanacak bir istemci inşa edeceğiz.
Giriş: İndirme yarıda kesiliyor, kısa istekler geçiyor
Peki bu konu neden 2026 yılında bu kadar güncel? Çünkü mobil proxy'ler, veri kazıma (scraping), otomasyon, test süreçleri ve pazar yeri çalışmaları için standart bir araç haline geldi. Hücresel ağ, yapısı gereği kablolu ağlardan daha istikrarsızdır. Bu ağlar; sayfayı açan, okuyan ve kapatan bir insan için tasarlandı. Tek bir TCP bağlantısını on dakika açık tutup üzerinden gigabaytlarca veri indiren bir makine için tasarlanmadı.
Bölüm başlığındaki paradoks da buradan geliyor. Kısa istekler geçer, çünkü herhangi bir zaman aşımı devreye girmeden veya bir handover (baz istasyonları arası geçiş) gerçekleşmeden önce tamamlanmayı başarırlar. Uzun işlemler daha uzun yaşar; dolayısıyla zaman aşımı, hücre değişimi sırasında kopma veya yanlış MTU nedeniyle büyük paket kaybı gibi sorunlarla karşılaşma olasılığını artırır.
- Bağlantıyı tam olarak kimin kopardığını beş dakikada nasıl anlarsınız: istemciniz mi, proxy mi, operatör mü, yoksa hedef sunucu mu?
- TCP keepalive ile HTTP keep-alive arasındaki temel fark nedir ve neden her iki ayara da ihtiyaç var?
- Yol üzerindeki üç zaman aşımını nasıl ölçersiniz ve bağlantının kaderini belirleyen en kısa olanı nasıl bulursunuz?
- Hücresel ağlarda MTU neden standart 1500 baytın altındadır ve PMTUD arızası nasıl görünür (belirti: büyük yanıtlarda takılma).
- Python ve Node'da Range ile indirmeye devam eden, yüklemeyi bölen ve doğru zaman aşımlarını kullanan hazır istemci kodu.
Teknik bir dille konuşacağız ama her terimi insan diliyle anlatacağız. Başlayalım.
Temeller: Mobil proxy üzerinden bağlantı nasıl çalışır
Arızalara geçmeden önce dünya görüşümüzü netleştirelim. Mobil proxy üzerinden bir istek yaptığınızda paket uzun bir zincirden geçer. Bu zinciri anlamak, teşhiste başarının yarısıdır.
Paketin istemciden sunucuya yolculuğu
Bir kargonun rotasını düşünün. Aşama aşama ilerler ve her aşamada geciktirilebilir veya kaybolabilir:
- İstemciniz - isteği yapan program. Kendi zaman aşımları ve soket ayarları vardır.
- Proxy sunucusu - sizin bağlantınızı alır ve hedefe kendi bağlantısını açar. Genellikle bunlar birbirine yapıştırılmış iki ayrı TCP bağlantısıdır.
- Mobil modem ve radyo arayüzü - işte o dar ve huysuz bölüm. Paket burada radyo dalgasıyla baz istasyonuna uçar.
- Operatör çekirdek ağı - NAT, ağ geçitleri, trafik önceliklendirme sistemleri.
- Genel internet - hedef veri merkezine giden omurga kanalları.
- Hedef sunucu - bağlantı süresi konusunda kendi limitleri olan uç nokta.
Kritik içgörü şu: proxy üzerinden bağlantı tek bir boru değil, en az iki borudur. İstemci proxy'ye kadar olan bağlantıyı, proxy de hedefe kadar olan bağlantıyı tutar. Kopma bu bölümlerin herhangi birinde olabilir ve belirtiler farklı olur.
Oturum nedir ve neden kırılgandır
TCP bağlantısı sanal bir kanaldır. Sizinle sunucu arasında fiziksel bir kablo yoktur; iki tarafın numaralandırılmış baytlar alışverişi yapma anlaşması vardır. İki taraf da numaraları ve durumu hatırladığı sürece bağlantı yaşar. Taraflardan biri durumu unuttuğu anda (NAT yeniden başladı, zaman aşımı doldu, hücre değişti) bağlantı fiilen ölür, ancak diğer taraf bunu uzun süre fark etmeyebilir.
İşte tam da bu, sinsi yarı açık bağlantıları (half-open) yaratır: bir taraf kanalı canlı sanıp veri beklerken, diğer taraf çoktan her şeyi unutmuştur. İstemci takılı kalır, hiçbir hata gelmez, zaman akar. Tanıdık geldi mi?
Sorunların yaşandığı üç katman
- Radyo katmanı - paket kayıpları, gecikmeler, hücre değişimi. Hücresel iletişimin doğası.
- Ağ katmanı - operatörün NAT zaman aşımları, MTU, parçalanma.
- Uygulama katmanı - proxy ve hedef HTTP sunucusunun zaman aşımları, yanıt gövdesi boyut limitleri.
Şimdi her birini tek tek ele alıp birbirinden nasıl ayırt edileceğini öğreneceğiz.
Derinlemesine inceleme: Bağlantıyı kim koparabilir ve tam olarak kimin kopardığını nasıl anlarsınız?
Bu, teşhis açısından en önemli bölüm. Faili bulamazsanız körlemesine ateş edersiniz. İyi haber: her failin kendine özgü bir imzası vardır.
Dört şüpheli
1. İstemciniz. En sık görülen ve en çok hafife alınan fail. HTTP kütüphaneleri, fark etmemiş olabileceğiniz varsayılan zaman aşımlarına sahiptir. Örneğin, isteğin toplam süresi için zaman aşımı, soket okuma zaman aşımı, hareketsizlik zaman aşımı. Eğer bağlantıyı istemciniz kopardıysa loglarda read timeout veya socket timeout şeklinde, çağrı yığınında kodunuzu gösteren bir hata görürsünüz.
2. Proxy sunucusu. Proxy'nin de kendi limitleri vardır: maksimum bağlantı ömrü, idle timeout, maksimum yanıt boyutu. Proxy bağlantıyı kopardığında, gövde aktarımı sırasında genellikle ani bir connection reset veya yanıtsız kapanma alırsınız. Üstelik proxy'ye ping atıldığında cevap alınır, kısa istekler çalışır.
3. İletişim operatörü. En görünmez olanı. Operatörlerin NAT tablolarında kayıtların bir ömrü vardır. Bağlantı üzerinden uzun süre trafik geçmezse, operatör kaydı NAT'tan siler ve sonraki paketlerin gideceği yer kalmaz. Belirti: bağlantı aktif aktarım sırasında değil, tam olarak duraklamalar sırasında takılır. Ayrıca baz istasyonu değişiminde de suçlu operatördür.
4. Hedef sunucu. Kendi keep-alive ayarları ve limitleri vardır. Birçok sunucu, N istekten veya T saniye sonra bağlantıyı kapatır. Belirti: sunucu Connection: close başlığını gönderir veya bağlantıyı (FIN ile) düzgün bir şekilde kapatır, (RST ile) koparmaz.
Belirtilere göre teşhis: imza tablosu
Faili dakikalar içinde belirlemeniz için karakteristik işaretleri inceleyelim.
- Kopmalar tam olarak duraklamalarda oluyor, aktif aktarım sırasında her şey yolunda - neredeyse kesinlikle operatörün NAT zaman aşımı veya proxy'nin idle timeout'u. Keepalive trafiğiyle çözülür.
- Kopma her zaman yaklaşık aynı veri miktarında oluyor (örneğin 8 veya 10 megabayt civarı) - proxy veya sunucudaki yanıt boyutu limiti. Range ile bölerek çözülür.
- Kopma her zaman yaklaşık aynı sürede oluyor (örneğin tam 60 veya 300 saniye) - bağlantı süresiyle ilgili sert bir limit vardır. En kısa zaman aşımını arayın.
- Takılma sadece büyük yanıtlarda oluyor, küçükler geçiyor - klasik PMTUD arızası ve MTU sorunu. Bununla ilgili aşağıda koca bir bölüm var.
- Miktara ve zamana bağlı olmayan, daha çok hareket halindeyken görülen rastgele kopmalar - baz istasyonu değişimi, handover, radyo sinyalinin zayıflaması.
- Veri göndermeye çalışırken anında RST - bağlantı bir tarafta zaten ölüdür (yarı açık) ya da proxy aktif olarak sıfırlıyordur.
Ön teşhis araçları
FIN'ı (kibarca kapatma) RST'den (kaba sıfırlama) ayırt etmek ve kopmanın hangi bölümde olduğunu anlamak için şunları kullanın:
- Soket düzeyinde loglama - kopmanın tam zamanını, aktarılan bayt sayısını, istisna türünü kaydedin.
- Trafik analizi - paket yakalama aracı, RST veya FIN'i kimin gönderdiğini gösterir. RST proxy adresinden geliyorsa suçlu proxydir. Bağlantı paket olmadan sessizce donuyorsa suçlu aradaki düğümdür (operatör).
- Kontrol ölçümleri - aynı işlemi doğrudan kablolu bağlantı üzerinden tekrarlayın. Kabloda her şey stabilken mobil proxy'de kopuyorsa sorun mobil bölümdendir.
Yazarın gözlemi: İncelediğimiz vakaların yaklaşık yüzde 70'inde suçlu, operatörün NAT zaman aşımı veya varsayılan idle timeout'du, proxy ya da sunucu değil. İnsanlar proxy'yi suçluyor; oysa çözüm, birkaç satırlık soket ayarında.
Keep-alive ve idle timeout: Yolda üç zaman aşımı vardır, kazanan en kısa olanıdır
İşte bilinçaltınıza kazınması gereken temel ilke: paketin yolunda birbirinden bağımsız birkaç hareketsizlik zaman aşımı vardır ve bağlantının kaderini en kısa olanı belirler. Tıpkı bir zincir gibi: en zayıf halkadan kopar.
Zaman aşımları nerede yaşar
- İstemcinizin idle timeout'u. Programınız hiçbir şey almadan ne kadar süre veri beklemeye hazırdır. Varsayılan olarak farklı kütüphanelerde 30 saniyeden sonsuza kadar değişir.
- Proxy'nin idle timeout'u. Proxy, boştaki bağlantıyı ne kadar süre açık tutar. Tipik değerler 60 ila 300 saniye arasındadır.
- Operatörün NAT zaman aşımı. Ağ çekirdeği, trafik olmadan adres çevrimi kaydını ne kadar süre saklar. TCP için bu genellikle 300-600 saniyedir, ancak UDP'de ve yoğun saatlerde 30-60 saniyeye kadar düşebilir.
- Hedef sunucunun keep-alive zaman aşımı. Sunucu, istekler arasında bağlantıyı ne kadar süre tutar. Genellikle 5-75 saniye.
Düşünün: istemci 120 saniye beklemeye hazır, proxy 90 saniyede koparıyor, operatör ise NAT'ı 60 saniyede temizliyor. Kim kazanır? Operatör. Bağlantı, boşluğun 60. saniyesinde ölür ve ne istemci ne de proxy bunu hemen fark eder.
En kısa zaman aşımı nasıl ölçülür
Yöntem basit ve güvenilir. Bağlantı kurarız, bir istek yaparız, sonra susar ve kopmaya kadar geçen süreyi ölçeriz. Rastlantısallığı ortadan kaldırmak için birkaç kez tekrarlarız.
- Keep-alive destekleyen bir test sunucusuna proxy üzerinden bağlantı açın.
- Kısa bir istek yapın ve yanıtı alın.
- Bağlantıyı kapatmayın. Zamanlayıcıyı başlatın.
- Periyodik olarak (saniyede bir) soketten bloke etmeyen modda okumayı deneyerek bağlantının canlı olup olmadığını kontrol edin.
- RST, FIN geldiği veya soketin okunamaz hale geldiği anı not edin.
Ölçümü üç kez yapın. Kopma her seferinde 60 saniye civarında gerçekleşiyorsa, bu sizin hareketsizlik tavanınızdır. Yani keepalive trafiğini 60 saniyeden daha sık, iyi bir pay bırakarak - örneğin her 20-25 saniyede bir - göndermeniz gerekir.
Idle timeout'a karşı kazanma stratejisi
En kısa zaman aşımı her şeyi belirlediğine göre, görevimiz bağlantının bu limitten daha uzun süre boşta kalmasını önlemek. İki yaklaşım var:
- Bağlantıyı yararlı trafikle doldurmak - aktif veri aktarımı sırasında idle zaman aşımları devreye girmez, çünkü hareketsizlik yoktur. Bu nedenle kesintisiz indirme işlemi nadiren idle timeout'tan etkilenir; asıl sorun boyut ve ömür limitlerinden kaynaklanır.
- Duraklamalarda keepalive denemeleri göndermek - yararlı veri olmadığında (örneğin sunucuda bir raporun oluşturulmasını beklerken), bağlantıyı yapay trafikle canlı tutmak gerekir. İşte burada ayrıntılı olarak ele alacağımız iki keep-alive mekanizması devreye girer.
TCP keepalive vs HTTP keep-alive: Farklı mekanizmalar, ikisi de gerekli
Sektördeki büyük kafa karışıklığı, birbirine benzeyen isimlerden kaynaklanıyor. TCP keepalive ve HTTP keep-alive, farklı katmanlarda çalışan tamamen farklı şeylerdir. Dayanıklı bir mobil istemci için ikisine de ihtiyaç vardır.
HTTP keep-alive: Bağlantının yeniden kullanılması
HTTP keep-alive (diğer adıyla kalıcı bağlantı), her istek için yeni bir TCP bağlantısı açmamakla ilgilidir. Bunun yerine tek bir bağlantı art arda birden fazla isteğe hizmet eder. Bu, uygulama katmanıdır.
Bu neden mobil ağlar için önemli? Hücresel ağ üzerinden yeni bir TCP bağlantısı kurmak maliyetlidir. Üçlü el sıkışma ve eğer şifreleme kullanılıyorsa TLS handshake de eklenir. Yüksek gecikmeli radyo kanalında bu yüzlerce milisaniye sürebilir. Bağlantıyı yeniden kullanarak bu süreyi sonraki her istekte kurtarırsınız.
Ama! HTTP keep-alive, duraklamalarda operatörün NAT zaman aşımına karşı hiçbir şekilde yardımcı olmaz. Sadece bağlantıyı bir sonraki istek için açık tutmanızı sağlar; ancak kendi başına aradaki boşluklarda trafik üretmez.
TCP keepalive: Taşıma katmanındaki nabız
TCP keepalive, TCP protokolünün kendi mekanizmasıdır. İşletim sistemi, diğer tarafın canlı olup olmadığını kontrol etmek ve aradaki NAT tablolarındaki kayıtları tazelemek için periyodik olarak boş bir hizmet paketi (keepalive probe) gönderir. Bu, işletim sistemi çekirdeği seviyesindedir.
Özellikle TCP keepalive, operatörün NAT zaman aşımlarına ve ara düğümlerin idle zaman aşımlarına karşı ana silahınızdır. Her deneme, yol boyunca hareketsizlik sayacını sıfırlayan bir trafiktir.
TCP keepalive'ın üç temel parametresi vardır:
- keepalive idle (veya keepalive time) - kaç saniyelik hareketsizlikten sonra denemeler gönderilmeye başlanır. Çoğu işletim sisteminde varsayılan 7200 saniyedir, yani iki saat. Mobil ağlar için felaket.
- keepalive interval - yanıt gelmezse denemeler arasındaki aralık.
- keepalive count (probes) - peş peşe kaç yanıtsız denemenin bağlantının ölü olduğu anlamına geldiği.
Mobil ağlar için önerilen değerler
Varsayılan iki saat kesinlikle uygun değil. Operatör, ilk denemeden çok önce NAT'ı temizler. İşte pratikte test edilmiş çalışan değerler:
- keepalive idle: 15-25 saniye. En agresif NAT zaman aşımını garantili şekilde geçmek için kısa bir aradan sonra denemeler göndermeye başlayın.
- keepalive interval: 10-15 saniye. Deneme ulaşmadıysa kısa bir aralıkla tekrarlayın.
- keepalive count: 3-4. Üç veya dört yanıtsız denemeden sonra bağlantıyı ölü kabul edin ve sonsuz takılmayı beklemeden yeniden kurun.
Bu kombinasyon çift yönlü fayda sağlar: bağlantı duraklamalarda operatör tarafından koparılmaz ve eğer yine de ölürse (örneğin handover nedeniyle), istemci bunu saatler sonra değil 45-70 saniye içinde öğrenir. Ölü bağlantıyı hızlı fark etmek, dayanıklılığın yarısıdır.
Neden her iki ayara da ihtiyaç var?
Bir benzetme yapalım. HTTP keep-alive, toplantı odasını gün boyu rezerve etmek gibidir; her seferinde yeniden rezerve etmek için koşturmazsınız. TCP keepalive ise temizlikçi odanın boş olduğunu düşünüp kilitlemesin diye odaya periyodik olarak uğramaktır. Rezerve edip de uğramazsanız kilitlerler. Her seferinde yeniden rezerve ederseniz vakit kaybedersiniz. İkisine de ihtiyaç var.
MTU ve parçalanma: Hücresel ağlarda paketler neden daha küçük?
Şimdi takılmaların en çok göz ardı edilen nedenine geçiyoruz. Küçük yanıtlar geçiyor ama büyükler tamamen takılıyorsa, yüzde 90 ihtimalle sorun MTU ve bozuk PMTUD'dur.
MTU nedir, basitçe
MTU (Maximum Transmission Unit), bölünmeden ağa gönderilebilecek tek bir paketin maksimum boyutudur. Klasik Ethernet'te bu 1500 bayttır. Bunu bir kapı genişliği olarak düşünün: kapıdan daha geniş bir mobilyayı içeri sokmak için parçalara ayırmanız gerekir.
Sorun şu ki hücresel ağlarda etkin MTU genellikle 1500'ün altındadır. Nedeni kapsüllemedir. Mobil trafik, operatör ağı içinde ek protokol katmanlarına sarılır. Her katman kendi başlık baytlarını ekler ve faydalı veri için daha az yer kalır. Mobil ağlarda gerçek çalışma MTU'su genellikle 1400-1480 bayt aralığında, hatta bazen daha da düşüktür.
PMTUD nedir ve neden bozulur?
PMTUD (Path MTU Discovery), yol boyunca maksimum paket boyutunu otomatik olarak belirleme mekanizmasıdır. Şöyle çalışır: istemci Don't Fragment (parçalama) bayrağıyla büyük bir paket gönderir. Yolda daha küçük MTU'ya sahip bir düğüm varsa, bu düğüm paketi atar ve izin verilen boyutu belirten fragmentation needed adlı özel bir ICMP mesajı geri gönderir. İstemci bu ipucunu alır ve paket boyutunu küçültür.
Güzel bir düzenek. Ancak tek bir kırılgan koşula dayanır: ICMP mesajlarının istemciye geri ulaşması gerekir. Gerçekte ise birçok ağ, güvenlik duvarı ve güvenlik ayarı ICMP'yi tamamen engeller. İşte tam burada PMTUD black hole (kara delik) adı verilen felaket yaşanır.
PMTUD arızası nasıl görünür: Takılmanın anatomisi
- İstemci bağlantıyı kurar. El sıkışma küçük paketlerle gerçekleşir - her şey yolundadır.
- İstemci kısa bir istek gönderir - küçük paket geçer, yanıt gelir. Küçük yanıtlar çalışır.
- Sunucu, Don't Fragment bayrağıyla 1500 baytlık tam boyutlu paketlerden oluşan büyük bir yanıt göndermeye başlar.
- Yolda bir yerde MTU'su 1400 olan bir düğüm bu paketleri atar, çünkü paketler daha büyüktür ve parçalanamaz.
- Düğüm geriye ICMP fragmentation needed gönderir, ancak bu ICMP güvenlik duvarı tarafından engellenir ve ulaşmaz.
- Sunucu ipucunu alamaz, aynı büyük paketleri göndermeye devam eder, paketler yine atılır. Sonsuz döngü.
- Sonuç: küçük paketler (başlıklar, ACK) geçer, ancak yanıt verisi geçemez. Bağlantı büyük yanıtın ortasında tamamen donar.
İşte bu yüzden kısa istekler geçerken büyük yanıtlar takılı kalıyor. Bu mistisizm değil, PMTUD kara deliğidir. Muhtemelen mobil trafikle çalışan mühendislerin en büyük saç beyazlatma kaynağıdır.
MTU sorunu nasıl çözülür?
Uygulama katmanından ağ katmanına kadar birkaç çözüm düzeyi vardır:
- MSS clamping. Ağ katmanındaki en güvenilir yöntem. MSS (Maximum Segment Size), tarafların en başta, el sıkışma sırasında anlaştığı maksimum TCP segment boyutudur. MSS'yi, ortaya çıkan paket gerçek MTU'ya sığacak şekilde açıkça sınırlandırırsanız (örneğin MSS 1360-1400), sunucu en baştan doğru boyutta paketler gönderir ve hiçbir ICMP'ye gerek kalmaz. Bu, kara deliği kökünden çözer.
- Arayüz MTU'sunu küçültmek. Modemi veya trafiğin geçtiği makineyi siz yönetiyorsanız, arayüz MTU'sunu 1400 veya altına ayarlayabilirsiniz. Böylece tüm giden paketler güvenli boyutun üzerine çıkmaz.
- ICMP geçişine izin vermek. Yol üzerindeki güvenlik duvarları üzerinde kontrolünüz varsa, fragmentation needed türündeki ICMP mesajlarına izin verin. Böylece standart PMTUD olması gerektiği gibi çalışır.
- Uygulama katmanı. Büyük bir dosya indiriyorsanız, Range istekleriyle parçalara bölün. Her parça, büyük akış sorunlarıyla karşılaşma olasılığı daha düşük olan ayrı bir kısa aktarımdır. Bunun detayları pratik bölümde.
İçgörü: Ağı siz yönetmeseniz bile, bağlantı ayarları veya proxy hizmeti parametreleri aracılığıyla MSS'yi neredeyse her zaman etkileyebilirsiniz. İyi bir mobil proxy sağlayıcısı, kendi tarafında doğru MSS clamping ayarını yaparak sizi kara deliklerden kurtarır. Bu, hizmet kalitesinin kriterlerinden biridir.
Baz istasyonu değişimi ve ağlar arası geçiş: TCP neden bunu kaldıramaz?
Şimdi en temel uyumsuzluğa gelelim. Hücresel ağ hareketlilik için tasarlandı, TCP ise değil. Bu, mimari düzeyde bir çatışmadır.
TCP neden adrese bağlıdır?
Bir TCP bağlantısı dörtlüyle benzersiz şekilde tanımlanır: kaynak adres, kaynak port, hedef adres, hedef port. Bu, bağlantının posta adresi gibidir. Herhangi bir öğe değişirse, bu artık başka bir bağlantıdır ve eskisi geçersiz hale gelir.
Peki mobil ağda ne olur? Baz istasyonu değişiminin bazı senaryolarında veya teknolojiler arası geçişlerde (örneğin farklı nesil iletişim teknolojileri ya da ağlar arasında) mobil düğümün harici IP adresi değişebilir. İşte tam burada TCP çaresiz kalır: yeni adresle bağlantıyı sürdürmeyi bilmez. Eski bağlantı tamamen ölüdür. Yoldaki tüm veriler kaybolur.
Handover: Her zaman ölümcül değildir, ama her zaman risklidir
Hakkını yememek gerekirse, modern ağlar handover'ı kesintisiz yapmaya çalışır: hücre değişiminde aynı IP'yi korumaya çalışır. Bu genellikle başarılır ve siz geçişi fark etmezsiniz. Ama bazen IP değişir, radyo kanalında bir iki saniyelik kısa bir kesinti olur veya paket kaybı artar. Kısa bir istek için bu fark edilmez. On dakikalık bir oturum için ise her seferinde oynadığınız bir piyangodur.
Handover sırasında kopma belirtileri
- Kopmalar rastgeledir; veri miktarına veya zamana bağlı değildir.
- Cihaz fiziksel olarak hareket ediyorsa kopma sıklığı artar (gerçek SIM kullanan mobil proxy'ler için tipiktir).
- Kopmadan sonra yeni bağlantı normal şekilde kurulur - ağ canlıdır, sadece belirli eski bağlantı ölmüştür.
Bununla ne yapmalı: Kabullenin ve dayanıklılık inşa edin
IP değişimini TCP düzeyinde yenmek imkânsızdır. Ancak bağlantı kopmasının bir arıza değil, normal bir durum olduğu bir istemci inşa edebilirsiniz. Felsefe basit: mobil ağ üzerindeki bağlantı tanımı gereği geçicidir ve istemci bağlantıyı sorunsuz bir şekilde yeniden kurabilmeli ve kaldığı yerden devam edebilmelidir.
Kodda uygulayacağımız belirli teknikler:
- İşlemlerin idempotansı. İstekleri, güvenle tekrarlanabilecek şekilde tasarlayın. Range ile indirme idempotandır: aynı bayt aralığının tekrar istenmesi aynı sonucu verir.
- Baştan indirmek yerine kaldığı yerden devam etme. Kopmada dosyaya yeniden başlamayın, son alınan bayttan devam edin. Trafik ve zaman kazandırır.
- Bağlantı ölümünü hızlı fark etme. Bahsettiğimiz agresif TCP keepalive sayesinde ölü bir bağlantıyı dakikalar içinde değil, saniyeler içinde öğrenirsiniz.
- Kısa işlemler. Tek bir aktarım ne kadar kısaysa, handover'a yakalanma olasılığı o kadar düşüktür. Büyük bir yüklemeyi parçalara bölmek, bu ilkenin doğrudan sonucudur.
Python pratiği: Kaldığı yerden devam eden ve zaman aşımlı dayanıklı istemci
Teori yeter, hadi inşa edelim. Python ile başlayalım. Şunları yapan bir istemci oluşturacağız: TCP keepalive ayarlar, makul zaman aşımları belirler, Range ile dosyayı parçalar halinde indirir ve kopmadan sonra kaldığı yerden devam edebilir.
Adım 1: Sokette TCP keepalive ayarı
Standart HTTP kütüphaneleri kutu kutusu agresif keepalive ayarlamaz. Sokete erişmeniz gerekir. requests ekosisteminde bu, soket seçeneklerini ayarlayan özel bir taşıma adaptörü ile yapılır: keepalive'ı açar, idle 20 saniye, interval 10 saniye, count 3 olarak belirler. Tanım düzeyinde mantık şudur: bağlantı kurulurken düşük seviyede gerekli parametreleri ayarlayan bir adaptör kaydederiz.
Ayarların anlamlı kısmı sözlü sözde kod olarak şöyle: SO_KEEPALIVE seçeneğini açın, ardından TCP_KEEPIDLE'ı 20, TCP_KEEPINTVL'ı 10 ve TCP_KEEPCNT'yi 3 olarak ayarlayın. Seçenek adları işletim sistemleri arasında biraz farklılık gösterir, bu nedenle üretimde platform kontrolü yapılarak seçilir.
Adım 2: Makul zaman aşımları
Kritik kural: zaman aşımlarını her zaman açıkça belirtin ve bağlantı zaman aşımı ile okuma zaman aşımını ayırın. Zaman aşımı olmayan varsayılan, istemcinin yarı açık bir bağlantıda sonsuza kadar takılacağı bir tuzaktır.
- Bağlantı zaman aşımı: 10 saniye. Mobil ağ üzerinden bağlantı kurmak daha yavaştır, ancak 10 saniye payıyla yeterlidir.
- Okuma zaman aşımı: 30 saniye. Bu, tüm aktarım için değil, veri parçaları arasındaki hareketsizlik için zaman aşımıdır. 30 saniye içinde tek bayt gelmezse bağlantı sorunlu kabul edilir.
- İşlemin toplam bütçesini tüm istek için tek bir dev zaman aşımıyla değil, devam indirme mantığı düzeyinde ayrıca kontrol edin.
Adım 3: Range ile kaldığı yerden devam ederek indirme
Algoritmanın fikri şu: Hedef dosyayı yazmak için açarız. Daha önce inilen kısmın boyutunu öğreniriz (dosya kısmen varsa). Kalan aralığı Range: bytes başlığıyla mevcut konumdan sona kadar isteriz. Veriler geldikçe akışı dosyaya yazarız. Bir kopma yakalarsak (okuma hatası, bağlantı kopması), panik yapmayız: diskte kaç bayt olduğuna tekrar bakarız ve isteği yeni başlangıç konumuyla tekrarlarız. Dosyanın tamamı elde edilene kadar böyle devam ederiz.
- Başlık isteğiyle dosyanın toplam boyutunu belirleyin (HEAD veya Content-Range'ı okumak için Range: bytes=0-0 ile GET).
- İnilen kısmın yerel boyutunu kontrol edin.
- Yerel boyut tam boyuta eşitse dosya hazır demektir, çıkın.
- Aksi halde yerel boyuttan başlayan bir Range isteği oluşturun.
- Yanıtı 64-256 kilobaytlık parçalar halinde okuyun ve dosyaya ekleyin.
- Başarılı tamamlanmada bütünlüğü doğrulayın (boyut, mümkünse sağlama toplamı).
- Kopmada deneme sayacını artırın, kısa bir duraklama yapın ve 2. maddeye dönün.
- Sistemik bir sorunda sonsuza kadar dönmemek için taşıma katmanındaki maksimum deneme sayısını sınırlayın (örneğin 5-8).
Önemli bir ayrıntı: Sunucunun Range'i desteklediğinden emin olun. İşaret, yanıttaki Accept-Ranges: bytes başlığı ve Range isteğine verilen 206 Partial Content kodudur. Sunucu 200 döndürüp Range'i yok sayarsa kaldığı yerden devam etmek mümkün değildir ve dosyanın tamamı indirilmelidir; bu durumda keepalive ve doğru MSS daha da önemli hale gelir.
Adım 4: Büyük yüklemenin parçalara bölünmesi
İndirmek yerine büyük bir veri yüklüyorsanız (örneğin veri gönderiyor veya büyük bir rapor alıyorsanız) aynı parçalama ilkesini uygulayın. Görevi sayfalara veya sabit boyutlu parçalara bölün. Her parça, kendi hata işlemesine sahip ayrı bir kısa işlemdir. Bir ilerleme günlüğü tutun: hangi parçaların onaylandığını görün. Kopmada yalnızca onaylanmamış parçaları tekrarlayın. Bu, kırılgan on dakikalık bir işlemi dayanıklı kısa işlemler serisine dönüştürür.
Sunucu yanıt kodlarına göre tekrar stratejilerine gelince, burada bunlara girmiyoruz; çünkü bu, 429 ve üstel geri çekilme hakkında ayrı bir yazının konusu ve bu makaleden sonra ona geçmelisiniz. Bizim odak noktamız taşıma: kopma, zaman aşımı, boyut.
Node.js pratiği: Dayanıklı HTTP ajanı ve akış (streaming)
Şimdi aynı ilkeler Node.js ekosisteminde. Burada bağlantı havuzunu yöneten ajan (agent) nesnesi merkezi bir rol oynar.
Adım 1: Keep-alive destekli ajan ayarı
Node'da keepAlive etkinleştirilmiş bir HTTP veya HTTPS ajanı oluşturulur. keepAlive true parametresi, ajanın bağlantıları yeniden kullanmasını sağlar (bu HTTP katmanıdır). Ayrıca keepAliveMsecs belirlenir - soket düzeyinde TCP keepalive denemelerinin gönderilme aralığı. Mobil ağlar için keepAliveMsecs'i operatörün NAT zaman aşımını geçmek için 15000-20000 milisaniye civarında ayarlayın. Ayrıca gereksiz bağlantı üretmemek için maxSockets ve maxFreeSockets'i sınırlayın.
Adım 2: Farklı katmanlarda zaman aşımları
Node'da zaman aşımları birkaç yerde belirlenir ve hiçbirini unutmamak önemlidir:
- Bağlantı kurma zaman aşımı - istek üzerindeki bir seçeneğe veya soketin bağlantı olayı işleyicisine bağlıdır.
- Soket hareketsizlik zaman aşımı - soket zaman aşımını ayarlayan yöntemdir. Tetiklendiğinde soketi açıkça yok etmek ve bunu bir kopma olarak ele almak gerekir. Node, zaman aşımında soketi otomatik olarak kapatmaz, yalnızca bir olay yayar; bu sıklıkla unutulur ve bağlantı asılı kalmaya devam eder.
- İstek ve soket üzerindeki error ve close olaylarının işlenmesi - her biri kontrollü bir yeniden deneme mantığına yönlendirmelidir.
Önerilen değerler Python ile aynıdır: connect yaklaşık 10 saniye, soket idle yaklaşık 30 saniye, keepalive denemeleri her 15-20 saniyede bir.
Adım 3: Kaldığı yerden devam eden akış ile indirme
Node'da akışlarla (stream) çalışmak doğaldır. Devam indirme mantığı Python'daki ile aynıdır: yerel dosyanın boyutunu kontrol ederiz, ekleme modunda bir yazma akışı açarız, mevcut boyuttan başlayan bir Range başlığıyla istek oluştururuz, data, end ve error olaylarına işleyiciler bağlarız. data olayında parçayı dosyaya yazarız. end olayında dosyanın tamamen alınıp alınmadığını kontrol ederiz. error veya beklenenden az veriyle erken close durumunda yeni bir konumdan tekrar başlatırız.
Node'da dayanıklılığın kilit noktası, akışın erken sonlanmasının doğru şekilde ele alınmasıdır. Bağlantı kopsa bile her şey alınmamışken end olayı gelebilir. Bu nedenle fiilen alınan miktarı her zaman Content-Length veya Content-Range başlığındaki beklenen miktarla karşılaştırın. Sadece end olayının tetiklenmesine güvenmeyin.
Adım 4: Taşıma katmanında yeniden deneme sarmalayıcısı
Tüm indirme işlemini sınırlı sayıda deneme içeren bir döngüye sarın. Denemeler arasında kısa bir duraklama olmalıdır (taşıma katmanı kopmaları için 1-3 saniye yeterlidir, çünkü neden sunucunun aşırı yüklenmesi değil, ağ olayıdır). Denemeleri sayın. Limite ulaşıldığında hatayı üst katmana teşhis bilgileriyle fırlatın: kaç bayt alındı, hata türü neydi, kaç deneme yapıldı. Bu teşhis, olayları analiz ederken çok değerlidir.
Yaygın hatalar: Yapmamanız gerekenler
Başkalarının kodlarında sıklıkla karşılaştığımız anti-pattern'leri inceleyelim. Bunlardan kaçının - sorunların yarısı ortadan kalkar.
Hata 1: Açık zaman aşımlarının olmaması
En yaygın ve en acı verici olanı. Zaman aşımı olmayan istemci, yarı açık bağlantıda sonsuza kadar takılır. Akış bloke olur, kaynak serbest kalmaz, siz de işlemin hâlâ devam ettiğini sanırsınız. Zaman aşımlarını her zaman açıkça belirleyin. Zaman aşımının olmaması sonsuz sabır değil, gizli bir bombadır.
Hata 2: Varsayılan TCP keepalive'a güvenmek
Varsayılan iki saat, TCP keepalive'ı mobil ağlar için faydasız hale getirir. Birçok kişi SO_KEEPALIVE'ı açar ve rahatlar; ilk denemenin 7200 saniye sonra, operatörün her şeyi çoktan temizlemesinden sonra gideceğini fark etmez. idle, interval ve count değerlerini açıkça ayarlayın.
Hata 3: Her kopmada dosyanın tamamını yeniden indirmek
Yüzde 95'te kopma ve sıfırdan tam yeniden başlatma yalnızca kayıp zaman değil, aynı zamanda proxy'de genellikle ücretlendirilen mobil trafiğin de boşa harcanmasıdır. Tüm büyük indirmeler için Range ile devam etme şarttır.
Hata 4: MTU ve MSS'yi görmezden gelmek
İnsanlar, nedeni PMTUD kara deliği olmasına rağmen aylarca büyük yanıtlardaki takılmalarla uğraşıp zaman aşımlarını ve proxy'leri değiştirir. Büyük yanıtlar takılıyor, küçükler geçiyorsa öncelikle MTU'yu kontrol edin ve MSS clamping ayarlayın. Bu size haftalar kazandırır.
Hata 5: Taşıma katmanı kopmalarını sunucu yanıtlarıyla karıştırmak
Taşıma katmanı kopması (RST, okuma zaman aşımı, ölü soket) ile hata kodu dönen sunucu yanıtı, farklı tepki stratejileri gerektiren farklı durumlardır. Taşıma kopmaları için kısa duraklamalı hızlı tekrarlar ve kaldığı yerden devam etme uygundur. 429 gibi kodlar dönen sunucu yanıtları için üstel geri çekilme gerekir - ve bu ayrı bir makalenin konusudur. Bu iki katmanı tek bir işleyicide karıştırmayın.
Hata 6: Aşırı agresif tekrarlar
Sistemik bir sorun varken (örneğin proxy tamamen erişilemezken) sınırsız tekrar döngüsü, asalak bir yüke dönüşür. Her zaman bir deneme tavanı koyun ve işlemi teşhis ile anlamlı bir şekilde sonlandırın.
Hata 7: Sonucun bütünlüğünü kontrol etmemek
İndirmenin tamamlanması, doğru verilerin alındığı anlamına gelmez. Bir kopma, tüm biçimsel görünümüyle tamamlanmış gibi duran, kırpılmış bir dosya bırakabilir. Her zaman boyutu, önemli veriler için ise sağlama toplamını kontrol edin.
Hata 8: Tek bir bağlantıyı çok uzun süre tutmak
Mobil ağ üzerinden bir bağlantı ne kadar uzun yaşarsa, bir handover, IP değişimi veya NAT zaman aşımıyla karşılaşmanın kümülatif olasılığı o kadar artar. Bağlantıyı periyodik olarak yeniden kurmak zayıflık değil, akıllıca bir temizliktir. Bağlantıları yeniden oluşturmaktan korkmayın.
Teşhis ve dayanıklılık oluşturma araçları ve kaynakları
Doğru araç saatler kazandırır. İşte el altında bulundurmanız gereken cephanelik.
Ağ ve paket teşhisi
- Trafik yakalama ve analizi. Paket yakalama aracı sizin mikroskobunuzdur. RST'yi kimin gönderdiğini, ICMP fragmentation needed'ın ulaşıp ulaşmadığını, gerçekte hangi boyutta paketlerin gittiğini ve akışın nerede kesildiğini gösterir. O olmadan MTU teşhisi ve kopmanın failini belirlemek bir tahmin oyununa dönüşür.
- Yol kontrol araçları. Rota izleme ve MTU kontrol araçları, paket boyutunun yolun neresinde düştüğünü anlamanıza yardımcı olur. Geçebilen maksimum paket boyutunu bilinçli olarak arayan modlar vardır - MSS ayarı için tam da gereken budur.
- Test yankı sunucuları. Keep-alive tutabilen ve belirli boyutta veri döndürebilen basit bir sunucu, idle zaman aşımlarını ölçmek ve büyük yanıt sorunlarını kontrollü koşullarda yeniden üretmek için vazgeçilmezdir.
İstemci için kütüphaneler ve yaklaşımlar
- Soket ayarlarında esneklik sağlayan HTTP istemcileri. Bağlantı parametrelerine erişim veren ve zaman aşımları ile keepalive'ı düşük seviyede ayarlamanıza izin veren kütüphaneleri seçin.
- Akış (streaming) mekanizmaları. Yanıt gövdesinin akış olarak işlenmesi büyük indirmeler için zorunludur - tüm yanıtı bellekte tutmamalısınız.
- İlerleme günlüğü. Basit bir durum deposu (hangi parçaların alındığı, diskte kaç bayt olduğu) kaldığı yerden devam etmeyi önemsiz bir göreve dönüştürür.
Proxy altyapısının kalitesi
Ayrıca şunu vurgulayalım: taşıma katmanı sorunlarının önemli bir kısmı kaliteli bir proxy sağlayıcısı tarafında çözülür. Doğru yapılandırılmış MSS clamping, uygun idle zaman aşımları, handover sırasında IP'nin istikrarlı tutulması, keep-alive ile şeffaf çalışma - bunların hepsi olgun bir hizmetin işaretleridir. MobileProxy.space gibi hizmetler, altyapıyı bu taşıma nüanslarını dikkate alarak tasarlar ve istemcinin bir kısım yükünü alır. Ancak ideal bir proxy ile bile istemcinin dayanıklı olması gerekir - çünkü radyo kanalı prensipte öngörülemezdir.
Vaka örnekleri ve sonuçlar: Bu pratikte nasıl işliyor?
Tipik durumları ve çözümlerini yansıtan birkaç genelleştirilmiş vakayı inceleyelim. Rakamlar ortalamadır, ancak gerçek büyüklük sıralarını yansıtır.
Vaka 1: Katalog yüklemesi ortasında takılıyordu
Durum. Ekip, mobil proxy üzerinden tek bir istekle büyük bir ürün kataloğu yüklüyordu. Yanıt yaklaşık 15 megabayttı. 6-8 megabayt civarında istikrarlı bir şekilde takılıyordu; hata yok, sadece sessizlik, ta ki birkaç dakika sonra genel zaman aşımı devreye girene kadar.
Teşhis. Küçük istekler kusursuz geçiyordu. Trafik yakalama, büyük paketlerin Don't Fragment bayrağıyla gönderildiğini ve ICMP fragmentation needed'ın geri dönmediğini gösterdi. Klasik PMTUD kara deliği.
Çözüm. Paketin mobil ağın gerçek MTU'su içinde kalmasını garantileyen bir değerde MSS clamping ayarladık ve yüklemeyi 2 megabaytlık sayfalara böldük.
Sonuç. Takılmalar tamamen ortadan kalktı. Yükleme süresi öngörülebilir hale geldi ve nadir kopmalarda tüm katalog yerine yalnızca bir sayfa tekrarlandı. Başarılı yükleme oranı yaklaşık yüzde 40'tan fiilen yüzde 100'e yükseldi.
Vaka 2: Bağlantı bekleme duraklamalarında ölüyordu
Durum. İstemci, ağır bir raporun oluşturulması için istek gönderiyordu, sunucu 90-120 saniye düşünüyor ve sonra sonucu teslim etmesi gerekiyordu. Ancak rapor hazır olduğunda bağlantı çoktan ölmüştü.
Teşhis. Idle zaman aşımı ölçümü, yaklaşık 60 saniyelik hareketsizlikte istikrarlı bir kopma olduğunu gösterdi. Fail, operatörün NAT zaman aşımıydı: bekleme sırasında hiç trafik yoktu.
Çözüm. TCP keepalive'ı idle 20 saniye ve interval 10 olacak şekilde etkinleştirdik. Artık bekleme sırasında bağlantı her 20 saniyede bir hizmet denemeleriyle tazeleniyordu.
Sonuç. Bağlantı, rapor hazır olana kadar yaşadı. Duraklamalardaki kopmalar sona erdi. Ekstra bonus olarak istemci, dakikalarca takılmak yerine gerçekten ölü bağlantıları 45-60 saniye içinde öğrenmeye başladı.
Vaka 3: Aktif veri kazıma sırasında rastgele kopmalar
Durum. Uzun süren veri kazıma oturumları, miktara veya zamana bağlı olmadan kaotik şekilde kopuyordu. Özellikle belirli saatlerde daha sık oluyordu.
Teşhis. Belirtiler, handover sırasında IP değişimine işaret ediyordu. Kopmadan sonra yeni bağlantı anında kuruluyordu - ağ canlıydı.
Çözüm. İstemciyi geçici bağlantı felsefesine göre yeniden düzenledik: kısa idempotant işlemler, ilerleme günlüğü, kopmada hızlı bağlantı yeniden kurma, kısa duraklamalı sınırlı yeniden denemeler.
Sonuç. Kopmalar fiziksel olarak ortadan kalkmadı (IP değişimini yenmek mümkün değil), ancak sorun olmaktan çıktı. Her kopma, kısa bir işlemin tekrarlanmasına mal oldu - saniyenin çok küçük bir kısmı. Sürecin genel güvenilirliği dramatik şekilde arttı ve mühendisler geceleri logların başında nöbet tutmayı bıraktı.
Vakalardan genel sonuç
Şu örüntüyü fark edin: her vakada çözüm, proxy'yi değiştirmekte değil, taşıma katmanını anlamak ve istemciyi doğru yapılandırmakta yatıyordu. Belirtilere dayalı teşhis, belirli faili ortaya çıkardı ve ardından tedavi hedefli ve hızlı oldu.
SSS: Mobil ağlarda bağlantı kopmaları hakkında sık sorulan sorular
Mobil proxy üzerinden kısa istekler çalışıp uzun olanlar neden kopuyor?
Çünkü uzun işlemler daha uzun yaşar ve taşıma katmanındaki her sorunla karşılaşmayı başarır: duraklamalarda idle zaman aşımı, yanıt boyutu limiti, bağlantı ömrü limiti, IP değişimli handover ve büyük paketlerde PMTUD kara deliği. Kısa istekler, bunlardan herhangi biri devreye girmeden önce tamamlanır. Çözüm: keepalive ve MSS yapılandırmak ve Range ile devam indirmeyi uygulamak.
Bağlantıyı tam olarak kimin kopardığını nasıl anlarım - proxy mi, operatör mü, sunucu mu?
İmzaya bakın. Duraklamalarda kopma - operatörün NAT zaman aşımı veya proxy'nin idle'ı. Sabit veri miktarında kopma - proxy veya sunucudaki boyut limiti. Sabit sürede kopma - ömür limiti. Büyük yanıtlarda takılma - MTU ve PMTUD. Hareket halinde rastgele kopmalar - handover. Kesin cevap için trafik yakalama kullanın: RST'nin hangi adresten geldiğini ve ICMP'nin ulaşıp ulaşmadığını gösterir.
TCP keepalive ve HTTP keep-alive arasındaki fark nedir?
HTTP keep-alive uygulama katmanında çalışır ve tek bir bağlantının birden çok istek için yeniden kullanılmasını sağlar, böylece kurulum maliyetinden tasarruf eder. TCP keepalive, işletim sistemi çekirdeği düzeyinde çalışır ve duraklamalarda bağlantıyı canlı tutmak ve NAT'ı tazelemek için periyodik olarak hizmet denemeleri gönderir. İlki yeni isteklerde zaman kazandırır, ikincisi hareketsizlikte kopmaktan kurtarır. İkisine de ihtiyaç var.
Mobil ağlar için TCP keepalive değerleri ne olmalı?
Başlangıç noktası: idle 15-25 saniye, interval 10-15 saniye, count 3-4. Bu kombinasyon, operatörlerin agresif NAT zaman aşımlarını geride bırakır ve aynı zamanda ölü bağlantıların hızlı tespitini sağlar. Kesin değerleri, kendi operatörünüz ve proxy'nizdeki idle zaman aşımını ölçerek belirleyin.
PMTUD kara deliği nedir ve nasıl tanınır?
Yoldaki bir düğümün çok büyük paketleri attığı, ancak boyutun küçültülmesi gerektiğine dair ICMP bildiriminin engellendiği ve göndericiye ulaşmadığı durumdur. Sonuç olarak büyük paketler sürekli kaybolurken küçükler geçer. Belirtiyle tanınır: el sıkışma ve küçük yanıtlar çalışır, büyük yanıtlar ise tamamen takılır. MSS clamping veya MTU'yu küçülterek çözülür.
Baz istasyonu değişiminde TCP bağlantısı korunabilir mi?
Ağ, handover sırasında aynı harici IP'yi koruyorsa evet, bağlantı geçişi atlatır, belki kısa bir gecikmeyle. IP değişiyorsa hayır, eski TCP bağlantısı geri dönüşümsüz şekilde ölüdür, çünkü TCP katı bir şekilde adres ve port çiftine bağlıdır. Doğru strateji, bağlantıyı ne pahasına olursa olsun korumaya çalışmak değil, bağlantıyı sorunsuz bir şekilde yeniden kuran ve kaldığı yerden devam eden bir istemci inşa etmektir.
Kopmadan sonra dosya indirmeye doğru şekilde nasıl devam edilir?
Sunucunun Range'i destekleyip desteklemediğini kontrol edin (Accept-Ranges: bytes başlığı ve Range isteğine 206 kodu). Ardından kopmada, alınmış kısmın boyutunu öğrenin ve kalanı bu bayttan başlayarak Range başlığıyla isteyin, aynı dosyaya ekleyin. Tamamen alınana kadar tekrarlayın ve deneme sayısını sınırlayın. Sonunda toplam boyutu beklenen boyutla mutlaka karşılaştırın.
Mobil proxy için HTTP istemcisinde hangi zaman aşımları ayarlanmalı?
Bağlantı kurma zaman aşımını (yaklaşık 10 saniye) ve okuma hareketsizlik zaman aşımını (yaklaşık 30 saniye, tüm aktarım için değil veri parçaları arasındaki duraklama olarak) ayırın. İşlemin toplam bütçesini tek bir dev zaman aşımıyla değil, devam indirme mantığı düzeyinde kontrol edin. Zaman aşımlarını asla sınırsız bırakmayın.
Yanıt kodlarına göre yeniden deneme stratejileri zaten ayarlanmışsa bir şey değiştirmek gerekir mi?
Evet. Yanıt kodlarına göre yeniden denemeler (örneğin 429'u üstel geri çekilmeyle işlemek) uygulama katmanıdır ve ayrı bir konudur. Taşıma katmanı kopmaları - RST, okuma zaman aşımları, ölü soketler - kendi mantığını gerektirir: kısa duraklamalı hızlı tekrarlar, devam indirme, keepalive ve doğru MSS. Bu iki katman birbirinin yerine geçmez ve istemcide bir arada bulunmalıdır.
Proxy sağlayıcısı seçimi taşıma dayanıklılığını etkiler mi?
Önemli ölçüde. Olgun bir sağlayıcı, MSS clamping yapar, uygun idle zaman aşımları ayarlar, handover'da IP'yi korumaya çalışır ve keep-alive ile doğru çalışır. Bu, sizin kodunuzdan önce sorunların bir kısmını ortadan kaldırır. Ancak ideal bir proxy bile dayanıklı bir istemci inşa etme ihtiyacını ortadan kaldırmaz, çünkü radyo kanalı prensipte öngörülemezdir.
Sonuç: Bağlantı geçicidir, ama veriler yerine ulaşmalı
Semptomdan dayanıklı istemciye uzanan bir yol kat ettik. Bu makaleyi yer imlerinize eklemeniz için ana noktaları kaydedelim.
Birinci. Mobil proxy üzerinden uzun bir bağlantının kopması mistisizm değil, oldukça somut mekanizmaların sonucudur: üç katmandaki idle zaman aşımları, boyut ve süre limitleri, MTU sorunları ve handover. Her birinin kendi imzası vardır ve belirtilere dayalı teşhis neredeyse her zaman faili ortaya çıkarır.
İkinci. Yoldaki en kısa zaman aşımı bağlantının kaderini belirler. Ölçün ve TCP keepalive'ı bu limitten daha agresif ayarlayın - mobil ağlar için idle 15-25 saniye. TCP keepalive ve HTTP keep-alive'in farklı mekanizmalar olduğunu ve ikisine de ihtiyaç olduğunu unutmayın.
Üçüncü. Büyük yanıtlar takılıp küçükler geçiyorsa, bu neredeyse kesinlikle PMTUD kara deliğidir. MSS clamping ve doğru MTU ile çözülür. Haftalarca zaman aşımı denemeyin, önce paket boyutunu kontrol edin.
Dördüncü. Handover sırasında IP değişimini yenmek imkânsızdır, ancak onu korkutucu olmaktan çıkarabilirsiniz. İstemciyi bağlantının geçiciliği etrafında inşa edin: kısa idempotant işlemler, Range ile devam indirme, ilerleme günlüğü, hızlı yeniden kurma, sınırlı tekrarlar ve zorunlu bütünlük kontrolü.
Sonraki adımlarınız basit. Proxy'nizde ve operatörünüzde idle zaman aşımını ölçün. TCP keepalive'ı etkinleştirin ve ayarlayın. Büyük yanıtlardaki davranışı test edin ve gerekirse MSS ayarlayın. Range ile devam indirmeyi uygulayın. Ayrıca, yalnızca taşıma katmanını değil uygulama katmanını da kapatmak için 429 ve üstel geri çekilme hakkındaki ilişkili makaleyi mutlaka inceleyin.
Mobil ağ doğası gereği öngörülemezdir. Ancak doğasına saygıyla inşa edilmiş bir istemci, bu öngörülemezliği gece nöbetlerinin kaynağı olmaktan çıkarıp rutin bir arka plan gürültüsüne dönüştürür. Bağlantı geçicidir - ve bu normaldir. Önemli olan verilerin yine de yerine ulaşmasıdır. Artık bunu nasıl başaracağınızı biliyorsunuz.