بازگشت به وبلاگ

چرا پروکسی کند است و چگونه سرعت آن را افزایش دهیم

تحلیل فنی دقیق دلایل کندی عملکرد سرورهای پروکسی با راه‌حل‌های عملی، نمونه‌های کد و نتایج آزمایش روش‌های مختلف بهینه‌سازی.

📅۲۵ آذر ۱۴۰۴
```html

پروکسی کند: 7 دلیل کاهش سرعت و روش‌های افزایش سرعت

سرعت اتصال پروکسی به طور مستقیم بر کارایی پارسینگ، اتوماسیون و هرگونه وظایف مرتبط با درخواست‌های انبوه تأثیر می‌گذارد. زمانی که پروکسی به آرامی کار می‌کند، این باعث افزایش زمان اجرای اسکریپت‌ها، زمان‌های تایم‌اوت و از دست دادن داده‌ها می‌شود. در این مقاله به بررسی دلایل فنی سرعت پایین و ارائه روش‌های خاص بهینه‌سازی با مثال‌های کد و نتایج آزمایش خواهیم پرداخت.

فاصله جغرافیایی سرور

فاصله فیزیکی بین سرور شما، پروکسی و منبع هدف، عامل اصلی تأخیر (latency) است. هر گره اضافی در زنجیره چند میلی‌ثانیه به زمان اضافه می‌کند که در درخواست‌های انبوه جمع می‌شود.

الگوی معمول درخواست از طریق پروکسی به این شکل است: سرور شما → سرور پروکسی → سایت هدف → سرور پروکسی → سرور شما. اگر پارسر شما در آلمان باشد، پروکسی در ایالات متحده و سایت هدف در ژاپن، داده‌ها ده‌ها هزار کیلومتر را طی می‌کنند.

مثال عملی: آزمایش 1000 درخواست به یک سایت اروپایی تفاوت میانگین زمان پاسخ را نشان داد: از طریق پروکسی در اروپا — 180 میلی‌ثانیه، از طریق پروکسی در آسیا — 520 میلی‌ثانیه. تفاوت 340 میلی‌ثانیه برای هر درخواست، 340 ثانیه (5.6 دقیقه) برای 1000 درخواست به همراه دارد.

راه‌حل: پروکسی را جغرافیایی نزدیک به منبع هدف انتخاب کنید. اگر سایت‌های روسی را پارس می‌کنید — از پروکسی با IP‌های روسی استفاده کنید. برای کار با خدمات جهانی (Google، Amazon) پروکسی‌های ایالات متحده یا غرب اروپا که مراکز داده اصلی در آنجا قرار دارند، بهینه‌تر هستند.

برای پروکسی‌های مسکونی به امکان انتخاب شهر یا منطقه خاص توجه کنید، نه فقط کشور. تفاوت در پینگ بین پروکسی‌های مسکو و ولادی‌وستوک هنگام دسترسی به سرور مسکو می‌تواند به 150-200 میلی‌ثانیه برسد.

تأثیر پروتکل بر سرعت انتقال داده‌ها

انتخاب پروتکل پروکسی به طور قابل توجهی بر سرعت تأثیر می‌گذارد. گزینه‌های اصلی: HTTP/HTTPS، SOCKS4، SOCKS5. هر کدام ویژگی‌های خاص خود را در پردازش داده‌ها و هزینه‌های اضافی دارند.

پروتکل سرعت هزینه‌های اضافی کاربرد
HTTP بالا حداقل وب‌پارسینگ، API
HTTPS متوسط +15-25% بر روی SSL اتصالات ایمن
SOCKS4 بالا کم ترافیک TCP
SOCKS5 متوسط-بالا +5-10% بر روی احراز هویت ترافیک عمومی، UDP

پروکسی‌های HTTP برای وب‌اسکرپینگ بهینه‌تر هستند، زیرا در سطح کاربردی کار می‌کنند و می‌توانند داده‌ها را کش کنند. SOCKS5 عمومی‌تر است، اما یک لایه اضافی پردازش را اضافه می‌کند. برای پارسینگ ساده HTML، تفاوت سرعت بین HTTP و SOCKS5 می‌تواند 10-15% باشد.

مثال پیکربندی در Python (requests):

import requests

# پروکسی HTTP - سریع‌تر برای درخواست‌های وب
proxies_http = {
    'http': 'http://user:pass@proxy.example.com:8080',
    'https': 'http://user:pass@proxy.example.com:8080'
}

# SOCKS5 - عمومی‌تر، اما کندتر
proxies_socks = {
    'http': 'socks5://user:pass@proxy.example.com:1080',
    'https': 'socks5://user:pass@proxy.example.com:1080'
}

# برای وب‌پارسینگ از HTTP استفاده کنید
response = requests.get('https://example.com', proxies=proxies_http, timeout=10)

اگر ارائه‌دهنده شما هر دو گزینه را ارائه می‌دهد، آن‌ها را در وظایف واقعی آزمایش کنید. برای کار با پروکسی‌های دیتاسنتر پروتکل HTTP معمولاً سرعتی 12-18% بالاتر از SOCKS5 در بار یکسان نشان می‌دهد.

بارگذاری بیش از حد سرور پروکسی و استخرهای IP

زمانی که یک سرور پروکسی بیش از حد زیادی اتصالات همزمان را مدیریت می‌کند، سرعت به دلیل محدودیت‌های پهنای باند و منابع محاسباتی کاهش می‌یابد. این موضوع به ویژه برای پروکسی‌های مشترک (shared) که یک IP توسط ده‌ها مشتری استفاده می‌شود، بحرانی است.

تصویر معمول بارگذاری: در ابتدای کار اسکریپت، سرعت نرمال است (50-100 درخواست در دقیقه)، سپس به طور ناگهانی به 10-15 درخواست کاهش می‌یابد. این زمانی اتفاق می‌افتد که سرور به حد مجاز اتصالات باز یا پهنای باند برسد.

نشانه‌های بارگذاری: افزایش زمان پاسخ به 200%+، تایم‌اوت‌های دوره‌ای، خطاهای "Connection reset by peer"، سرعت ناپایدار با نوسانات شدید.

راه‌حل‌ها:

  • از استخر پروکسی به جای یک IP استفاده کنید. چرخش بین 10-20 پروکسی بار را توزیع کرده و احتمال مسدود شدن را کاهش می‌دهد.
  • تعداد اتصالات همزمان از طریق یک پروکسی را محدود کنید (توصیه می‌شود بیش از 5-10 رشته موازی نباشد).
  • برای وظایف با بار بالا، پروکسی‌های خصوصی (dedicated) را انتخاب کنید که منابع با دیگر کاربران به اشتراک گذاشته نمی‌شود.
  • سرعت را در زمان واقعی نظارت کنید و پروکسی‌های کند را به طور خودکار از چرخش حذف کنید.

مثال پیاده‌سازی استخر با نظارت بر سرعت:

import time
import requests
from collections import deque

class ProxyPool:
    def __init__(self, proxies, max_response_time=5.0):
        self.proxies = deque(proxies)
        self.max_response_time = max_response_time
        self.stats = {p: {'total': 0, 'slow': 0} for p in proxies}
    
    def get_proxy(self):
        """دریافت پروکسی بعدی از استخر"""
        proxy = self.proxies[0]
        self.proxies.rotate(-1)  # انتقال به انتها
        return proxy
    
    def test_and_remove_slow(self, url='http://httpbin.org/ip'):
        """آزمایش و حذف پروکسی‌های کند"""
        for proxy in list(self.proxies):
            try:
                start = time.time()
                requests.get(url, proxies={'http': proxy}, timeout=10)
                response_time = time.time() - start
                
                self.stats[proxy]['total'] += 1
                if response_time > self.max_response_time:
                    self.stats[proxy]['slow'] += 1
                
                # حذف اگر بیش از 50% درخواست‌ها کند باشند
                slow_ratio = self.stats[proxy]['slow'] / self.stats[proxy]['total']
                if slow_ratio > 0.5 and self.stats[proxy]['total'] > 10:
                    self.proxies.remove(proxy)
                    print(f"پروکسی کند حذف شد: {proxy}")
            except:
                self.proxies.remove(proxy)

# استفاده
proxies = [
    'http://proxy1.example.com:8080',
    'http://proxy2.example.com:8080',
    'http://proxy3.example.com:8080'
]

pool = ProxyPool(proxies, max_response_time=3.0)
pool.test_and_remove_slow()

# کار با استخر
for i in range(100):
    proxy = pool.get_proxy()
    # انجام درخواست از طریق proxy

تنظیمات اتصال و تایم‌اوت‌ها

تنظیمات نادرست پارامترهای اتصال، دلیل رایج کندی ظاهری پروکسی است. تایم‌اوت‌های بسیار بزرگ باعث می‌شوند اسکریپت منتظر پروکسی‌های غیرقابل دسترس بماند و تایم‌اوت‌های بسیار کوچک منجر به قطع اتصالات نرمال می‌شود.

پارامترهای کلیدی که بر سرعت تأثیر می‌گذارند:

  • Connection timeout — زمان انتظار برای برقراری اتصال. بهینه: 5-10 ثانیه برای پروکسی‌های مسکونی، 3-5 برای پروکسی‌های دیتاسنتر.
  • Read timeout — زمان انتظار برای پاسخ پس از برقراری اتصال. بستگی به وظیفه دارد: 10-15 ثانیه برای پارسینگ، 30+ برای بارگذاری فایل‌های بزرگ.
  • Keep-Alive — استفاده مجدد از اتصالات TCP. تا 200-300 میلی‌ثانیه در هر درخواست بعدی به همان دامنه صرفه‌جویی می‌کند.
  • Connection pooling — استخر اتصالات باز. برای عملکرد بالا در درخواست‌های انبوه حیاتی است.

پیکربندی بهینه برای requests:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# ایجاد یک جلسه با تنظیمات بهینه
session = requests.Session()

# تنظیم استراتژی تلاش مجدد
retry_strategy = Retry(
    total=3,  # حداکثر 3 تلاش
    backoff_factor=0.5,  # تأخیر بین تلاش‌ها: 0.5، 1، 2 ثانیه
    status_forcelist=[429, 500, 502, 503, 504],
    allowed_methods=["GET", "POST"]
)

# آداپتور با استخر اتصالات
adapter = HTTPAdapter(
    max_retries=retry_strategy,
    pool_connections=10,  # استخر برای 10 میزبان
    pool_maxsize=20  # حداکثر 20 اتصال
)

session.mount("http://", adapter)
session.mount("https://", adapter)

# تنظیم پروکسی
session.proxies = {
    'http': 'http://user:pass@proxy.example.com:8080',
    'https': 'http://user:pass@proxy.example.com:8080'
}

# درخواست با تایم‌اوت‌های بهینه
# (connection_timeout, read_timeout)
response = session.get(
    'https://example.com',
    timeout=(5, 15),  # 5 ثانیه برای اتصال، 15 برای خواندن
    headers={'Connection': 'keep-alive'}  # استفاده مجدد از اتصال
)

استفاده از جلسات با Keep-Alive هنگام پارسینگ 1000 صفحه از یک سایت، کارایی را 30-40% نسبت به ایجاد یک اتصال جدید برای هر درخواست افزایش می‌دهد. صرفه‌جویی در زمان برای برقراری اتصال TCP و SSL handshake در عملیات انبوه حیاتی است.

رمزنگاری و هزینه‌های SSL/TLS

اتصالات HTTPS به منابع محاسباتی اضافی برای رمزنگاری/دشفرم داده‌ها و انجام SSL/TLS handshake نیاز دارند. هنگام کار از طریق پروکسی، این دو بار اتفاق می‌افتد: بین شما و پروکسی، بین پروکسی و سرور هدف.

هزینه‌های معمول SSL/TLS:

  • Handshake اولیه: 150-300 میلی‌ثانیه (بستگی به الگوریتم و فاصله دارد)
  • رمزنگاری/دشفرم داده‌ها: +10-20% به زمان انتقال
  • بار اضافی بر روی CPU سرور پروکسی در ترافیک بالا

روش‌های بهینه‌سازی:

1. از TLS Session Resumption استفاده کنید
این امکان را می‌دهد که پارامترهای SSL-session را دوباره استفاده کرده و handshake کامل را رد کنید. صرفه‌جویی تا 200 میلی‌ثانیه در هر اتصال بعدی.

در Python این به طور خودکار هنگام استفاده از requests.Session() کار می‌کند، اما اطمینان حاصل کنید که برای هر درخواست یک جلسه جدید ایجاد نکنید.

2. TLS 1.3 را ترجیح دهید
TLS 1.3 فقط به یک round-trip برای handshake نیاز دارد در حالی که TLS 1.2 به دو round-trip نیاز دارد. این زمان برقراری اتصال را 30-50% کاهش می‌دهد.

اطمینان حاصل کنید که کتابخانه شما (OpenSSL، urllib3) از TLS 1.3 پشتیبانی می‌کند و در تنظیمات غیرفعال نیست.

3. برای وظایف داخلی HTTP را در نظر بگیرید
اگر داده‌های عمومی را پارس می‌کنید که حاوی اطلاعات محرمانه نیستند و سایت به HTTP در دسترس است، از اتصال رمزنگاری نشده استفاده کنید. این سرعت را 15-25% افزایش می‌دهد.

هنگام کار با پروکسی‌های موبایل، جایی که کانال ارتباطی ممکن است کندتر باشد، هزینه‌های SSL حتی بیشتر به چشم می‌آید. در آزمایش‌ها، تفاوت بین درخواست‌های HTTP و HTTPS از طریق پروکسی‌های 4G به طور متوسط 280 میلی‌ثانیه بود.

حل DNS و کشینگ

هر درخواست به یک دامنه جدید نیاز به حل DNS دارد — تبدیل نام دامنه به آدرس IP. بدون کشینگ، این 20-100 میلی‌ثانیه به هر درخواست اضافه می‌کند و در صورت وجود سرور DNS کند، تأخیر می‌تواند به 500+ میلی‌ثانیه برسد.

هنگامی که از طریق پروکسی کار می‌کنید، درخواست‌های DNS ممکن است در سه مکان انجام شوند:

  • در سمت شما (مشتری دامنه را حل کرده و IP پروکسی را منتقل می‌کند)
  • در سرور پروکسی (SOCKS5، HTTP CONNECT — پروکسی دامنه را دریافت کرده و خود آن را حل می‌کند)
  • در سرور هدف (به ندرت، در پیکربندی‌های خاص)

برای پروکسی‌های SOCKS5، حل DNS معمولاً در سمت سرور پروکسی انجام می‌شود که ممکن است کندتر باشد اگر ارائه‌دهنده پروکسی DNS‌های بدی داشته باشد. پروکسی‌های HTTP بیشتر در سمت مشتری حل می‌کنند.

روش‌های تسریع DNS:

import socket
from functools import lru_cache

# کشینگ حل DNS در سمت مشتری
@lru_cache(maxsize=256)
def cached_resolve(hostname):
    """کش کردن نتایج درخواست‌های DNS"""
    try:
        return socket.gethostbyname(hostname)
    except socket.gaierror:
        return None

# استفاده
hostname = 'example.com'
ip = cached_resolve(hostname)
if ip:
    # استفاده از IP به طور مستقیم در درخواست‌ها
    url = f'http://{ip}/path'
    headers = {'Host': hostname}  # مشخص کردن میزبان اصلی در هدر

رویکرد جایگزین — استفاده از DNS‌های عمومی سریع در سطح سیستم:

  • Google DNS: 8.8.8.8، 8.8.4.4
  • Cloudflare DNS: 1.1.1.1، 1.0.0.1
  • Quad9: 9.9.9.9

در Linux تنظیمات از طریق /etc/resolv.conf انجام می‌شود:

nameserver 1.1.1.1
nameserver 8.8.8.8
options timeout:2 attempts:2

برای اسکریپت‌های Python با تعداد زیادی دامنه، توصیه می‌شود کش DNS را پیش‌گرم کنید:

import concurrent.futures
import socket

def warmup_dns_cache(domains):
    """پیش‌حل کردن لیست دامنه‌ها"""
    def resolve(domain):
        try:
            socket.gethostbyname(domain)
        except:
            pass
    
    with concurrent.futures.ThreadPoolExecutor(max_workers=20) as executor:
        executor.map(resolve, domains)

# لیست دامنه‌ها برای پارسینگ
domains = ['site1.com', 'site2.com', 'site3.com']
warmup_dns_cache(domains)

# حالا DNS در کش است، درخواست‌ها سریع‌تر خواهند بود

کیفیت زیرساخت ارائه‌دهنده

سرعت پروکسی به طور مستقیم به کیفیت تجهیزات و کانال‌های ارتباطی ارائه‌دهنده بستگی دارد. پروکسی‌های ارزان معمولاً بر روی سرورهای شلوغ با رابط‌های شبکه کند و سخت‌افزار قدیمی کار می‌کنند.

پارامترهای بحرانی زیرساخت:

پارامتر بد خوب تأثیر بر سرعت
پهنای باند کانال 100 مگابیت/ثانیه 1+ گیگابیت/ثانیه بحرانی در بارگذاری فایل‌ها
پردازنده سرور 2-4 هسته 8+ هسته بر روی پردازش SSL/TLS تأثیر می‌گذارد
RAM 4-8 گیگابایت 16+ گیگابایت کشینگ و بافرینگ
Uptime <95% 99%+ پایداری اتصالات
مسیر‌یابی استاندارد بهینه‌سازی شده BGP Latency و از دست دادن بسته‌ها

ارائه‌دهندگانی که زیرساخت خود را دارند (نه فروشندگان مجدد) معمولاً سرعت بالای ثابتی را ارائه می‌دهند. آن‌ها تمام استک را کنترل می‌کنند: از سخت‌افزار تا تنظیمات تجهیزات شبکه.

نشانه‌های زیرساخت با کیفیت:

  • سرعت پایدار در طول روز (انحرافات بیشتر از 15-20% از میانگین نباشد)
  • jitter کم (نوسان تأخیر) — کمتر از 10 میلی‌ثانیه
  • حداقل از دست دادن بسته‌ها (<0.1%)
  • واکنش سریع پشتیبانی فنی به مشکلات (مهم برای وظایف تجاری)
  • اطلاعات شفاف در مورد مکان سرورها و ویژگی‌های کانال‌ها

برای وظایف بحرانی توصیه می‌شود پروکسی‌ها را در شرایطی که به شدت به شرایط واقعی نزدیک است آزمایش کنید. دسترسی آزمایشی را برای 1-3 روز خریداری کرده و اسکریپت‌های واقعی را با نظارت بر تمام متریک‌ها اجرا کنید.

روش آزمایش سرعت پروکسی

آزمایش صحیح به شناسایی نقاط ضعف و مقایسه عینی ارائه‌دهندگان مختلف کمک می‌کند. یک speedtest ساده کافی نیست — باید پارامترهای مهم برای وظایف خود را اندازه‌گیری کنید.

متریک‌های کلیدی برای اندازه‌گیری:

  • Latency (تاخیر) — زمان عبور بسته به عقب و جلو. برای وظایف با تعداد زیادی درخواست‌های کوچک بحرانی است.
  • Throughput (پهنای باند) — حجم داده‌ها در واحد زمان. برای بارگذاری فایل‌ها و تصاویر مهم است.
  • Connection time — زمان برقراری اتصال. کارایی را برای درخواست‌های یکباره نشان می‌دهد.
  • Success rate — درصد درخواست‌های موفق. کمتر از 95% — نشانه بدی است.
  • Jitter — نوسان تأخیر. jitter بالا (>50 میلی‌ثانیه) نشان‌دهنده ناپایداری کانال است.

اسکریپت جامع برای آزمایش:

import time
import requests
import statistics
from concurrent.futures import ThreadPoolExecutor, as_completed

def test_proxy_performance(proxy, test_url='https://httpbin.org/get', requests_count=50):
    """
    آزمایش جامع پروکسی
    
    Args:
        proxy: URL پروکسی
        test_url: URL برای آزمایش
        requests_count: تعداد درخواست‌های آزمایشی
    
    Returns:
        dict با متریک‌ها
    """
    results = {
        'latencies': [],
        'connection_times': [],
        'total_times': [],
        'successes': 0,
        'failures': 0,
        'errors': []
    }
    
    session = requests.Session()
    session.proxies = {'http': proxy, 'https': proxy}
    
    def single_request():
        try:
            start = time.time()
            response = session.get(
                test_url,
                timeout=(5, 15),
                headers={'Connection': 'keep-alive'}
            )
            total_time = time.time() - start
            
            if response.status_code == 200:
                results['successes'] += 1
                results['total_times'].append(total_time)
                # تخمین تقریبی latency
                results['latencies'].append(total_time / 2)
            else:
                results['failures'] += 1
        except Exception as e:
            results['failures'] += 1
            results['errors'].append(str(e))
    
    # اجرای موازی درخواست‌ها
    with ThreadPoolExecutor(max_workers=10) as executor:
        futures = [executor.submit(single_request) for _ in range(requests_count)]
        for future in as_completed(futures):
            future.result()
    
    # محاسبه آمار
    if results['total_times']:
        metrics = {
            'proxy': proxy,
            'total_requests': requests_count,
            'success_rate': (results['successes'] / requests_count) * 100,
            'avg_response_time': statistics.mean(results['total_times']),
            'median_response_time': statistics.median(results['total_times']),
            'min_response_time': min(results['total_times']),
            'max_response_time': max(results['total_times']),
            'stdev_response_time': statistics.stdev(results['total_times']) if len(results['total_times']) > 1 else 0,
            'jitter': statistics.stdev(results['latencies']) if len(results['latencies']) > 1 else 0,
            'failures': results['failures']
        }
        return metrics
    else:
        return {'proxy': proxy, 'error': 'All requests failed'}

# آزمایش
proxy = 'http://user:pass@proxy.example.com:8080'
metrics = test_proxy_performance(proxy, requests_count=100)

print(f"پروکسی: {metrics['proxy']}")
print(f"نرخ موفقیت: {metrics['success_rate']:.1f}%")
print(f"میانگین زمان پاسخ: {metrics['avg_response_time']*1000:.0f} میلی‌ثانیه")
print(f"میانه: {metrics['median_response_time']*1000:.0f} میلی‌ثانیه")
print(f"Jitter: {metrics['jitter']*1000:.0f} میلی‌ثانیه")
print(f"انحراف معیار: {metrics['stdev_response_time']*1000:.0f} میلی‌ثانیه")

برای نتایج دقیق‌تر، در زمان‌های مختلف روز (صبح، روز، عصر) و بر روی سایت‌های هدف مختلف آزمایش کنید. سرعت ممکن است بسته به جغرافیا و بار شبکه به طور قابل توجهی متفاوت باشد.

نکته: یک خط پایه (baseline) ایجاد کنید — یک اتصال مستقیم بدون پروکسی را آزمایش کنید. این یک نقطه مرجع برای ارزیابی هزینه‌های پروکسی فراهم می‌کند. هزینه‌های نرمال: 50-150 میلی‌ثانیه برای پروکسی‌های با کیفیت.

بهینه‌سازی جامع: چک‌لیست

استفاده از تمام روش‌های توصیف شده به صورت ترکیبی اثر تجمعی دارد. در اینجا یک برنامه گام به گام برای بهینه‌سازی سرعت کار از طریق پروکسی آورده شده است:

گام 1: انتخاب و تنظیم پروکسی

  • پروکسی را جغرافیایی نزدیک به منابع هدف انتخاب کنید
  • برای وب‌پارسینگ از پروتکل HTTP به جای SOCKS5 استفاده کنید
  • پروکسی‌های خصوصی را برای وظایف با بار بالا ترجیح دهید
  • اطمینان حاصل کنید که ارائه‌دهنده TLS 1.3 را پشتیبانی می‌کند

گام 2: بهینه‌سازی کد

  • از requests.Session() با Keep-Alive استفاده کنید
  • تنظیمات connection pooling (10-20 اتصال) را پیکربندی کنید
  • تایم‌اوت‌های بهینه را تنظیم کنید: 5-10 ثانیه برای اتصال، 15-30 برای خواندن
  • منطق retry با exponential backoff را پیاده‌سازی کنید
  • حل DNS را کش کنید

گام 3: مدیریت استخر پروکسی

  • استخر 10-50 پروکسی برای چرخش ایجاد کنید
  • تعداد درخواست‌های همزمان از طریق یک پروکسی را محدود کنید (5-10 رشته)
  • سرعت را نظارت کرده و به طور خودکار پروکسی‌های کند را حذف کنید
  • برای وظایفی که نیاز به حفظ IP دارند، از sticky sessions استفاده کنید

گام 4: بهینه‌سازی سیستم

  • DNS‌های سریع (1.1.1.1، 8.8.8.8) را تنظیم کنید
  • محدودیت‌های فایل‌های باز در OS را افزایش دهید (ulimit -n 65535)
  • برای Linux: پارامترهای TCP هسته را بهینه کنید
  • اگر با حجم‌های بزرگ داده کار می‌کنید، از SSD برای کشینگ استفاده کنید

گام 5: نظارت و آزمایش

  • به طور منظم سرعت پروکسی را آزمایش کنید (حداقل یک بار در هفته)
  • متریک‌ها را ثبت کنید: زمان پاسخ، نرخ موفقیت، خطاها
  • عملکرد ارائه‌دهندگان مختلف را مقایسه کنید
  • هشدارها را در صورت کاهش سرعت زیر آستانه تنظیم کنید

مثال پیکربندی بهینه‌شده برای production:

import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from collections import deque
import time

class OptimizedProxyPool:
    def __init__(self, proxies_list):
        self.proxies = deque(proxies_list)
        self.session = self._create_optimized_session()
        self.stats = {p: {'requests': 0, 'avg_time': 0} for p in proxies_list}
    
    def _create_optimized_session(self):
        """ایجاد یک جلسه بهینه‌شده"""
        session = requests.Session()
        
        # استراتژی تلاش مجدد
        retry = Retry(
            total=3,
            backoff_factor=0.3,
            status_forcelist=[429, 500, 502, 503, 504],
            allowed_methods=["GET", "POST", "PUT"]
        )
        
        # آداپتور با connection pooling
        adapter = HTTPAdapter(
            max_retries=retry,
            pool_connections=20,
            pool_maxsize=50,
            pool_block=False
        )
        
        session.mount("http://", adapter)
        session.mount("https://", adapter)
        
        # هدرهای Keep-Alive
        session.headers.update({
            'Connection': 'keep-alive',
            'Keep-Alive': 'timeout=60, max=100'
        })
        
        return session
    
    def get_best_proxy(self):
        """دریافت پروکسی با بهترین عملکرد"""
        # مرتب‌سازی بر اساس سرعت میانگین
        sorted_proxies = sorted(
            self.stats.items(),
            key=lambda x: x[1]['avg_time'] if x[1]['requests'] > 0 else float('inf')
        )
        return sorted_proxies[0][0] if sorted_proxies else self.proxies[0]
    
    def request(self, url, method='GET', **kwargs):
        """انجام درخواست از طریق پروکسی بهینه"""
        proxy = self.get_best_proxy()
        self.session.proxies = {'http': proxy, 'https': proxy}
        
        start = time.time()
        try:
            response = self.session.request(
                method,
                url,
                timeout=(5, 15),  # connection, read
                **kwargs
            )
            
            # به‌روزرسانی آمار
            elapsed = time.time() - start
            stats = self.stats[proxy]
            stats['avg_time'] = (
                (stats['avg_time'] * stats['requests'] + elapsed) / 
                (stats['requests'] + 1)
            )
            stats['requests'] += 1
            
            return response
        except Exception as e:
            # در صورت خطا، پروکسی را به انتهای صف منتقل کنید
            self.proxies.remove(proxy)
            self.proxies.append(proxy)
            raise e

# استفاده
proxies = [
    'http://user:pass@proxy1.example.com:8080',
    'http://user:pass@proxy2.example.com:8080',
    'http://user:pass@proxy3.example.com:8080'
]

pool = OptimizedProxyPool(proxies)

# انجام درخواست‌ها
for url in ['https://example.com', 'https://example.org']:
    try:
        response = pool.request(url)
        print(f"موفق: {url}, وضعیت: {response.status_code}")
    except Exception as e:
        print(f"خطا: {url}, {e}")

استفاده از این چک‌لیست به افزایش سرعت کار از طریق پروکسی 2-3 برابر نسبت به تنظیمات پایه کمک می‌کند. در پروژه‌های واقعی پارسینگ، این زمان اجرای وظایف را از ساعت‌ها به دقیقه‌ها کاهش می‌دهد.

نتیجه‌گیری

عملکرد کند پروکسی یک مشکل قابل حل است، اگر دلایل فنی را درک کرده و روش‌های بهینه‌سازی صحیح را به کار ببرید. عوامل اصلی سرعت: نزدیکی جغرافیایی، انتخاب پروتکل، کیفیت زیرساخت ارائه‌دهنده و تنظیمات صحیح کد مشتری هستند.

رویکرد جامع به بهینه‌سازی شامل...

```