İçeriğe geç
Guides 7 dk okuma 805 görüntülenme

Python'da asenkron proxy

Python'da yüksek performanslı asenkron proxy'ler kurmayı inceleyin. Bu rehber, verimli ağ işlemleri için aiohttp ve httpx'i kapsar.

Python
Python'da asenkron proxy

Python'da asenkron proxy'ler, birden fazla eşzamanlı ağ isteğini verimli biçimde yönetmek için aiohttp ve httpx gibi kütüphaneleri kullanır ve I/O işlemlerinin ana yürütme thread'ini bloklamasını önler.

Proxy servisleri doğası gereği I/O bağımlıdır; çalışma sürelerinin büyük bölümünü upstream sunuculardan gelen ağ yanıtlarını veya istemci isteklerini beklemekle geçirir. Geleneksel senkron (bloklayan) I/O modelleri thread başına aynı anda tek bir isteği işler; bu da kaynakların verimsiz kullanılmasına ve sınırlı ölçeklenebilirliğe yol açar. Python'un asyncio çatısını kullanan asenkron I/O ise, I/O işlemlerinin tamamlanmasını beklerken bağlam değiştirerek tek bir thread'in çok sayıda eşzamanlı bağlantıyı yönetmesine olanak tanır. Bu mimari, bir proxy'nin işlem hacmini ve yanıt verme hızını belirgin biçimde artırır.

Temel asenkron kavramlar

Python'un asyncio kütüphanesi asenkron programlamanın temelini sağlar. Başlıca öğeler şunlardır:

  • Event loop: coroutine'leri planlayıp çalıştıran, I/O olaylarını ve callback'leri işleyen merkezi bileşen.
  • Coroutine'ler (async def): duraklatılıp devam ettirilebilen fonksiyonlar. async def ile tanımlanır ve await ile çalıştırılır.
  • await anahtar sözcüğü: bir awaitable (başka bir coroutine, Future veya Task) tamamlanana kadar coroutine'in çalışmasını duraklatmak için kullanılır. Bu, kontrolü event loop'a geri verir.

Asenkron proxy servisleri için aiohttp

aiohttp, asyncio için asenkron bir HTTP istemci/sunucu çatısıdır. Bir proxy'nin hem gelen (sunucu) hem de giden (istemci) bileşenlerini kurmak için uygundur.

Proxy sunucusu olarak aiohttp

aiohttp.web, gelen istemci isteklerini dinleyen bir web sunucusu kurmak için gereken araçları sağlar.

import aiohttp.web

async def handle_request(request):
    """
    Gelen istekler için örnek bir handler.
    Gerçek bir proxy'de bu, isteği iletirdi.
    """
    return aiohttp.web.Response(text=f"Received: {request.method} {request.url}")

async def main():
    app = aiohttp.web.Application()
    app.router.add_route('*', '/{path:.*}', handle_request) # Tüm rotaları yakalar
    runner = aiohttp.web.AppRunner(app)
    await runner.setup()
    site = aiohttp.web.TCPSite(runner, '0.0.0.0', 8080)
    await site.start()
    print("aiohttp proxy server started on port 8080")
    while True:
        await asyncio.sleep(3600) # Sunucuyu çalışır durumda tutar

if __name__ == '__main__':
    import asyncio
    asyncio.run(main())

Asenkron HTTP istemcisi olarak aiohttp

aiohttp.ClientSession, istemci isteklerini upstream sunuculara iletmek için kritik olan giden HTTP isteklerini yapmak üzere kullanılır. Bağlantı havuzunu ve çerezleri yönetir.

import aiohttp
import asyncio

async def fetch_url(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            response.raise_for_status() # HTTP hatalarında istisna fırlatır
            return await response.text()

async def example_client_usage():
    content = await fetch_url('http://httpbin.org/get')
    print(f"Fetched content: {content[:100]}...")

if __name__ == '__main__':
    asyncio.run(example_client_usage())

Asenkron proxy servisleri için httpx

httpx, Python için modern ve tam donanımlı bir HTTP istemcisidir; hem senkron hem asenkron API sunar. Asenkron yetenekleri asyncio üzerine kuruludur.

Asenkron HTTP istemcisi olarak httpx

httpx.AsyncClient, asenkron istekler yapmak için birincil arayüzdür. requests'e benzer bir API sunar; bu da requests kütüphanesini bilen geliştiriciler için onu sezgisel kılar.

import httpx
import asyncio

async def fetch_url_httpx(url):
    async with httpx.AsyncClient() as client:
        response = await client.get(url)
        response.raise_for_status() # HTTP hatalarında istisna fırlatır
        return response.text

async def example_httpx_client_usage():
    content = await fetch_url_httpx('http://httpbin.org/get')
    print(f"Fetched content (httpx): {content[:100]}...")

if __name__ == '__main__':
    asyncio.run(example_httpx_client_usage())

httpx sunucu yetenekleri sunmaz; tamamen bir istemci kütüphanesidir.

aiohttp ile httpx istemci karşılaştırması

Özellik aiohttp.ClientSession httpx.AsyncClient
Amaç Asenkron HTTP istemci ve sunucu çatısı. Asenkron (ve senkron) HTTP istemcisi.
API tarzı Daha alt seviye asyncio entegrasyonu, daha ayrıntılı. requests benzeri API, genelde daha derli toplu.
HTTP/2 desteği Yerel HTTP/2 istemci desteği yok. Yerel HTTP/2 istemci desteği var.
HTTP/3 (QUIC) desteği Yok. quic-go (Rust) üzerinden deneysel destek.
WebSocket istemcisi Var. Yok.
Bağımlılıklar multidict, yarl, async_timeout, attrs. httpcore, idna, certifi, `sniffio (asgari).
Bağlantı havuzu ClientSession tarafından yönetilir. AsyncClient tarafından yönetilir.
Yönlendirme yönetimi Otomatik, yapılandırılabilir. Otomatik, yapılandırılabilir.
Akışlı yanıtlar Evet, response.content.read() ile. Evet, response.aiter_bytes() ile.
Proxy yapılandırması ClientSession metotlarında doğrudan proxy parametresi. AsyncClient ve isteklerde doğrudan proxies parametresi.

Bir proxy sunucusu kurmak için sunucu yetenekleri nedeniyle aiohttp gereklidir. Giden istemci bileşeni için ikisi de kullanılabilir. httpx çoğu zaman daha basit bir API ve yerleşik HTTP/2 desteği sunar; bu da avantaj sağlayabilir.

aiohttp (sunucu) ve httpx (istemci) ile asenkron proxy kurmak

Bu yaklaşım, gelen proxy isteklerini işlemek için aiohttp'yi, bunları hedef sunucuya iletmek için httpx'i kullanır. Bu birleşim genellikle sunucu kontrolü ile istemci basitliği/özellikleri arasında iyi bir denge sağlar.

import aiohttp.web
import httpx
import asyncio
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

# Bağlantı havuzu için httpx.AsyncClient bir kez oluşturulur
# Bu istemci tüm giden isteklerde kullanılacaktır
# Asılı kalan bağlantıları önlemek için varsayılan bir timeout belirleyin
OUTGOING_CLIENT = httpx.AsyncClient(timeout=30.0) 

async def proxy_handler(request):
    """
    Gelen istemci isteklerini işler, httpx ile iletir
    ve yanıtı istemciye döndürür.
    """
    target_url = str(request.url).lstrip('/') # Yoldaki baştaki eğik çizgiyi kaldırır

    # Şema, host ve query parametrelerini koruyarak hedef URL'yi yeniden oluşturur
    # Tipik bir forward proxy'de istemci tam URL gönderir (ör. GET http://example.com/path)
    # Reverse proxy'de sunucu yalnızca yolu alabilir ve bir temel URL'ye ihtiyaç duyar.
    # Bu örnek, tam URL'nin yolda bulunduğu bir forward proxy varsayar.
    # Reverse proxy için sabit bir temel URL eklerdiniz:
    # target_url = f"http://upstream.example.com{request.url.path_qs}"

    # Hop-by-hop ve proxy'ye özgü başlıkları hariç tutarak başlıkları çıkarır
    headers = {
        k: v for k, v in request.headers.items() 
        if k.lower() not in ['host', 'connection', 'keep-alive', 'proxy-authenticate', 
                             'proxy-authorization', 'te', 'trailers', 'transfer-encoding', 
                             'upgrade', 'via', 'x-forwarded-for', 'x-real-ip']
    }

    # Yoksa X-Forwarded-For ekler
    client_ip = request.remote
    if client_ip:
        headers['X-Forwarded-For'] = headers.get('X-Forwarded-For', '') + (', ' if headers.get('X-Forwarded-For') else '') + client_ip

    request_method = request.method
    request_body = await request.read() if request_method in ('POST', 'PUT', 'PATCH') else None

    logger.info(f"Proxying {request_method} {target_url} from {request.remote}")

    try:
        # İsteği httpx ile iletir
        proxy_response = await OUTGOING_CLIENT.request(
            method=request_method,
            url=target_url,
            headers=headers,
            content=request_body,
            params=request.query # Query parametrelerini ayrıca iletir
        )
        proxy_response.raise_for_status() # 4xx/5xx yanıtlarında istisna fırlatır

        # Yanıtı istemci için hazırlar
        response_headers = {
            k: v for k, v in proxy_response.headers.items()
            if k.lower() not in ['content-encoding', 'transfer-encoding', 'connection'] # Hop-by-hop başlıklar
        }

        # Büyük yanıtları belleğe yüklememek için yanıt gövdesini akış hâlinde gönderir
        response = aiohttp.web.StreamResponse(status=proxy_response.status, headers=response_headers)
        await response.prepare(request)
        async for chunk in proxy_response.aiter_bytes():
            await response.write(chunk)
        await response.write_eof()

        logger.info(f"Forwarded {request_method} {target_url} with status {proxy_response.status}")
        return response

    except httpx.HTTPStatusError as e:
        logger.error(f"HTTP error proxying {target_url}: {e.response.status_code} - {e.response.text}")
        return aiohttp.web.Response(
            status=e.response.status_code,
            text=f"Upstream HTTP Error: {e.response.status_code}\n{e.response.text}",
            content_type="text/plain"
        )
    except httpx.RequestError as e:
        logger.error(f"Network error proxying {target_url}: {e}")
        return aiohttp.web.Response(
            status=502, # Bad Gateway
            text=f"Proxy Network Error: {e}",
            content_type="text/plain"
        )
    except Exception as e:
        logger.exception(f"Unexpected error in proxy_handler for {target_url}")
        return aiohttp.web.Response(
            status=500,
            text=f"Proxy Internal Error: {e}",
            content_type="text/plain"
        )

async def start_proxy_server():
    app = aiohttp.web.Application()
    # Bu rota tüm metotları ve yolları karşılar
    # Forward proxy'de istemci istekleri şöyle görünür: GET http://example.com/path
    # aiohttp yolu '/http://example.com/path' olarak ayrıştırır
    # Tam URL'yi elde etmek için proxy_handler içinde baştaki '/' karakterini kaldırıyoruz.
    app.router.add_route('*', '/{path:.*}', proxy_handler) 

    runner = aiohttp.web.AppRunner(app)
    await runner.setup()
    site = aiohttp.web.TCPSite(runner, '0.0.0.0', 8080)
    await site.start()
    logger.info("Asynchronous proxy server started on http://0.0.0.0:8080")

    # Sunucuyu süresiz çalışır durumda tutar
    try:
        while True:
            await asyncio.sleep(3600) 
    finally:
        await OUTGOING_CLIENT.aclose() # httpx istemcisinin kapatıldığından emin olur
        await runner.cleanup()

if __name__ == '__main__':
    asyncio.run(start_proxy_server())

Proxy servisleri için pratik hususlar

Başlık yönetimi

Proxy'ler HTTP başlıklarını dikkatle yönetmelidir.
* Hop-by-hop başlıklar (Connection, Keep-Alive, Proxy-Authenticate, Proxy-Authorization, TE, Trailer, Transfer-Encoding, Upgrade) iki düğüm arasındaki bağlantıya özgüdür ve iletilmemelidir.
* X-Forwarded-For / X-Real-IP: upstream sunucuyu asıl talep sahibi hakkında bilgilendirmek için istemcinin IP adresini bu başlıklara ekleyin veya mevcut değere iliştirin.
* Via başlığı: proxy'nin devrede olduğunu belirtmek için isteğe bağlı olarak bir Via başlığı ekleyin.

Gövde akışı (streaming)

Büyük istek veya yanıt gövdelerinde, veriyi tamamen belleğe yüklemek yerine akış hâlinde aktarmak kritiktir. Hem aiohttp (gelen için request.read(), giden için response.write() ile) hem de httpx (content parametresi ve response.aiter_bytes() ile) akışı destekler; bu da bellek tükenmesini önler ve gecikmeyi azaltır.

Bağlantı havuzu

Hem aiohttp.ClientSession hem de httpx.AsyncClient bağlantı havuzu uygular. Bu istemcileri bir kez oluşturup birden fazla istekte yeniden kullanmak (OUTGOING_CLIENT örneğinde gösterildiği gibi) performans için kritiktir. Bu, her istek için yeni TCP bağlantıları kurmanın maliyetini azaltır.

Timeout'lar

Proxy servisleri, upstream sunucu gecikmelerinden veya arızalarından etkilenir. Giden istekler için sıkı timeout'lar uygulamak, kaynakların tükenmesini önlemek ve hızlı yanıt veren bir servis sunmak için şarttır. httpx.AsyncClient ve aiohttp.ClientSession, bağlantı, okuma ve toplam timeout değerlerinin yapılandırılmasına izin verir.

Hata yönetimi ve yeniden denemeler

Ağ sorunları (ör. bağlantı reddedildi, DNS hataları) ve HTTP hataları (ör. upstream'den gelen 5xx yanıtlar) için sağlam bir hata yönetimi gereklidir. Güvenilirliği artırmak için geçici hatalarda üstel geri çekilmeli (exponential backoff) yeniden deneme mekanizmaları uygulayın.

WebSocket proxy'leme

aiohttp, sunucu tarafında WebSocket'ler için yerel destek sunar (aiohttp.web.WebSocketResponse). WebSocket proxy'lemek, Upgrade başlığının işlenmesini ve istemci, proxy ile hedef WebSocket sunucusu arasında çift yönlü bir veri akışı kurulmasını gerektirir. httpx, istemci tarafında WebSocket bağlantılarını desteklemez.

Performans ayarı

  • uvloop: aiohttp uygulamalarında uvloop (Cython ile yazılmış, asyncio event loop'unun doğrudan yerine geçen bir alternatif) kurmak performansı belirgin biçimde artırabilir.
  • İşletim sistemi limitleri: yüksek eşzamanlılığa sahip proxy servislerinde işletim sistemindeki açık dosya tanıtıcısı limitlerini (ulimit -n) yükseltmek çoğu zaman gereklidir.
  • Kaynak izleme: darboğazları belirlemek ve kaynak dağılımını iyileştirmek için CPU, bellek ve ağ I/O'sunu izleyin.
Güncellendi: 03.03.2026
Kategoriye dön

Bunları da okuyun

Guides 2 dk

Nike SNKRS için Proxy: Sınırlı Sürümler ve Çoklu Katılım

Nike SNKRS'ta birden fazla hesapla çekilişlere katılmak, IP limitlerini aşmak ve ban yemeden sınırlı sürümleri kapmak için residential veya mobil proxy kullanın. Hangi türü seçmeli ve nasıl kurmalı.

Guides 2 dk

iPhone'da Proxy Nasıl Kurulur (Wi-Fi ve SOCKS5)

iPhone'da proxy'yi yerleşik Wi-Fi ayarlarından (HTTP/HTTPS) veya SOCKS5 ile hücresel kapsama için Shadowrocket gibi bir uygulamayla kurun. Adım adım iOS kurulumu ve bilinmesi gereken kısıtlar.

Guides 3 dk

Tinder için proxy: çoklu hesap ve ban'lerden kaçınma

Birden fazla profil işletmek ve IP shadowban'lerinden kaçınmak için Tinder'da mobil veya residential proxy kullanın. Mobilin neden kazandığı, kurulumu ve proxy'nin şehri neden değiştirmediği.

Guides 2 dk

StockX için proxy: fiyat takibi ve hesap yönetimi

StockX'te fiyatları izlemek, birden fazla hesap çalıştırmak ve drop'ları yasaklanmadan kapmak için residential, ISP veya mobil proxy kullanın. Hangi türü seçeceğinizi ve nasıl kuracağınızı anlatıyoruz.

Guides 3 dk

OpenAI API için Proxy: Erişim, Hız Limitleri ve Kurulum

OpenAI API'yi residential veya ISP proxy üzerinden yönlendirerek desteklenen bölgelere erişin, 429 hız limitlerinden kaçının ve hesapları izole edin. Hangi proxy'yi seçmeli ve Python kurulum örnekleri.

Guides 1 dk

E2E testleri için Cypress'te proxy kurulumu

Cypress'te proxy kurulumu: HTTP_PROXY değişkenleri, cy-proxy-middleware ve coğrafi konuma bağlı içeriğin test edilmesi.

Proxy'lerimizi deneyin

100+ ülkede 20,000+ proxy

support_agent
GProxy Support
Usually replies within minutes
Hi there!
Send us a message and we'll reply as soon as possible.