Proxy ile çalışırken geliştiriciler genellikle klasik HTTP proxy ayarlarının WebSocket bağlantıları için çalışmadığı ve gRPC'nin TLS el sıkışması hatalarıyla çöktüğüyle karşılaşırlar. Sorun, WebSocket, HTTP/2 ve gRPC'nin sadece "HTTP seçenekleri" değil, tünelleme, çoklama ve başlık işleme gereksinimleri olan farklı taşıma modelleri olduğudur. Bu yazıda, bu protokollerin her birini nasıl proxyleyeceğimizi, pratikte karşılaşılan tuzakları ve belirli bir görev için protokol ve proxy türünü nasıl seçeceğimizi inceleyeceğiz - WebSocket üzerinden veri ayrıştırmadan yüksek yüklenmeli gRPC mikro hizmetlerine kadar.
Protokoller arasındaki farklar ve bunun proxy için önemi
HTTP/1.1 "istek - yanıt" modeline göre çalışır: istemci bir bağlantı açar, istek gönderir, yanıt alır ve ya bağlantıyı kapatır ya da bir sonraki istek için açık tutar (keep-alive). Proxy sunucuları on yıllardır bu model için optimize edilmiştir - başlık ayrıştırma, istek gövdesinin tamponlanması, Host başlığına göre basit yönlendirme.
WebSocket bu modeli bozar: başlangıçtaki HTTP el sıkışmasından (Upgrade: websocket) sonra bağlantı sürekli iki yönlü bir kanala dönüşür, burada veriler her iki yönde de her an gidebilir. Proxy bu bağlantıyı "serbest bırakmalı" ve sadece baytları her iki yönde iletmelidir, bunları HTTP istekleri olarak yorumlamaya çalışmamalıdır.
HTTP/2 çoklama ekler - birden fazla mantıksal istek, tek bir TCP bağlantısı üzerinden paralel olarak, metin başlıkları yerine ikili çerçeveler kullanarak geçer. Proxy için bu, metni satır satır okumakla kalmayıp, proxy düzeyinde HTTP/2 ikili protokol desteği veya TLS üzerinden şeffaf TCP tünelleme gerektirdiği anlamına gelir.
gRPC daha da ileri gider: tamamen HTTP/2 üzerine inşa edilmiştir, serileştirme için Protokol Buffers kullanır ve istemciden sunucuya kadar olan tüm yol boyunca HTTP/2 uyumlu bir taşıma gerektirir. Eğer bir proxy bir noktada bağlantıyı HTTP/1.1'e "aşağı çekerse", gRPC isteği geçmeyecektir.
Bu farklılıkları anlamak kritik öneme sahiptir, çünkü yanlış proxy türü seçimi veya tünelleme ayarının yanlış yapılması bağlantı kopmalarına, zaman aşımına ve tanımlanması zor hatalara yol açar; bu hataları taşıma katmanını anlamadan teşhis etmek zordur.
WebSocket üzerinden proxy: ayar ve kod
WebSocket üzerinden proxy için iki ana senaryo vardır: WSS (yani TLS üzerinden WebSocket) için CONNECT yöntemiyle HTTP proxy ve protokolü ayırt etmeden TCP bağlantısını tünelleyen SOCKS5 proxy. SOCKS5 genellikle daha az sorun çıkarır, çünkü başlangıçta her türlü TCP trafiği için "şeffaf bir boru" olarak tasarlanmıştır.
websockets ve python-socks kütüphanesi ile Python'da SOCKS5 proxy üzerinden WebSocket'e bağlanma örneği:
import asyncio
from python_socks.sync import Proxy
import websockets
import websockets.sync.client as ws_client
def connect_ws_via_proxy():
proxy = Proxy.from_url("socks5://user:pass@proxy_host:1080")
sock = proxy.connect(dest_host="echo.websocket.events", dest_port=443)
ws = ws_client.connect(
"wss://echo.websocket.events",
sock=sock,
server_hostname="echo.websocket.events"
)
ws.send("Hello via proxy")
print(ws.recv())
ws.close()
connect_ws_via_proxy()
Node.js'de benzer bir görev ws paketi ile socks-proxy-agent ile çözülmektedir:
const WebSocket = require('ws');
const { SocksProxyAgent } = require('socks-proxy-agent');
const agent = new SocksProxyAgent('socks5://user:pass@proxy_host:1080');
const socket = new WebSocket('wss://echo.websocket.events', { agent });
socket.on('open', () => socket.send('Hello via proxy'));
socket.on('message', (data) => console.log(data.toString()));
Eğer proxy yalnızca HTTP (CONNECT yöntemi ile) üzerinden erişilebiliyorsa, şema benzer - çoğu modern WebSocket istemcisi HTTP tüneli üzerinden çalışabilmektedir, önemli olan proxy'nin uzun süreli bağlantıları zaman aşımına uğratmadığından emin olmaktır. Bu, genellikle 30-60 saniye süreli bir "aktif olmayan" bağlantı limiti olan ucuz veri merkezi proxy'leri ile sık karşılaşılan bir sorundur - akış yapan WebSocket görevleri için bu kritik öneme sahiptir ve sağlayıcıdan keep-alive parametrelerini netleştirmek daha iyidir.
HTTP/2 üzerinden proxy: çoklama ve tuzaklar
HTTP/2 üzerinden proxy ile ilgili en büyük zorluk, birçok proxy sunucusunun (özellikle eski Squid veya basit yönlendirme proxy'leri) yalnızca HTTP/1.1 ile çalışması ve bağlantıyı otomatik olarak "aşağı çekmesidir". İstemci için bu genellikle fark edilmez (istek yine de gerçekleştirilir), ancak çoklama avantajları kaybolur - gecikmeler artar, özellikle bir host'a çok sayıda paralel istek gönderildiğinde.
Proxy üzerinden HTTP/2 bağlantısının desteklenip desteklenmediğini cURL ile --http2 bayrağı ve ayrıntılı çıktı ile kontrol edebilirsiniz:
curl -v --http2 -x http://user:pass@proxy_host:8080 https://example.com
# Çıktıda şu satırı arayın:
# * Using HTTP2, server supports multiplexing
# Yoksa, bağlantı HTTP/1.1'e düştü
Python'da HTTP/2 üzerinden proxy için httpx kütüphanesi ile HTTP/2 desteği etkinleştirilmelidir:
import httpx
proxies = {
"http://": "http://user:pass@proxy_host:8080",
"https://": "http://user:pass@proxy_host:8080",
}
with httpx.Client(proxies=proxies, http2=True) as client:
response = client.get("https://example.com")
print(response.http_version) # "HTTP/2" bekliyoruz
print(response.status_code)
Önemli bir nokta: HTTP/2, protokolü müzakere etmek için ALPN uzantısı ile TLS gerektirir, bu nedenle proxy, TLS trafiğini CONNECT üzerinden şeffaf bir şekilde tünellemelidir, kendi başına TLS'yi sonlandırmamalıdır (bu özel bir HTTP/2 uyumlu proxy değilse). Bu nedenle, HTTP/2 görevleri için konut proxy'leri ve veri merkezi proxy'leri farklı davranır - sağlayıcıdan, ALPN müzakerelerini kesintisiz bir TLS tünelleme desteği olup olmadığını netleştirmek önemlidir.
gRPC üzerinden proxy: TLS, ALPN ve özel gereksinimler
gRPC, bu bağlamda en talepkar protokoldür. Sıkı bir şekilde HTTP/2'ye bağlıdır ve genellikle kimlik doğrulama için iki yönlü TLS (mTLS) kullanır. HTTP/2 CONNECT tünelleme desteği olmayan sıradan bir yönlendirme proxy'si, gRPC trafiğini geçiremez - bağlantı, UNAVAILABLE: upstream connect error gibi hatalarla çöker.
Python'da gRPC'yi proxylemek için (grpc kütüphanesi ile) proxy, çevresel değişkenler aracılığıyla ayarlanır, çünkü kanal seçeneklerinde proxy desteği tarihsel olarak yoktur:
import os
import grpc
os.environ["grpc_proxy"] = "http://user:pass@proxy_host:8080"
os.environ["https_proxy"] = "http://user:pass@proxy_host:8080"
channel = grpc.secure_channel(
"grpc.example.com:443",
grpc.ssl_channel_credentials()
)
# Oluşturulan stub ile bir çağrı örneği
# stub = YourServiceStub(channel)
# response = stub.YourMethod(request)
Node.js'de gRPC için proxy, grpc-js kanal seçenekleri aracılığıyla ayarlanır ve HTTP/2 uyumlu bir proxy ajanı ile birlikte kullanılır:
const grpc = require('@grpc/grpc-js');
const { HttpsProxyAgent } = require('https-proxy-agent');
process.env.grpc_proxy = 'http://user:pass@proxy_host:8080';
process.env.https_proxy = 'http://user:pass@proxy_host:8080';
const client = new YourServiceClient(
'grpc.example.com:443',
grpc.credentials.createSsl()
);
gRPC'nin proxy üzerinden stabil bir şekilde çalışması için düşük gecikme ve sık bağlantı kopmaları olmadan stabil bir TCP bağlantısı kritik öneme sahiptir - çoklu gRPC akışları, ayrı HTTP/1.1 isteklerine göre ağ hatalarına daha duyarlıdır. Bu tür senaryolarda, konut proxy'leri genellikle ucuz veri merkezi havuzlarına göre daha iyi bir stabilite gösterir, çünkü hedef sunucuya giden yol daha öngörülebilir bir ağ altyapısından geçer.
Protokollerin karşılaştırma tablosu
| Protokol | Bağlantı türü | Proxy gereksinimleri | Tavsiye edilen proxy türü |
|---|---|---|---|
| HTTP/1.1 | istek-yanıt, keep-alive | minimum, herhangi bir HTTP proxy | Veri merkezi proxy'leri |
| WebSocket | sürekli iki yönlü kanal | uzun bağlantı desteği, zaman aşımı olmadan | Konut proxy'leri |
| HTTP/2 | çoklama ikili akışlar | şeffaf TLS tünelleme, ALPN | Konut veya veri merkezi proxy'leri |
| gRPC | HTTP/2 + Protobuf, genellikle mTLS | düşük gecikme, stabilite, HTTP/2 CONNECT | Mobil proxy'ler sert filtreleri aşmak için |
Yığınınıza uygun protokol ve proxy nasıl seçilir
Protokol seçimi nadiren serbest bir karar olur - hedef API tarafından belirlenir. Ancak, bu protokol için proxy türü seçimi, sizin sorumluluğunuzdadır ve burada belirli bir senaryoya dayanmak önemlidir:
WebSocket üzerinden veri ayrıştırma (örneğin, piyasa verileri veya gerçek zamanlı veriler akışı) uzun süreli kesintisiz bir bağlantı gerektirir. Burada konut proxy'leri daha iyi çalışır - çünkü hedef hizmetin anti-fraud algoritmalarına daha az maruz kalırlar ve bağlantıyı tipik veri merkezi havuzlarından daha uzun süre tutarlar.
Dış proxy üzerinden gRPC mikro hizmetleri ile entegrasyon (örneğin, farklı coğrafi konumlardan API testleri) düşük gecikme ve HTTP/2 desteği gerektirir. Bunun için iyi yönlendirme ile konut IP'leri uygundur ve zaman açısından kritik görevler için, hedef hizmet veri merkezi aralıklarını agresif bir şekilde filtreliyorsa mobil proxy'ler tercih edilmelidir.
REST/GraphQL API'ye toplu HTTP/2 istekleri çoklama ile - hedef hizmetin varsayılan olarak veri merkezi IP aralıklarını engellemediği sürece hızlı ve ucuz veri merkezi proxy'leri yeterlidir.
Genel kural: Protokol bağlantı stabilitesine ne kadar "kaprisli" ise (WebSocket, gRPC), konut veya mobil IP'lerin anlamı o kadar fazladır. İstek ne kadar basit ve kısa ise (normal HTTP/1.1 veya uzun oturumlar olmadan HTTP/2), veri merkezi proxy'leri ile çalışmak o kadar konforludur - daha hızlıdırlar ve daha yüksek bant genişliği sağlarlar.
Yaygın hatalar ve çözümleri
Hata 1: WebSocket her 30-60 saniyede bir kopuyor. Sebep - proxy veya ara dengeleyici "aktif olmayan" bağlantıları kapatıyor. Çözüm: uygulama düzeyinde ping/pong çerçevelerini proxy zaman aşımından daha kısa bir aralıkla etkinleştirin (genellikle 20-25 saniye yeterlidir).
Hata 2: gRPC proxy üzerinden UNAVAILABLE hatası veriyor, oysa doğrudan çalışıyor. Proxy, HTTP/2 CONNECT tünellemesini desteklemiyor. Çözüm: sağlayıcının HTTP/2 desteğini kontrol edin veya protokolü yorumlamadan TCP'yi tünelleyen SOCKS5 proxy kullanın.
Hata 3: HTTP/2 fark edilmeden HTTP/1.1'e düşüyor. Bu genellikle proxy'de ALPN desteğinin olmamasından kaynaklanır. Protokol sürümünü kodda açıkça kontrol edin (yukarıdaki httpx örneği gibi) - yanıtın http_version'ını kontrol etmeden "her şey çalışıyor" diye güvenmeyin.
Hata 4: Proxy üzerinden gRPC çoklamasında yüksek gecikme. Genellikle proxy sağlayıcısındaki çok sayıda ara düğümden kaynaklanır. Çözüm: basit bir RTT isteği ile gecikmeyi önceden test edin ve özellikle zaman açısından kritik gRPC çağrıları için doğrudan yönlendirme ile sağlayıcı seçin.
Sonuç
WebSocket, HTTP/2 ve gRPC, proxy ayarları için farklı yaklaşımlar gerektirir; çünkü farklı taşıma modellerinde çalışırlar: WebSocket için basit "TCP bağlantısını serbest bırakma"dan gRPC için HTTP/2 CONNECT ve ALPN desteğine kadar. Protokol sürümünü kodda açıkça kontrol edin, uzun süreli bağlantıların stabilitesini önceden test edin ve maksimum tünelleme şeffaflığı gerektiğinde SOCKS5 kullanın.
Eğer yığınınız uzun ömürlü WebSocket bağlantıları veya gecikmeye duyarlı gRPC çağrıları içeriyorsa, konut proxy'lerini denemenizi öneririz - bunlar tipik veri merkezi havuzlarına göre daha stabil ve öngörülebilir bağlantılar sağlar. Yüksek bant genişliği ile basit HTTP/2 istekleri için veri merkezi proxy'leri uygundur, sert anti-fraud filtrelemeleri olan hedef hizmetler için ise mobil proxy'ler tercih edilmelidir.