Giriş
Uzun yıllardır IPTV ve medya yansıtma (mirror) sistemleri üzerinde çalışıyorum. Bunların her biri aslında birer veri çekme (scraping) motoru: bir kaynaktan akış ve kanal bilgisini çekip kendi arayüzünüzde sunmak. Yeni başlayanlar “veri çekmek kolay, curl ile at” der. Deneyim der ki; asıl zorluk veriyi çekmek değil, bloklanmadan ve kaynağı düşürmeden bunu ölçekli yapmaktır.
Bu yazıda bir IPTV yansıtma sisteminin mimarisini; proxy rotasyonu, throttle, TLS fingerprint, TTL önbellek ve hata bütçesi (error budget) üzerinden anlatacağım.
1. Throttle: Kaynağın gözünden bakın
İlk ve en çok ihmal edilen kural: kendinizi kaynak sunucunun yerine koyun. Bir kaynaktan 1 saniyede 200 istek geliyorsa, 120. istekten sonra çoğu kaynak sizi ya rate-limit ile karşılar ya da IP bazlı bloklar.
// Basit token bucket throttle
final class Throttle
{
private array $tokens = [];
private float $rate;
public function __construct(float $requestsPerSecond)
{
$this->rate = $requestsPerSecond;
}
public function wait(string $source): void
{
$now = microtime(true);
$last = $this->tokens[$source] ?? $now;
$elapsed = $now - $last;
// izin verilen aralık
$minInterval = 1.0 / $this->rate;
if ($elapsed < $minInterval) {
usleep((int)(($minInterval - $elapsed) * 1_000_000));
}
$this->tokens[$source] = microtime(true);
}
}
Anahtar nokta: throttle’ı kaynak başına tutmaktır. Tek global havuz yanlıştır çünkü farklı kaynakların farklı toleransları vardır.
2. Proxy rotasyonu: Bloklanmadan ölçeklenmek
Tek IP ile rate-limit’i aşamazsınız. İhtiyacınız olan şey sağlıklı bir proxy havuzudur. Havuz yönetiminde en kritik veri yapısı “kara liste + soğuma” dur:
- Bir proxy 4xx/407 (auth hatası) verdi mi → anında pasif.
- Ardışık proxy time-out’ları → soğuma süresi koy.
- Rotasyon rastgele değil, son kullanım zamanına göre sıralı olmalı — aynı proxynin ardışık isteklerde kullanılmaması için.
// Proxy havuzu: başarısız olanları arka plana iterate et
class ProxyPool
{
private array $proxies = [];
private array $cooldown = [];
public function next(): string
{
foreach ($this->proxies as $proxy) {
$cd = $this->cooldown[$proxy] ?? 0;
if ($cd < time()) {
return $proxy;
}
}
usleep(100_000);
return $this->next();
}
public function penalize(string $proxy): void
{
$this->cooldown[$proxy] = time() + 30;
}
}
3. TLS/JA3 fingerprint: “Tarayıcı gibi görünmek”
Modern CDN’ler (Cloudflare başta) yalnızca User-Agent’a bakmaz. TLS el sıkışmasının JA3 fingerprint alanına bakar. cURL ile gönderdiğiniz istek tarayıcıdan farklı bir imza taşır ve hemen “bot” olarak sınıflandırılır.
Çözüm seçenekleri:
- Gerçek bir tarayıcı motoru (Playwright/Puppeteer) ile istek atın.
curl-impersonategibi Chrome imzasını taklit eden araçlar kullanın.- TLS fingerprint’i değiştirmek istiyorsanız, HTTP/2 + ALPN + cipher ayarlarını tarayıcı değerlerine eşleyin.
4. TTL önbellek: Aynı stream’i 1000 istekle yeniden çekmeyin
Yansıtma sistemlerinin en büyük israfı: aynı kanal listesini her kullanıcı isteğinde kaynaktan yeniden indirmek. Doğru yaklaşım, sonucu TTL ile bellekte/disk’te tutmak ve kaynağa yalnızca TTL dolunca gitmektir.
$cacheKey = 'xtream:' . md5($sourceUrl);
$ttl = 3600; // 1 saat
$list = apcu_fetch($cacheKey);
if ($list === false) {
$list = fetchFromSource($sourceUrl);
apcu_store($cacheKey, $list, $ttl);
}
Bu, kaynak isteklerini %90’dan fazla azaltır hem de yanıtınızı dramatik şekilde hızlandırır. Önbellek tabanları: tek sunucuda APCu, dağıtık yapıda Redis.
5. Hata bütçesi ve yarı-senkrone arka plan
Her kaynak zamanla bozulur. Plan olarak: kullanıcı isteğini asla doğrudan kaynağa bağlamayın. Bunun yerine:
- Arka plan bir işçi, kaynağı periyodik çeker ve önbelleğe yazar.
- Kullanıcı isteği yalnızca önbelleği okur.
- Önbellek boşsa → bir önceki “stale” kopyayı sun, kaynağı async tazele.
Bu, kaynak dayansa bile kullanıcının 200 almasını sağlar. “Stale-while-revalidate” deseni.
Özet: Öncelik sırası
- Önce throttle (kaynağı koru).
- Sonra TTL önbellek (kaynak isteklerini azalt).
- Ardından proxy rotasyonu (ölçeklen).
- En sonda fingerprint (bloklanmayı geciktir).
Bu sırayla giderseniz, önce stabilite sonra performans sonra gizlilik kazanırsınız. Tersine giderseniz, fingerprint’i düzeltirken kaynağınızı throttle etmeyi unutup kendinizi bloklatırsınız.