Bir resim hayal edin. Cuma akşamı, ayrıştırıcınız veya hesap yönetim sisteminiz nihayet canlıya alındı. İlk dakikalarda her şey uçuyor. Sonra garip şeyler olmaya başlıyor: bazı istekler başarısız oluyor, bir yerde captcha çıkıyor, bir hesap aniden kimlik doğrulaması istiyor ve loglar bağlantı hataları karmaşasına dönüşüyor. Tanıdık geldi mi? On vakadan dokuzunda sorunun kaynağı hedef site veya iş mantığınız değil. Sorun, uygulamanın IP adreslerini nasıl yönettiğinde.

Çoğu proje basit bir şeyle başlar: adres listesi içeren bir metin dosyası, satır satır okuma, rastgele bir satır seçme. Ve bu işe yarar. Ta ki gerçek yük gelene kadar. O zaman saf liste dağılır ve konsolda tek bir istekle tekrarlanamayan aralıklı hatalar alırsınız.

Bu makale, uygulama içinde proxy havuzu tasarlamak için kapsamlı bir rehberdir. Belirli bir görev için adresin nasıl seçileceğini, adreslerin sağlığının nasıl kontrol edileceğini, sorunlu IP'lerin karantinaya nasıl alınıp geri döndürüleceğini ve tek bir hesap için sticky-oturumun nasıl korunacağını ele alacağız. Bu mühendislik konusu, ancak erişilebilir bir dille, kod, kontrol listeleri ve gerçek hataların analiziyle anlatacağız.

Hemen sınırları belirtelim. Tek bir istek için zaman aşımlarını ve yeniden deneme politikalarını tartışmıyoruz – bu ayrı ve büyük bir konu. Ayrıca adresin modem veya donanımda fiziksel olarak nasıl değiştiğine de girmiyoruz – bu uygulama değil, altyapı seviyesidir. Odağımız, kodunuzdaki havuz mantığıdır.

Metin dosyasındaki adres listesi neden gerçek yük altında çöker

Şimdi tipik bir başlangıç ​​uygulamasına dürüstçe bakalım. Bir dosya var, içinde yüz satır adres var. Uygulama dosyayı okur, satırları bir diziye koyar ve her istek için rastgele bir öğe alır. Basit, anlaşılır, gösterilerde çalışır. Peki neden bozuluyor?

Sorun bir: Adresin durumu hakkında hafıza yok

Diziden rastgele seçim, adresin bir saniye önce ne olduğu hakkında hiçbir şey bilmez. Kırk yedinci adres az önce üst üste beş hata verdi ve açıkça sağlıksızsa, rastgele algoritma onu yine aynı olasılıkla seçer. Ölü bir adrese defalarca çarpar, zamanınızı, yeniden denemelerinizi ve daha da önemlisi hedef platformun eylemlerinize olan güvenini boşa harcarsınız.

Sorun iki: Görevin adrese bağlanması yok

Hesaplarla çalışırken, bir hesabın ağa her zaman aynı adresten çıkması kritiktir. Platformların dolandırıcılık önleme sistemleri, bir kullanıcının oturumunun birkaç dakika içinde farklı coğrafi bölgelerden onlarca farklı alt ağ arasında zıpladığını fark eder. Bu doğal değildir. Gerçek bir insan böyle davranmaz. Dosyadan rastgele seçim bu kargaşayı garanti eder.

Sorun üç: Birden fazla işçi varken yarış koşulları

Birden fazla paralel işlem veya iş parçacığı başlattığınız anda, bellekteki basit dizi bir yarış koşulları kaynağına dönüşür. İki işçi aynı dizini okur, ikisi de aynı adresi alır ve ikisi de adresi iki kat fazla yükler. Hiçbir koordinasyon yoktur. Sayaclar varsa, süreçler arasında kaybolurlar.

Sorun dört: Gözlemlenebilirlik yok

Metin dosyası sessizdir. Hangi adresin yüzde seksen captcha verdiğini, hangisinin yavaşladığını veya hangisinin bir gündür ölü olduğunu söylemez. Körü körüne çalışırsınız ve sorunları, artık çok geç olduğunda iş metriklerindeki dolaylı semptomlardan öğrenirsiniz.

Sonuç basit: Adres listesi veridir. Yük altında adres yönetimi ise bir sistemdir. Aralarındaki fark, makalemizin konusudur. Şimdi bu sistemi tuğla tuğla inşa edeceğiz.

Temeller: havuz, görev için adres kiralama ve oturum olarak kabul edilen şey

Temelden başlayalım. Deneyimli bir mühendissenseniz yine de okumanızı öneririm – burada makale boyunca kullanacağımız terminolojiyi sabitliyoruz.

Adres havuzu nedir?

Havuz, sadece bir adres listesi değil, davranışı olan bir nesnedir. Adresleri durumlarıyla birlikte saklar ve iki ana işlem sağlar: bir görev için adres vermek ve onu geri almak. Klasik benzetme – bir kütüphane. Kitaplarla dolu bir rafınız var, ancak sizinle raf arasında bir kütüphaneci var. Hangi kitapların ödünç verildiğini, hangilerinin hasarlı olup onarıma gönderildiğini ve hangilerinin boşta olduğunu bilir. Kendiniz rafa dokunmazsınız – kütüphaneciden istersiniz ve o uygun kitabı verir.

Görev için adres kiralama

Kiralama, bir adresin belirli bir göreve geçici olarak tahsis edilmesidir. Havuz adresi verir, onu meşgul olarak işaretler veya üzerinde yeni bir yük olduğunu kaydeder ve görev tamamlandığında adres iade edilir. Bu nedenle havuz arayüzünde iki yöntem belirir ve bunlar iş atlarımız olacak: acquire – adres al, ve release – sonuç raporuyla geri ver.

Geri dönerken rapor – kilit bir detay. Görev adresi iade ettiğinde, havuzu sonucun ne olduğu konusunda bilgilendirir: başarı, bağlantı hatası, captcha, engelleme. Bu bilgi, sağlık ve karantina mantığının tamamını besler.

Sticky bağlama vs rastgele seçim

Burada çok önemli bir sınır var. Rastgele seçim, her istekte havuzun rastgele bir adres vermesidir. Bu mod, sürekli bir oturum kavramının olmadığı görevler için iyidir: her isteğin bağımsız olduğu bağımsız sayfalardan toplu kamu verisi toplama gibi.

Sticky bağlama, belirli bir anahtarın (örneğin hesap kimliği) her zaman aynı adresi almasıdır. Bu, kişiliğin zaman içinde sürekliliğinin önemli olduğu yerlerde kritiktir. Bir hesapla çalışmak tipik bir örnektir. Hesap, platforma ağda zıplayan bir sürü varlık değil, istikrarlı bir kullanıcı olarak görünmelidir.

İş görevi düzeyinde oturum olarak kabul edilen şey

Oturum kelimesi aşırı yüklüdür. HTTP düzeyinde bir anlama, TCP düzeyinde başka bir anlama gelir. Ancak bizi ilgilendiren iş oturumudur. Bu, platform açısından aynı kullanıcıdan ve aynı adresten gelmesi gereken mantıksal olarak bağlantılı bir dizi eylemdir.

İş oturumu örnekleri:

  • Bir hesaba giriş yapmak, içinde bir dizi eylem gerçekleştirmek ve çıkış yapmak – tümü aynı adresten.
  • Çok adımlı bir senaryo: ürün kartını açma, sepete ekleme, ödeme yapma – tüm adımlar birbirine bağlıdır.
  • Bir profil altında bir iş günü boyunca çalışmak; burada adres değişikliği şüpheli bir taşınma gibi görünürdü.

Oturumun sınırlarını belirlemek, teknik bir veri değil, sizin proje kararınızdır. Oturumun on beş dakika mı, bir saat mi yoksa açıkça çıkış yapılana kadar mı yaşadığına siz karar verirsiniz. Bu tanım, havuzun anahtarı adrese ne kadar süre bağlı tutacağını belirler. Bunu aklımızda tutalım – sticky-oturumlar konusuna birden çok kez döneceğiz.

Derinlemesine inceleme: havuzda bir adresin yaşam döngüsü

Ayrı stratejilere girmeden önce genel resmi görmek faydalı olacaktır. İyi tasarlanmış bir havuzda her adresin bir yaşam döngüsü, arasında geçiş yaptığı bir dizi durum vardır.

Adresin durumları

  • Healthy (sağlıklı) – adres verilebilir, metrikler normal.
  • Degraded (bozulmuş) – adres hala veriliyor, ancak daha düşük ağırlıkla, çünkü performans düştü.
  • Quarantined (karantinada) – adres geçici olarak verilmez, bekleme süresi devam eder.
  • Probing (test ediliyor) – adres hizmete dönmeden önce aktif kontrol geçiriyor.
  • Dead (ölü) – adres uzun süreliğine veya kalıcı olarak çalışmaz kabul edilir.

Durumlar arasındaki geçişler, inşa ettiğimiz sistemin ta kendisidir. Sağlıklı bir adres, hata biriktirdiğinde bozulur. Bozulmuş bir adres eşiğe ulaştığında karantinaya girer. Karantinadan bekleme süresinden sonra kontrole gider. Kontrolü geçerse sağlıklı olarak geri döner. Geçemezse artan bekleme süresiyle karantinaya döner. Birkaç kez üst üste başarısız olursa adres ölü kabul edilir.

Neden bir soyutlama katmanına ihtiyaç var?

Kilit içgörü: Uygulama adresin durumlarını bilmemelidir. Uygulama kodu sadece adres ister ve sonuçla geri verir. Yaşam döngüsünün tüm karmaşıklığı havuzun içinde gizlidir. Bu kapsülleme ilkesidir ve yüz kat kendini amorti eder. Karantina stratejisini değiştirmek istediğinizde, iş mantığındaki onlarca yeri değil, tek bir modülü düzeltirsiniz.

Zihinsel yük modeli

Adresin üç eksende yaşadığını aklınızda tutmak iyidir:

  • Tazelik – sağlığını en son ne zaman kontrol ettik.
  • Yük – şu anda üzerinde kaç görev var.
  • İtibar – birikmiş başarı ve başarısızlık geçmişi.

Herhangi bir seçim stratejisi, aslında bu üç ekseni tek bir puanda birleştirir. Şimdi belirli stratejilere geçeceğiz.

Adres seçim stratejileri: round-robin'den anahtar hash'ine

Havuzun kalbi, bir sonraki acquire isteğinde hangi adresin verileceğine karar veren algoritmadır. Burada tek bir doğru cevap yoktur. Strateji seçimi görev tarafından belirlenir. Dört temel yaklaşımı inceleyip hangisinin ne zaman uygun olduğunu açıklayacağız.

Round-robin: sırayla

Round-robin en basit adil algoritmadır. Adresler bir halka halinde dizilir ve işaretçi her istekte bir ilerler. Tüm halka bitince yeniden başlanır. Artısı – aynı adreslerle mükemmel derecede eşit yük dağılımı. Eksisi – algoritma adresler arasındaki farklılıklara karşı kördür. Hızlı ve yavaş aynı miktarda trafik alır.

Ne zaman kullanılmalı: homojen havuz, oturum gerektirmeyen görevler, tüm adreslerin kalite ve kapasite açısından yaklaşık olarak eşit olduğu durumlar.

Ağırlıklı seçim

Ağırlıklı seçim, her adrese bir ağırlık atanan round-robin'in gelişmiş halidir. Daha yüksek ağırlıklı adres daha fazla trafik alır. Ağırlık, bilinen bant genişliğine göre statik olarak veya canlı metrikler (başarı oranı ve gecikme) temelinde dinamik olarak yeniden hesaplanarak belirlenebilir.

Dinamik ağırlık güçlü bir araçtır. Adres daha sık captcha döndürmeye başladı mı? Ağırlığını düşürürüz, daha az trafik alır ancak tamamen çıkmaz. Metrikler düzelirse ağırlık tekrar yükselir. Bu, karantinaya keskin bir şekilde almaktan daha yumuşak olan kademeli bir kendi kendine düzenlemedir.

Ağırlık için basit bir formül: ağırlık = başarı oranı / normalize edilmiş gecikme. Başarı ne kadar yüksek ve gecikme ne kadar düşükse ağırlık o kadar yüksek olur. Bunu kayan bir pencerede (örneğin son elli istek) yeniden hesaplayın.

Least-connections: en az yüklü olan

Least-connections, şu anda üzerinde en az aktif görev bulunan adresi verir. Bu, görevlerin süreleri çok farklı olduğunda harika çalışır. Round-robin böyle bir durumda uzun süreli görevlerle bir adresi boğarken diğeri boşta kalabilir. Least-connections, verilen istek sayısını değil, gerçek yükü kendiliğinden dengeler.

Uygulama için her adreste bir aktif kiralama sayacı gerekir. Bu sayaç acquire ile artar, release ile azalır. Minimum sayaçlı adres seçilir. Dikkat: bu sayaç paylaşılan bir durumdur ve birden çok işçi varsa ortak bir depoda yaşamalıdır. Buna durum bölümünde tekrar döneceğiz.

Anahtar hash'i: bir hesap, her zaman aynı adres

İşte hesaplarla çalışmak için asıl önemli olan. Anahtar hash'i, adresin rastgele değil, görevin anahtarına bağlı olarak deterministik bir şekilde seçildiği stratejidir. Hesap kimliğini alırız, ondan bir hash hesaplarız, adres sayısına bölümünden kalanı alırız – indeksi elde ederiz. Aynı hesap her zaman aynı indeksi, dolayısıyla aynı adresi verir.

Bu neden sadece kullanışlı değil, aynı zamanda prensip olarak önemlidir? İşte makalenin kilit içgörüsü burada gizli.

Deterministik hash neden dolandırıcılık önleme için rastgelelikten daha önemlidir

Platformların dolandırıcılık önleme sistemleri, kullanıcının davranış profili oluşturur. En güçlü güven sinyallerinden biri, ağ ortamının istikrarıdır. Gerçek bir insan her gün yaklaşık olarak aynı adres kümesinden ağa çıkar. Sağlayıcısı nadiren değişir, coğrafyası istikrarlıdır.

Şimdi bir hesabın her işlemde farklı bir alt ağdan yeni bir adres gösterdiğini düşünün. Sistem için bu imkansız bir davranış gibi görünür: bir insan bir dakikada fiziksel olarak on farklı yerde olamaz. Rastgele adres seçimi, tam da böyle bir kırmızı bayrak üretir.

Deterministik hash sorunu kökünden çözer. Hesap adrese matematiksel olarak, durum saklamadan bağlanır. Uygulama yeniden başlasa ve tüm belleği kaybetse bile, aynı hesap yine aynı adresi hesaplar. Bu kendi kendini iyileştiren bir bağlamadır. Güzel, değil mi?

Tuzak: havuz boyutunun değişmesi

Saf bölme kalanlı hash'in sinsi bir zayıflığı vardır. Adres sayısı değişirse – biri eklendi veya karantinaya alındı – hemen hemen tüm anahtarlar için bölme kalanı değişir. Neredeyse tüm hesaplar aniden yeni adreslere taşınır. Bu tam da kaçınmaya çalıştığımız felakettir.

Çözüm – tutarlı hashleme. Bu teknikte, bir adresin eklenmesi veya çıkarılması, tüm anahtarların değil, yalnızca küçük bir kısmının yeniden atanmasına neden olur. Adresler ve anahtarlar hayali bir halkaya yerleştirilir, anahtar en yakın adrese kadar halkada ilerler. Bir adres kaldırıldığında yalnızca onun anahtarları taşınır, diğerleri yerinde kalır. Tam da canlı bir havuzda adreslerin gelip gittiği yerde sticky bağlama için doğru temel, tutarlı hashlemedir.

Stratejileri birleştirme

Gerçek bir uygulamada stratejiler sıklıkla birleştirilir. Tipik gelişmiş bir senaryo: hesap anahtarlı görevler için tutarlı hash, rezervasyondan sorumlu adres grubu içinde least-connections kullanılır. Oturumsuz veri toplama için ağırlıklı round-robin kullanılır. Havuz birden çok strateji tutabilir ve görev türüne göre uygun olanı seçebilir.

Strateji seçim kontrol listesi

  • Oturum veya hesaba bağlanma kavramı var mı? Anahtar hash'i, tercihen tutarlı hash kullanın.
  • Görevler bağımsız ve homojen mi? Round-robin.
  • Adresler kalite açısından farklı mı? Dinamik ağırlıklı seçim.
  • Görevler süre açısından çok farklı mı? Least-connections.
  • Karışık yük mü? Alt gruplara bölerek birleştirin.

Health-check: pasif ve aktif sağlık kontrolleri

Havuz, adreslerinin durumu hakkında ne kadar bilgi sahibiyse o kadar iyidir. Bu nedenle sağlık kontrol mekanizması, health-check. Birbirini tamamlayan iki yaklaşım vardır: pasif ve aktif. İkisi de gereklidir.

Trafik hatalarından pasif health-check

Pasif kontrol ayrı istekler yapmaz. Adresten geçen gerçek trafiği gözlemler. Her release çağrısı bir sonuç getirir ve havuz bu sonuca göre adresin itibarını günceller. Bu bedavadır – zaten iş için bir istek yaptınız, sadece sonucunu da kaydettiniz.

Pasif gözlemde bozulma sinyali olarak kabul edilenler:

  • Bağlantı hataları: adres yanıt vermiyor, bağlantı kopuyor.
  • Ağ düzeyinde engellemeye özgü yanıtlar.
  • Captcha patlaması – dolaylı ancak adres itibarının düştüğüne dair önemli bir sinyal.
  • Adresin tarihsel normuna göre gecikmede keskin artış.

Pasif yaklaşımın artısı – güncellik ve sıfır ek yük. Eksisi – yalnızca trafik gittikten sonra tepki verir, yani ilk zarar gören istekler kaçınılmazdır. Ayrıca boşta bekleyen adresler hakkında hiçbir şey bilmez.

Aktif health-check probları

Aktif kontrol, havuzun iş trafiğinden bağımsız olarak kendi başına yaptığı ayrı bir probdur. Genellikle, istikrarlı yanıt veren ve adresin çalışabilirliği hakkında fikir veren önceden bilinen bir kontrol kaynağına hafif bir istek yapılır.

Aktif problar, pasifin yapamadığını çözer: boşta bekleyen adresleri ve karantinadaki adresleri dönüşten önce kontrol eder. Adresin karantinadan hizmete dönüp dönmeyeceğine karar veren bariyer tam da aktif probdur.

Kontrol başarısızlığı olarak kabul edilen şey

Başarısızlık tanımı ince bir noktadır. Çok katı olursa rastgele bir dalgalanma yüzünden normal adresleri atarsınız. Çok yumuşak olursa ölü adresler havuzda asılı kalır. Mantıklı bir yaklaşım çok faktörlü bir eşiktir.

  • Tek bir hata başarısızlık değildir. Bu gürültüdür. Ağ doğası gereği güvenilmezdir.
  • Başarısızlık birikmiş bir sinyaldir: örneğin son beş istekten üçü hata veya penceredeki başarı oranının yüzde yetmişin altına düşmesi.
  • Captcha oranı ayrıca ele alınmalıdır. Buradaki eşik daha düşüktür, çünkü captcha adresin itibarıyla ilgili bir sinyaldir, rastgele bir arıza değil.

Hangi aralıklar kullanılmalı

Aktif prob aralıkları, veri güncelliği ile ek yük arasında bir dengedir. Genel yönergeler:

  • Yük altındaki sağlıklı adresleri aktif olarak problamaya gerek yok – pasif trafik onlar adına konuşur.
  • Boşta bekleyen sağlıklı adresler – her otuz-altmış saniyede bir prob, onları hazır tutmak için.
  • Karantinadaki adresler – aşağıda açıklanan bekleme süresi programına göre prob.
  • Tüm adresleri aynı anda problamayın. Probları zamana yayın, rastgele bir kayma ekleyin, böylece senkron dalgalanmalar yaratmazsınız.

Flapping ve histerezis ile nasıl bastırılır

Şimdi en hafife alınan olgulardan biri. Flapping, bir adresin hızla sağlıklı ve hasta durumları arasında gidip gelmesidir. Prob geçti – hizmete döndü. Hemen hata – çıkarıldı. Bir saniye sonra prob yine geçti – geri döndü. Ve bu böyle devam eder. Bu sistemi yorar, metriklerde dalgalanma yaratır ve adresin ne çalışmasına ne de dinlenmesine izin verir.

Çözüm – histerezis. Elektronikten gelen bir terim, duruma girme ve çıkma için farklı eşikler anlamına gelir. Fikir basit: bir adresi hasta kabul etmek için, onu tekrar sağlıklı kabul etmekten daha az sinyal gerekir. Örneğin, üç üst üste hata karantinaya çıkarır, ancak geri dönmek için beş üst üste başarılı prob gerekir. Eşiklerdeki asimetri, küçük dalgalanmaların durumu değiştirmediği bir istikrar bölgesi yaratır.

Flapping'e karşı ikinci araç – durumda minimum bekleme süresi. Karantinaya giren bir adres, prob daha önce geçse bile, orada minimum bir süre geçirmek zorundadır. Bu hızlı salınımları bastırır. Histerezis ve minimum bekleme süresinin birleşimi, sinirli bir sistemi sakin ve öngörülebilir bir sisteme dönüştürür.

Health-check kontrol listesi

  • Her iki kontrol türü de çalışıyor: trafiğe göre pasif ve problarla aktif.
  • Başarısızlık, tek bir hata değil, birikmiş bir sinyal olarak tanımlanmış.
  • Captcha oranı için ayrı, daha hassas bir eşik belirlenmiş.
  • Aktif problara rastgele kayma eklenmiş.
  • Histerezis ayarlanmış: soruna girme eşiği, çıkma eşiğinden daha düşük.
  • Flapping'e karşı durumda minimum bekleme süresi belirlenmiş.

Karantina ve hizmete dönüş: bekleme süresi, limitler ve havuz koruması

Bir adres sorunlu kabul edildiğinde, onu hemen atmak doğru değildir. Çoğu zaman sorun geçicidir. Karantinanın görevi, adrese dinlenme şansı vermek ve ardından iyileşip iyileşmediğini kontrol etmektir. Burada çok ince mühendislik vardır.

Üstel bekleme süresi

Saf karantina, adresi sabit bir süre (örneğin bir dakika) tutar ve geri verir. Ancak adres kalıcı olarak sorunluysa, onu tekrar tekrar geri verir ve her seferinde yeni bir hata dalgası alırsınız. Çözüm – üstel bekleme süresi.

Prensip: karantinaya her tekrar düşüşte bekleme süresi artar. İlk sefer – bir dakika. İkinci sefer – iki dakika. Sonra dört, sekiz, on altı. Makul bir tavana kadar, örneğin bir saat. Adres yeterince uzun süre başarılı çalıştığında, bekleme süresi sayacı başlangıç ​​değerine sıfırlanır.

Bu, iki sorunu aynı anda zarif bir şekilde çözer. Geçici olarak tökezleyen bir adres hızla geri döner. Kalıcı olarak hasta bir adres ise sistemi giderek daha az rahatsız eder ve aslında ölü hale gelir, havuzu sık sık yararsız problarla doldurmaz.

Bekleme süresine rastgele bir dağılım (jitter) ekleyin. Aksi takdirde aynı anda karantinaya giren tüm adresler aynı anda geri döner. Jitter, dönüşleri zamana yayar.

Aynı anda karantinaya alınan adreslerin limiti

İşte en sık unutulan kritik bir koruma. Ya adreslerin yarısını aynı anda etkileyen bir olay olursa? Örneğin, hedef platform kontrolleri sıkılaştırdı. Havuz dürüstçe adresleri birer birer karantinaya almaya başlar. Ve bir sınır koymazsanız, kendinizi neredeyse hiç adresin kalmadığı bir durumda bulursunuz.

Bu nedenle kural: Aynı anda karantinada olan adreslerin oranı için katı bir limit. Örneğin, havuzun yüzde otuzundan fazla olmamalı. Limite ulaşıldığında, karantinaya yeni adaylar alınmaz, yalnızca ağırlıkları düşürülür. Mantık şu: hiç kaynağınız kalmamasındansa, hafif bozulmuş adreslerle çalışmak daha iyidir.

Havuzun tamamının karantinaya girmesi durumuna karşı koruma

Bu, önceki düşüncenin uç noktaya taşınmış halidir. Bir düşünün: kontrol kaynağına yapılan probun kendisi bozuldu. Kaynak çöktü veya yanıtını değiştirdi. Havuz tüm adreslerin ölü olduğuna karar verir ve tüm havuzu karantinaya alır. Uygulama durur, oysa adresler aslında gayet iyi durumdadır.

Koruma mekanizmaları:

  • Hizmette garantili asgari. Biçimsel olarak kontrolü geçmemiş olsalar bile, her zaman en az bir-iki adresi erişilebilir tutun. Şüphe altında çalışsınlar, sistem durmasındansa iyidir.
  • Korelasyon analizi. Tüm adreslerde aynı anda hatalar başladıysa – bu şüphelidir. Ortak bir faktör bozulmuş olabilir: prob, sizin tarafınızdaki ağ, hedef kaynak. Havuz, toplu bir başarısızlığı tanıyabilmeli ve tüm adresleri birden çıkarmamalıdır.
  • Ayrı kontrol kaynakları. Aktif probu tek bir kontrol noktasına bağlamayın. Bu, tek hata noktanız haline gelirse, yanlış pozitifler tüm havuzu çökertebilir.

Yarı açık durum üzerinden hizmete dönüş

Karantinadan dönüş anlık değildir. İyi bir uygulama – yarı açık durum, kesici deseninden (circuit breaker) gelen bir fikir. Karantinadaki bir adres hemen tam trafik almaz. Önce ona küçük bir pay, deneme amaçlı bir damla verilir. Deneme istekleri başarılıysa, adres tam ağırlığına ulaşana kadar pay kademeli olarak artırılır. Denemeler başarısız olursa – artırılmış bekleme süresiyle karantinaya geri dönülür.

Böyle bir kademeli ramp-up, henüz iyileşmemiş bir adrese erken bir trafik patlaması yaşanmasını önler.

Karantina kontrol listesi

  • Bekleme süresi, tekrarlanan karantinalarda üstel olarak artar.
  • Senkron dönüşlere karşı bekleme süresine jitter eklenmiştir.
  • Aynı anda karantinadaki adreslerin oranı için bir limit vardır.
  • Her koşulda hizmette minimum adres garantisi vardır.
  • Toplu başarısızlık, ortak bir sorunun işareti olarak tanınabilir.
  • Dönüş, kademeli trafik artışıyla yarı açık durum üzerinden yapılır.

Durum depolama: süreç belleği ve ortak depo

Tartıştığımız tüm mantık – yük sayaçları, itibar, karantina durumları – bunlar bir yerde yaşayan verilerdir. Tam olarak nerede olduğu, belirleyici bir mimari karardır. Bu, tek bir süreciniz mi yoksa birden çok süreciniz mi olduğuna bağlıdır.

Süreç belleği: basit ama yalnız

Uygulama tek bir süreçte çalışıyorsa, havuz durumunu bellekte tutmak en kolayıdır. Sıradan veri yapıları: adres sözlüğü, sayaçlar ve zamanlayıcılar. Hızlı, bağımlılık yok, ağ gecikmesi yok.

Eksileri açık. Yeniden başlatma – tüm geçmiş kaybolur, havuz sıfırdan başlar, kimin karantinada olduğunu unutur. Ve asıl önemlisi, birden fazla süreç olduğunda çalışmaz. Her sürecin kendi izole dünya görüşü olacaktır. Biri bir adresi karantinaya alır, diğeri bundan habersizdir ve onu yüklemeye devam eder.

Ortak depo: Redis ve Memcached

Birden fazla işçiniz olduğunda – ve gerçek yük altında neredeyse her zaman birden fazladır – durum ortak hale gelmelidir. İşte burada Redis veya Memcached gibi hızlı depolar sahneye çıkar. Ayrı bir hizmet olarak yaşarlar, tüm işçiler onlara erişir ve havuz durumunun tek ve tutarlı bir resmini sağlarlar.

Redis çoğu durumda Memcached'e tercih edilir, çünkü atomik işlemler, sıralanmış kümeler ve hash'ler gibi veri yapıları, atomik artırma sayaçları ve küçük komut dosyalarını atomik olarak çalıştırma yeteneği sunar. Bunların hepsi işimize yarayacak.

Birden çok işçi varken yarış koşulları

Ortak depo görünürlük sorununu çözer, ancak yenisini doğurur – yarış koşulları. Klasik least-connections senaryosu: iki işçi aynı anda sayaçları okur, ikisi de X adresinin en az yüklü olduğunu görür, ikisi de onu seçer, ikisi de sayacı artırır. Sonuçta adres iki kat yük alır, oysa algoritma bundan kaçınmalıydı.

Çözümler:

  • Atomik işlemler. Redis'te sayaç artırma doğası gereği atomiktir. Bunu ayrı ayrı okuma, artırma ve yazma yerine kullanın.
  • Komut dosyaları. Birden çok değeri okuyup karar vermeyi gerektiren karmaşık seçim mantığını, depo tarafında tek bir atomik komut dosyası olarak tasarlayın. Bu sayede okuma ve yazma arasına kimse giremez.
  • Dağıtık kilitler. Kritik bölümler için kısa süreli kilit alınabilir. Ancak dikkatli olun – kilitler performansı düşürür ve kendileri sorun kaynağı olabilir. Atomik işlemler neredeyse her zaman daha iyidir.

TTL kayıtları

Ortak depodaki en önemli araç – TTL, bir kaydın otomatik olarak kaybolduğu yaşam süresi. Çöp birikmesini ve durumların takılıp kalmasını önler.

TTL nerede kullanılmalı:

  • Anahtarın adrese sticky bağlanması. İş oturumunu hatırlayın? Bağlanma kaydının TTL'si, oturumun süresidir. TTL'yi on beş dakika olarak ayarlayın – on beş dakika hareketsizlikten sonra bağlanma kendiliğinden kaybolur, hesap bir sonraki erişimde taze bir bağlanma alabilir. Oturumun yaşam süresini ifade etmenin temiz ve zarif bir yoludur.
  • Aktif kiralama sayacı. Bir işçi release çağırmadan düşerse, sayaç sonsuza kadar yüksek kalma riski taşır. TTL veya periyodik mutabakat buna karşı korur. Genellikle kiralama, görevin maksimum süresinden biraz daha büyük bir TTL ile bir kayıt olarak tasarlanır, böylece düşen bir işçi adresi sonsuza kadar meşgul tutmaz.
  • Karantina durumu. Bekleme süresinin kendisi doğal olarak TTL ile ifade edilir: karantina kaydı, bekleme süresi kadar yaşar ve süresi dolduğunda kaybolur, dönüş yolunu açar.

Karma yaklaşım

Uygulamada sıklıkla bir karma yaklaşım kullanılır. Sık okunan sıcak veriler, işçinin yerel belleğinde kısa bir süre için önbelleğe alınır, ancak doğruluk kaynağı ortak depo olmaya devam eder. Bu, Redis'e yapılan çağrıların sayısını azaltır, ancak senkronizasyon bozukluğuna karşı dikkatli olmayı gerektirir. İyi bir uzlaşma, anlık doğruluk gerektirmeyen metrikler için çok kısa (örneğin bir-iki saniye) TTL'li yerel bir önbellektir.

Gözlemlenebilirlik: her adres için metrikler ve kötü IP'yi kötü siteden ayırt etme

Ölçmediğiniz şeyi yönetemezsiniz. Gözlemlenebilirlik, havuzu kara bir kutudan, her adresin sağlığını gördüğünüz ve sorunların nedenlerini anladığınız şeffaf bir sisteme dönüştürür.

Her adres için metrikler

Kayan bir pencerede her adres için tutulması gereken minimum set:

  • Başarı oranı. Başarılı tamamlamaların toplam görevlere oranı. En önemli bütünleşik sağlık göstergesi.
  • Gecikme. Sadece ortalama değil, aynı zamanda yüzdelik dilimleri de tutun. Medyan ve örneğin doksan beşinci yüzdelik, ortalama hakkında kuyruklardan çok daha fazlasını anlatır; ortalama aykırı değerlerle kolayca bozulabilir.
  • Captcha oranı. Ayrı ve çok anlamlı bir metrik. Bir adresteki captcha oranındaki artış, genellikle doğrudan hatalar artmaya başlamadan önce, itibar düşüşünün erken bir sinyalidir.
  • Aktif kiralama sayısı. Mevcut yük, least-connections için ve dağılımı anlamak için gereklidir.
  • Karantina geçmişi. Adresin kaç kez ve ne kadar süreyle karantinaya alındığı. Kronik ihlalciler hemen görülür.

Havuz geneli metrikler

  • Her durumdaki adreslerin oranı: kaç sağlıklı, bozulmuş, karantinada, ölü.
  • Toplam verim ve toplam başarı oranı.
  • Zaman içinde karantinaya girme sıklığı – bir artış olay olduğunu gösterir.
  • Karantina limitinin doluluk oranı – limite yaklaşmak endişe verici bir işarettir.

Kötü IP'yi kötü siteden nasıl ayırt edilir

İşte olgun bir sistemi saf olandan ayıran soru. Hatalar başladı – ama kim suçlu? Sorunlu adres mi yoksa hedef platformun kendisi mi geçici olarak herkes için erişilemez? Bunu karıştırırsanız, başka bir sunucunun günahları yüzünden sağlıklı adresleri karantinaya almaya başlarsınız.

Teşhisleri ayırma yöntemi – korelasyon analizi:

  • Bir adreste sorun. Hatalar ve captcha'lar bir veya birkaç adreste yoğunlaşmışsa, diğerleri normal çalışıyorsa – adres suçludur. Karantinaya alın.
  • Belirli bir platforma tüm adreslerde sorun. Belirli bir hedef platforma tüm adreslerde başarı oranı aniden düştüyse, ancak diğerlerinde her şey iyiyse – suçlu havuz değil, bu platformdur. Adresleri karantinaya almak anlamsız ve zararlıdır.
  • Tüm platformlara tüm adreslerde sorun. Muhtemelen sorun sizin tarafınızdadır: ağ, altyapı, prob sisteminin kendisi. Burada da adresleri suçlayamazsınız.

Pratik sonuç: Metrikler sadece adrese göre değil, adres-platform çiftine göre de kesilmelidir. O zaman başarı matrisi, hangi satırın tamamen kırmızı olduğunu (adres suçlu) ve hangi sütunun tamamen kırmızı olduğunu (platform suçlu) hemen gösterir. Bu basit iki boyutlu gösterim, saatlerce süren hata ayıklamayı kurtarır ve havuzu boş yere kendi kendini yok etmekten korur.

Loglar ve izleme

Toplanmış metriklerin yanı sıra, havuzun kararlarını loglamak faydalıdır: bu adres neden seçildi, neden karantinaya alındı. Bir şeyler ters gittiğinde, bu karar izleri can simidiniz olacak. Her isteği detaylıca loglamayın – boğulursunuz. Durum geçişlerini ve alışılmadık kararları loglayın.

Pratik: Python ve Node.js'de havuz iskeleti

Teoriden koda geçelim. İki popüler platformda uygulamanın anahtar parçalarını inceleyelim. Bunlar tam iskeletlerdir, projenizin özelliklerini ekleyeceğiniz çerçevelerdir. Ana fikirlerin netliği için ayrıntıları atlayacağız: acquire ve release arayüzü, adres seçimi ve sonucun kaydedilmesi.

Arayüz: acquire ve release

Sözleşmeyi belirleyelim. acquire yöntemi, isteğe bağlı bir anahtar alır – örneğin sticky bağlama için hesap kimliği – ve bir adres döndürür. release yöntemi, adresi ve görevin sonucunu alır. Sonuç en az iki durumla tanımlanır: başarılı mı, captcha veya engelleme belirtisiyle karşılaşıldı mı.

Python iskeleti

Python'da basitleştirilmiş bir havuza bakalım. Netlik açısından mantığı bellekte tutuyoruz, ancak ortak deponun nereye bağlanacağını belirtiyoruz.

Veri yapısının temel öğeleri: anahtarın adres olduğu bir sözlük, değer ise itibar alanları, aktif kiralama sayısı, karantinadan çıkış zaman damgası ve mevcut bekleme süresini içeren bir durum nesnesidir. Ayrıca anahtar-adres sticky bağlamalarının bir tablosunu tutuyoruz.

Python benzeri bir dilde acquire yönteminin sözde kodu şöyle görünür. Önce anahtar var mı kontrol edilir. Anahtar belirtilmişse ve onun için canlı bir bağlanma varsa ve bağlanan adres sağlıklıysa – bağlanmanın TTL'sini uzatarak onu döndürürüz. Bağlanma yoksa – sağlıklı adresler arasından anahtardan tutarlı hash ile bir adres seçeriz, bağlanmayı TTL ile kaydederiz, adresi döndürürüz. Hiç anahtar yoksa – oturumsuz görevler için strateji uygularız, örneğin sağlıklı adresler arasından ağırlıklı seçim. Tüm durumlarda seçilen adresin aktif kiralama sayacını artırırız.

release sözde kodu: aktif kiralama sayacını azaltır. Sonuca göre itibarın kayan penceresini güncelleriz – başarı veya başarısızlık ekleriz, ayrıca captcha işaretini de dikkate alırız. Birikmiş sinyaller, histerezis dikkate alınarak başarısızlık eşiğini geçerse – adresi karantinaya alırız: durumu işaretleriz, bekleme süresini temel süre çarpı 2 üzeri tekrar sayısı (tavanla sınırlı) olarak hesaplarız, jitter ekleriz, TTL veya dönüş zaman damgası belirleriz. Sonuç iyiyse ve adres uzun süredir istikrarlıysa – karantina tekrar sayacını sıfırlarız.

Ayrı bir arka plan döngüsü, belirli bir aralıkta bekleme süresi dolan karantinadaki adresleri tarar ve aktif bir prob başlatır. Prob histerezis dikkate alınarak gereken sayıda başarılı olursa – adresi düşük ağırlıklı yarı açık duruma, ardından kademeli olarak sağlıklı duruma geçirir. Başarısız olursa – artırılmış bekleme süresiyle karantinayı uzatır.

Python uygulaması için önemli pratik ayrıntılar: çok sayıda paralel göreviniz varsa asenkron kullanın, paylaşılan yapılara erişimi uygun senkronizasyonla sarın ve birden çok sürece geçerken iç sözlükleri Redis'e yapılan atomik komutlar ve komut dosyalarıyla değiştirin. Aktif kiralama sayacı atomik artırma için idealdir, anahtar-adres bağlanması TTL'li bir kayıt için uygundur, duruma göre adres kümelerini sıralanmış kümelerde tutmak uygundur; burada adresin ağırlığı onun puanıdır.

Node.js iskeleti

Node.js'de asenkron model doğaldır ve havuz genellikle acquire ve release asenkron yöntemlerine sahip, promise döndüren bir sınıf olarak tasarlanır. Fikir aynıdır, deyimler değişir.

Durum yapısı – adreslerin nesne sözlüğü, değer ise sonuçların dairesel tamponu olarak itibar, aktif kiralama sayacı ve karantina alanlarını içerir. Birden çok işçi için – ve Node'da bu genellikle bir süreç kümesidir – durum yine Redis'e taşınır, çünkü her süreç izoledir.

Node'da acquire yöntemi: depo üzerinden sticky bağlanmayı asenkron olarak kontrol ederiz, canlı ve sağlıklıysa – döndürür ve TTL'yi uzatırız. Aksi halde adres seçeriz – anahtar için tutarlı hash, oturumsuz görev için ağırlıklı. Kiralama sayacını atomik olarak artırırız. Adresi döndürürüz.

Node'da release yöntemi: sayacı atomik olarak azaltırız. Sonucu itibar penceresine yazarız. Histerezisli eşikleri kontrol ederiz ve başarısızlık durumunda karantina koyarız – üstel bekleme süresi ve jitter ile, aynı anda karantinadaki toplam adres sayısı limitine uyarak – limit aşılırsa karantina yerine ağırlığı düşürürüz.

Node'da arka plan kontrolü, süresi dolmuş adresleri seçen ve aktif probları zamana yayan periyodik bir zamanlayıcıyla uygulanır. Başarılı problar, adım adım ağırlık ekleyerek adresi kademeli olarak geri getirir.

Her iki platform için ortak tavsiye: ilk seferde mükemmel yapmaya çalışmayın. Round-robin artı pasif health-check artı bellekte basit karantina ile başlayın. acquire ve release arayüzünün iş mantığınız için uygun olduğundan emin olun. Ardından sırayla hash ile sticky, aktif problar, ortak depo, limitler ve gözlemlenebilirlik ekleyin. Her katmanı gerçek yük altında olgunlaştırın.

Uygulama mini kontrol listesi

  • Arayüz, isteğe bağlı anahtarla acquire ve sonuçla release'ye indirgenmiştir.
  • Durum karmaşıklığının tümü havuzun içinde gizlidir, iş kodu bunu bilmez.
  • Sticky, deterministik, tercihen tutarlı hash ile uygulanmıştır.
  • Sayaçlar ve bağlanmalar birden çok işçi varken atomiktir.
  • Karantina ve boşta bekleyen adresler için arka plan aktif prob döngüsü vardır.
  • Her release'de metrikler yazılır.

Tipik hatalar: yapılmaması gerekenler

Teori öğrenildi, iskelet inşa edildi. Şimdi sürekli basılan tırmıklara göz atalım. Bu hataları bilmek size haftalarca hata ayıklama süresi kazandıracak.

Farklı platformlar için ortak havuz

Büyük bir havuz oluşturup tüm hedef platformlara trafiği oradan geçirmek cazip gelebilir. Bunu düşünmeden yapmayın. Bir adresin farklı platformlardaki itibarı farklıdır. Bir platformda harika çalışan bir adres, başka bir platformda engellenmiş olabilir. Hepsini tek bir havuzda ve tek bir istatistikte karıştırırsanız, bulanık bir resim elde edersiniz; bir görev için iyi olan adres, başka bir görevle ilgili sorunlar nedeniyle haksız yere cezalandırılır.

Doğru olan, itibarı adres-platform çifti bazında tutmak ve havuzları veya alt grupları farklı yönler için mantıksal olarak ayırmaktır. Böylece karantina kararı hedefe yönelik ve adil olur.

Bir adres için görev limitinin olmaması

Sağlıklı bir adresin bile bir sınırı vardır. Havuz popüler bir adrese yüzlerce eşzamanlı görev yüklerse, kendiniz bir anomali yaratırsınız: tek bir noktadan doğal olmayan yüksek aktivite yoğunluğu. Bu hem adresi aşırı yükler hem de platform için şüpheli görünür.

Bir adreste eşzamanlı kiralama sayısı için bir tavan belirleyin. Tavana ulaşıldığında adres geçici olarak adaylardan çıkarılır, trafik diğerlerine gider. Bu basit kısıtlama, birçok belayı önler.

Oturumun ortasında rotasyon

Hesaplarla çalışırken affedilmez bir günah. Hesap bir adresten işleme başladı, ancak karantina veya havuz boyutunun değişmesi nedeniyle oturumun ortasında aniden başka bir adrese geçti. Platform açısından kullanıcı ışınlanmış oldu. Bu, otomasyonun en belirgin işaretlerinden biridir.

Koruma: aktif bir oturum devam ederken, anahtarın adrese bağlanması dokunulmaz olmalıdır, adres biraz bozulmuş olsa bile. Bağlanmayı yalnızca oturum sınırlarında değiştirin – doğal sona ermesinde veya TTL'sinin dolmasında. Ve eğer adres tamamen öldüyse ve başka çare yoksa – oturumu yarı yolda başka bir adrese atmaktansa, düzgün bir şekilde sonlandırmak daha iyidir.

Diğer sık hatalar

  • Tek bir hatayı ölüm cezası olarak görmek. Tek bir rastgele arıza yüzünden adresi karantinaya almak. Ağ güvenilmezdir, tek bir hata normaldir. Yalnızca birikmiş sinyal önemlidir.
  • Histerezis eksikliği. Flapping ve dalgalanmaya yol açar, daha önce bahsetmiştik.
  • Üstel yerine sabit bekleme süresi. Kalıcı olarak hasta bir adres sürekli geri döner ve istatistikleri bozar.
  • Karantina limiti yok. Bir olay tüm havuzu karantinaya alabilir ve sistemi durdurabilir.
  • Senkron problar. Tüm adresler aynı anda problanır ve yük dalgalanmaları yaratır.
  • Birden çok işçi varken yalnızca bellekte durum. Her süreç kendi gerçekliğinde yaşar, koordinasyon yoktur.
  • Takılı kalan kiralamalar. Bir arıza nedeniyle release çağrılmaz, sayaç yüksek kalır, adres sonsuza kadar meşgul sayılır. Kiralama için TTL ile tedavi edilir.
  • Tek bir kontrol kaynağına körü körüne güvenmek. O düşerse, tüm havuz kendini ölü sayar.

Uygulama için araçlar ve kaynaklar

Pratik cephaneliği toplayalım. Havuzu inşa ederken gerçekten işe yarayacak olanlar.

Durum depoları

  • Redis. Ortak durum için ana seçim. Atomik sayaçlar, ağırlıklar ve durumlar için sıralanmış kümeler, adres meta verileri için hash'ler, kullanıma hazır TTL, karmaşık atomik mantık için komut dosyaları. Görevimiz için neredeyse ideal.
  • Memcached. Daha basit ve hafif, yalnızca temel sayaçlı önbellekler gerekiyorsa uygun olabilir, ancak zengin yapılar ve karmaşık işlemler için Redis'in gerisinde kalır.

Ekosistemlere göre kütüphaneler ve yaklaşımlar

  • Python. Paralel görevler için asenkron yığın, Redis istemcisi asenkronite ve komut dosyalarını destekler, hazır tutarlı hashleme uygulamaları ve yarı açık durum için kesici deseni (circuit breaker) mevcuttur.
  • Node.js. Deyimsel asenkron sınıflar, olgun Redis istemcileri, ortak durumun zorunlu olduğu süreç kümesi modeli, tutarlı hashleme kütüphaneleri ve kesici uygulamaları mevcuttur.

Gözlemlenebilirlik

  • Zaman serisi metrik sistemi. Adreslere ve adres-platform çiftlerine göre başarı oranı, gecikme ve captcha göstergelerini depolamak için.
  • Gösterge panelleri. Havuz durum dağılımının, adres-platform matrisinin, karantina sıklığının görselleştirilmesi. Bir bakışta kötü adresi kötü platformdan ayırt etmeyi sağlar.
  • Uyarılar. Karantina limitine yaklaşıldığında, toplu başarısızlıkta, toplam başarı oranı eşiğin altına düştüğünde bildirim.

Kendiniz ne inşa etmelisiniz?

Büyük olasılıkla, tüm nüanslarınızı kapsayan hazır bir evrensel havuz kütüphanesi bulamazsınız – oturumların iş mantığı çok spesifiktir. Bu nedenle havuzun çekirdeği genellikle kendiniz yazılır, listelenen yapı taşlarına dayanarak: depo, hashleme, metrikler, kesici deseni. İyi haber şu ki, dikkatli bir acquire ve release arayüzü ile bu çekirdek kompakt olur ve projeler arasında yeniden kullanılabilir.

Kullanım senaryoları ve sonuçlar

Makaledeki ilkelerin pratikte nasıl çalıştığını gösteren birkaç genelleştirilmiş senaryoya bakalım. Rakamlar açıklayıcıdır, ancak oranlar tipik dinamikleri yansıtır.

Senaryo bir: oturumsuz genel veri toplama

Görev – bağımsız sayfalardan genel bilgileri toplu olarak toplamak. Dosyadan saf rastgele seçimle başlandı. Başarı oranı yüzde yetmiş civarında dalgalanıyordu, çünkü ölü adresler canlılarla eşit miktarda trafik alıyordu.

Ağırlıklı seçim ve pasif health-check ile bir havuz uygulandı. Adres ağırlığı, kayan bir başarı oranı penceresine göre yeniden hesaplanıyordu. Ölü adresler hızla ağırlık kaybetti ve neredeyse hiç görev almamaya başladı. Boşta bekleyen adresler için aktif problar ve üstel karantina eklendi.

Sonuç: başarı oranı yaklaşık yüzde yetmişten yüzde doksanın üzerine çıktı. Ölü adreslere yapılan yararsız denemelerin sayısı katlanarak düştü. Senaryonun ana çıkarımı – oturum olmasa bile, yalnızca itibara dayalı uyarlanabilir yönlendirme, verimlilikte gözle görülür bir sıçrama sağlar.

Senaryo iki: hesaplarla çalışma ve sticky-oturumlar

Görev – her birinin ağ ortamının istikrarının kritik olduğu çok sayıda hesabın sürdürülebilir şekilde çalışması. Başlangıçta rastgele adres seçimi kullanılıyordu ve hesaplar sürekli alt ağlar arasında zıplıyordu. Sonuç – doğrulama istekleri ve captcha oranında patlama.

Hesap kimliğinden tutarlı hash ile deterministik bağlamaya geçildi, bağlanmalar Redis'te saklandı ve TTL iş oturumunun süresine eşitlendi. Kesin bir kural getirildi: oturum ortasında rotasyon yok. Bağlanma yalnızca sınırlarda değişiyordu.

Sonuç: hesaplardaki captcha oranı belirgin şekilde düştü, doğrulama isteklerinin sayısı azaldı, hesapların davranışı platformlar için istikrarlı ve doğal görünmeye başladı. Senaryonun içgörüsü – dolandırıcılık önleme için ağ ortamının öngörülebilirliği, herhangi bir karmaşık rotasyondan daha değerlidir.

Senaryo üç: olay ve karantina çığına karşı koruma

Çalışan bir sistem sırasında hedef platform aniden kontrolleri sıkılaştırdı. Tüm adreslerde aynı anda captcha'lar yağmaya başladı. Karantina limiti olmayan havuz, bu senaryonun ilk sürümünde, dakikalar içinde neredeyse tüm havuzu karantinaya aldı – sistem fiilen durdu.

İyileştirme sonrası üç şey eklendi: karantinadaki adreslerin oranı için limit, toplu başarısızlığın ortak bir sorunun işareti olarak tanınması ve hizmette garantili minimum adres. Olay tekrarlandığında havuz, başarısızlıkların belirli bir platformdaki tüm adreslerde aynı anda korele olduğunu fark etti, suçun kendisinde olmadığını anladı ve çığa izin vermedi. Sadece ağırlıkları düşürdü ve durum normale dönene kadar minimum kaynaklarla çalışmaya devam etti.

Sonuç: tam durma yerine sistem, düşüşle değil, bozulmayla olayı atlattı. İçgörü – dayanıklılık, en iyi günde değil, en kötü günde nasıl davrandığıyla ölçülür.

Senaryo dört: kötü adres ile kötü platform teşhisi

Ekip haftalarca periyodik olarak sağlıklı adresleri karantinaya alıyordu ve nedenini anlamıyordu. Metrikler yalnızca adreslere göre tutuluyordu, platformlara göre kesilmiyordu. İki boyutlu adres-platform matrisi eklendiğinde resim anında netleşti: sorun adreslerde değil, tüm adresler için aynı anda hata dalgaları veren kaprisli bir platformdaydı.

Mantık, bir platform sütununda korele olan başarısızlıkların adresleri cezalandırmaması için ayarlandı. Sonuç – yanlış karantina sayısı neredeyse sıfıra düştü ve havuzun faydalı kapasitesi tek bir yeni adres eklenmeden arttı. İçgörü – doğru metrik dilimlemesi bazen herhangi bir algoritmadan daha değerlidir.

Sık sorulan sorular

Yalnızca birkaç adres varsa havuza gerek var mı?

Bir avuç adres bile olsa, herhangi bir yük veya oturum kavramı ortaya çıktığında havuz kendini amorti eder. Pasif health-check ve basit karantina, ölü bir adrese sürekli vurmanızı önler. Sticky bağlama hesapların istikrarını korur. Tam tutarlı hash ve birkaç adres için ortak depo gereksiz olabilir, ancak bellekte acquire ve release arayüzüne sahip temel bir havuz neredeyse her zaman kurmaya değer.

Sticky oturum süresi nasıl seçilir?

Teknik hususlardan değil, iş anlamından yola çıkın. Kendinize sorun: bir dizi eylemin ne kadar süreyle tek bir sürekli ziyaret olarak algılanması gerekiyor? Kısa senaryolar için dakikalar, bir profil altında etkinlik dönemi için onlarca dakika veya saatler. Bu süreyi bağlanmanın TTL'si olarak ayarlayın ve aktif oturum sırasında her erişimde uzatın, böylece iş yarıda kesilmesin.

Ya bağlanan adres oturumun ortasında ölürse?

Bu en tatsız durumdur. Genel kural – oturum ortasında rotasyon yapmayın. Adres bozulmuş ancak hala canlıysa, oturum sonuna kadar onunla devam edin. Tamamen öldüyse, oturumu başka bir adrese atıp ışınlanma efekti yaratmaktansa, oturumu düzgün bir şekilde sonlandırmak veya duraklatmak tercih edilir. İş mantığını, oturumu sonlandırmanın onu taşımaktan daha az acı verici olacağı şekilde tasarlayın.

Aktif problar ne sıklıkla yapılmalı?

Yük altındaki sağlıklı adresleri problamayın – pasif kontrol sayesinde canlı trafik onlar adına konuşur. Boşta bekleyen sağlıklı adresleri onlarca saniyede bir kontrol edin, hazır tutmak için. Karantinadaki adresleri üstel bekleme süresi programına göre problayın. Probları jitter ile zamana yaydığınızdan emin olun, böylece senkron aktivite dalgalanmaları yaratmazsınız.

Redis zorunlu mu, yoksa bellek yeterli mi?

Kesinlikle tek bir süreciniz varsa ve durumu yeniden başlatmada kaybetmeyi kabul ediyorsanız, başlangıçta bellek kabul edilebilir. İkinci bir işçi ortaya çıktığında ortak depo neredeyse zorunlu hale gelir, aksi halde süreçler koordinasyon olmadan farklı gerçekliklerde yaşar. Redis, atomik işlemleri, veri yapıları ve TTL'si sayesinde en uygun seçimdir. Bellekle başlayın, ancak depo soyutlamasını oluşturun, böylece Redis'e geçiş kodun yarısını yeniden yazmayı gerektirmez.

Adres sorununu hedef platform sorunundan nasıl ayırt ederim?

Metrikleri yalnızca adrese göre değil, adres-platform çiftine göre tutun. Hatalar bir adreste tüm platformlarda yoğunlaşmışsa – adres suçludur. Belirli bir platformda tüm adreslerde hata varsa – platform suçludur ve adresler cezalandırılamaz. Tüm adreslerde tüm platformlarda hata varsa – sorunu kendi tarafınızda arayın: ağ, altyapı, prob sisteminin kendisi. Bu iki boyutlu dilimleme, doğru teşhis koymanın en güvenilir yoludur.

Ya neredeyse tüm havuz karantinaya girerse?

Doğru koruma ile bu imkansız olmalıdır. Aynı anda karantinadaki adreslerin oranı için bir limit belirleyin. Her koşulda hizmette minimum adres garanti edin. Havuza, toplu eşzamanlı başarısızlığı adreslerin suçu değil, ortak bir sorunun işareti olarak tanımayı öğretin. Limite ulaşıldığında karantinaya almaktan ağırlıkları düşürmeye geçin – tamamen durmaktansa, hafif bozulmuş kaynaklarla çalışmak daha iyidir.

Varsayılan olarak hangi seçim stratejisini kullanmalıyım?

Oturumlarınız yoksa ve adresler homojense round-robin ile başlayın. Adresler farklı kalitedeyse metrik bazlı dinamik ağırlıklı seçim. Görevler süre açısından çok farklıysa least-connections. Hesaplara veya oturumlara bağlanma varsa anahtara göre tutarlı hash – ve bu tartışılmaz, çünkü hesaplarla çalışmanın istikrarını belirler. Karmaşık sistemlerde stratejileri görev türlerine göre birleştirin.

Captcha'ları metriklerde ayrıca hesaba katmak gerekli mi?

Evet, kesinlikle ve sıradan hatalardan daha hassas bir eşikle. Captcha, adres itibarının düştüğünün erken ve doğru bir sinyalidir, genellikle doğrudan retlerden önce gelir. Captcha'ları genel hatalarla karıştırırsanız, bu öncü göstergeyi kaybedersiniz. Her adres için ayrı bir captcha oranı metriği, sorunlu adresin henüz açıkça arızalanmaya başlamadan ağırlığını düşürmenizi sağlar.

Bir işçi düştüğünde takılı kalan kiralamalardan nasıl kaçınırım?

Yalnızca açık release çağrısına güvenmeyin. Kiralamayı, görevin izin verilen maksimum süresinden biraz daha büyük bir TTL ile bir kayıt olarak tasarlayın. İşçi düşüp adresi iade etmezse, kaydın süresi dolar ve aktif yük sayacı düzelir. Ek olarak, sayaçları periyodik olarak gerçekle mutabık kılabilirsiniz. Bu, takılı kalan kiralamalar nedeniyle havuzun kapasitesinin yavaşça sızmasını önler.

Sonuç ve sonraki adımlar

Uzun bir yol kat ettik. Metin dosyasındaki adres listesinin gerçek yük altında neden çöktüğünün acı gerçeğinden, uygulama içinde tam bir mühendislik adres yönetimi sistemine kadar. Ana hatları toparlayalım.

Havuz, bir liste değil, basit bir acquire ve release arayüzünün arkasına gizlenmiş davranışı olan bir nesnedir. Adres seçim stratejisi görev tarafından belirlenir: homojen için round-robin, farklı kaliteler için ağırlıklı seçim, farklı sürelerdeki görevler için least-connections ve – hesaplarla çalışmak için kritik olarak – anahtara göre deterministik, tercihen tutarlı hash. Dolandırıcılık önleme sistemlerinden güven kazandıran, karmaşık rastgelelik değil, ağ ortamının öngörülebilirliğidir.

Adres sağlığı iki ayağa dayanır: gerçek trafik üzerinden pasif kontrol ve aktif problar. Başarısızlık, tek bir hata değil, birikmiş bir sinyal olarak tanımlanır ve histerezis ile minimum bekleme süresi flapping'i bastırır. Karantina, jitter ile üstel bekleme süresine dayanır, kesinlikle çıkarılan adreslerin oranı için bir limit ile sınırlandırılmıştır ve tüm havuzun yedek kulübesine düşme felaketinden korunur. Durum, birden çok işçi varken atomik işlemler ve TTL ile ortak bir depoda yaşar. Adres-platform çifti bazında gözlemlenebilirlik, kötü adresi kötü platformdan ayırt etmenizi sağlar – bu beceri haftalar kazandırır.

Şimdi ne yapmalı? Adım adım somut bir uygulama planı öneriyorum.

  1. Mevcut adres çalışmasını, içini henüz değiştirmeden acquire ve release arayüzüne sarın. Bu zemini hazırlayacaktır.
  2. Bellekte pasif health-check ve basit karantina ekleyin. Burada bile istikrar artışını hissedeceksiniz.
  3. Gerekli seçim stratejisini ekleyin. Hesaplarla çalışıyorsanız, hemen anahtar hash ile sticky'yi ekleyin.
  4. Aktif probları ve koruyucu limitlerle üstel bekleme süresini bağlayın.
  5. İkinci işçi çıkar çıkmaz durumu ortak depoya taşıyın. Atomiklik ve TTL'yi ekleyin.
  6. Metrikleri ve gösterge panellerini ayarlayın, kesinlikle adres-platform dilimlemesiyle.
  7. Histerezis ve eşikleri gerçek verilerinize göre ince ayar yapın – burada evrensel sayılar yok, yalnızca sizin gözlemleriniz var.

Her şeyi birden inşa etmeye çalışmayın. Her katmanı yük altında olgunlaştırın, metrikleri alın, sonuçlar çıkarın ve devam edin. Olgun bir proxy havuzu, tek seferlik bir inşa değil, görevlerinizin büyümesiyle birlikte ayarladığınız canlı bir sistemdir. Ancak bu kılavuzdaki ilk adımlar bile, kırılgan adres listenizi uygulamanızın güvenilir bir temeline dönüştürecektir. Ve itiraf edin, bu harcanan çabaya değer.