استخرهای اتصال و تاخیر
استخرهای اتصال و تاخیر
1) چرا استخر مورد نیاز است
اتصالات گران هستند (TCP/TLS دست دادن، احراز هویت، گرم کردن). استخر اجازه می دهد:- استفاده مجدد از اتصالات آماده (نگه داشتن زنده) → زیر TTFB.
- کنترل همزمان و فشار دادن به عقب به جای بهمن عقب نشینی.
- کاهش دم p95/p99 به دلیل اندازه و زمان درست.
خطرات کلیدی: صف های انتظار در استخر، مسدود کردن سر خط، محتوا برای اتصالات و طوفان عقب نشینی.
2) پایه ریاضی: نحوه شمارش اندازه استخر
ما از قانون لیتل استفاده میکنیم: «L = λ × W». برای یک استخر، این به این معنی است:- «λ» جریان متوسط درخواست (RPS) است.
- «W» میانگین اتصال مشغول در هر درخواست (زمان سرویس، از جمله تأخیر شبکه و عملیات سرویس از راه دور) است.
- حداقل اندازه استخر 'N _ min ≈ λ × W' است.
- اضافه کردن یک حاشیه برای تغییرات و p99: headroom 20-50٪.
- مثال: 300 RPS، میانگین زمان نگهداری 40 ms → 'N _ min = 300 × 0. 04 = 12`. با حاشیه 50٪، 18 اتصالات →
اگر دم ها بزرگ هستند: «W _ p95» یا «W _ p99» را برای مسیرهای بحرانی در نظر بگیرید - استخرها رشد می کنند.
3) اصول طراحی عمومی
1. مسیر داده کوتاه: استفاده مجدد (نگه داشتن زنده، multiplexing HTTP/2/3).
2. محدودیت موازی: بهتر است به سرعت (429/503) را رد کنید تا به عقب برگردید.
3. Timeouts> retreats: تنظیم زمان های کوچک و عقب نشینی های نادر jitter.
4. صفهای مشتری کوتاهتر از صفهای سرور هستند (fail-fast سریع).
5. فشار پشتی: هنگامی که استخر پر است - بلافاصله NACK/error/collbeck «later».
6. جداسازی استخر توسط اهداف: DB، کش، PSP خارجی - محدودیت های آنها.
4) HTTP/1 1 در مقابل HTTP/2/3، زنده نگه داشتن
HTTP/1 است. 1: یک درخواست اتصال در یک زمان (عملا) ؛ نیاز به یک استخر با اتصالات متعدد در هر میزبان.
HTTP/2: جریان چندگانه در یک TCP ؛ اتصالات کمتر، اما مسدود کردن HOL در TCP ممکن است زمانی که بسته ها از دست رفته اند.
HTTP/3 (QUIC): استقلال جریان بیش از UDP - مشکلات HOL کمتر، بایت اول سریعتر.
- نگه داشتن زمان زنده 30-90s (توسط مشخصات)، محدودیت درخواست برای اتصال (بازیافت برازنده).
- پیش گرم کردن (preconnect) در شروع کار
- حداکثر جریان در هر HTTP/2 را محدود کنید (به عنوان مثال 100-200).
nginx upstream backend {
server app-1:8080;
server app-2:8080;
keepalive 512;
keepalive_requests 1000;
keepalive_timeout 60s;
}
proxy_http_version 1. 1;
proxy_set_header Connection "";
فرستاده (استخر HTTP/2):
yaml http2_protocol_options:
max_concurrent_streams: 200 common_http_protocol_options:
idle_timeout: 60s max_connection_duration: 3600s
5) DB Pools: PgBouncer، HikariCP، رانندگان
هدف محدود کردن معاملات رقابتی و حفظ اتصال کوتاه است.
5. 1 PgBouncer (PostgreSQL)
حالت ها: «جلسه »/« معامله »/« بیانیه». برای API - اغلب معامله.
پارامترهای مهم عبارتند از «pool _ size»، «min _ pool _ size»، «reserve _ pool _ size»، «server _ idle _ timeout»، «query _ wait _ timeout».
ini
[databases]
appdb = host=pg-primary port=5432 dbname=appdb
[pgbouncer]
pool_mode = transaction max_client_conn = 5000 default_pool_size = 100 min_pool_size = 20 reserve_pool_size = 20 query_wait_timeout = 500ms server_idle_timeout = 60 server_reset_query = DISCARD ALL
5. 2 HikariCP (جاوا)
اتصالات کوچک و سریع، وقفه های سخت.
properties dataSourceClassName=org. postgresql. ds. PGSimpleDataSource maximumPoolSize=30 minimumIdle=5 connectionTimeout=250 validationTimeout=200 idleTimeout=30000 maxLifetime=1800000 leakDetectionThreshold=5000
قوانین و مقررات:
- 'maximumPoolSize ≈ RPS × W × headroom'.
- اتصال، وقفه، تعداد زیادی از میلی ثانیه، نه ثانیه.
- فعال کردن تشخیص نشت.
5. 3 برو/گره/پایتون - نمونه
برو HTTP. مشتری) استفاده مجدد + وقفه (:go tr:= &http. Transport{
MaxIdleConns: 512,
MaxIdleConnsPerHost: 128,
IdleConnTimeout: 60 time. Second,
TLSHandshakeTimeout: 2 time. Second,
}
c:= &http. Client{
Transport: tr,
Timeout: 2 time. Second ,//general
}
گره ها مامور زنده نگه داشتن:
js const http = require('http');
const agent = new http. Agent({ keepAlive: true, maxSockets: 200, maxFreeSockets: 64, timeout: 60000 });
psycopg/SQLAlchemy (پایتون):
python engine = create_engine(
url, pool_size=30, max_overflow=10, pool_recycle=1800, pool_pre_ping=True, pool_timeout=0. 25
)
6) صف انتظار و تاخیر دم
Tails زمانی رخ می دهد که:- استخر کوچکتر از «λ × W» است → صف اتصال در حال رشد است.
- ناهمواری بار (انفجار) بدون بافر و محدودیت.
- درخواست های طولانی اتصال را می گیرند و یک HOL ایجاد می کنند.
- استخرهای جداگانه بر اساس نوع درخواست (سریع/آهسته).
- پیادهسازی یک اتمام وقت سمت مشتری. اگر منقضی شده - سریع NACK.
- تشخیص و قطع مدار در مسیرها (Envoy، HAProxy).
- سهمیه برای مسیرهای «سنگین»، یک استخر جداگانه برای گزارش/صادرات.
yaml circuit_breakers:
thresholds:
- priority: DEFAULT max_connections: 200 max_pending_requests: 100 max_requests: 1000 max_retries: 2
7) زمان و عقب نشینی (سفارش صحیح)
1. قطع وقت اتصال (کوتاه: 50-250 میلی ثانیه در داخل DC).
2. TLS handshake timeout (500-1000 ms вне DC).
3. درخواست/خواندن زمان (نزدیک به SLO مسیر).
4. تکرار: حداکثر 1 بار، فقط برای روش های idempotent ؛ جرقه + عقب نشینی.
5. بودجه Retray: حد جهانی به عنوان یک درصد از RPS (به عنوان مثال، ≤ 10٪).
8) زنده نگه داشتن، ناگل، پروتکل ها
غیرفعال کردن ناگل (TCP_NODELAY) برای RPC های پیام کوچک.
فعال کردن HTTP keep-alive در هر کجا که ممکن است.
TIME_WAIT را تماشا کنید - فقط اگر عواقب را درک کنید، «استفاده مجدد »/« بازیافت» را تنظیم کنید. بهتر - استفاده مجدد از اتصالات، نه تنظیم هسته.
TLS - از ادامه جلسه و ALPN استفاده کنید.
9) تنظیم OS/Kernel (با احتیاط)
شبکه است. هسته ای. «سوماکسکان»، «نت». IPV4 ip_local_port_range'، تور. IPV4 tcp_fin_timeout' است.
توصیف کننده ها: «nofile» ≥ 64k در هر فرآیند پروکسی.
تعادل IRQ، GRO/LRO - توسط مشخصات ترافیک.
اولویت - مشخصات ؛ تنظیم بدون معیارها اغلب مضر است.
10) قابلیت مشاهده: آنچه باید اندازه گیری شود
استفاده از استخر: مشغول/کل، اتصال P50/P95 در انتظار.
درخواست های پرواز و زمان نگهداری آنها (برش مسیر).
بودجه خطای Retray: نسبت تکرارها.
ریزش اتصال ایجاد/بستن در هر ثانیه.
TCP/TLS: SYN RTT، دست دادن، استفاده مجدد از جلسه.
Для БД: اتصالات فعال، انتظار، معاملات طولانی، قفل.
Графики: «RPS vs pool wait»، «توزیع زمان نگهداری»، «نسبت استفاده مجدد»، «سفرهای مدار».
11) دستور العمل های مورد
11. 1 API دروازه → باطن
HTTP/2 به backends، «max _ concurrent _ streams = 200».
یک استخر از 20-40 اتصال در هر سرویس در هر گره دروازه.
Timeouts: اتصال 100ms، در هر تلاش 300-500ms، به اشتراک گذاشته 1-2s، 1 تلاش مجدد با لرزش.
11. 2 PostgreSQL → خدمات از طریق PgBouncer
'pool _ mode = transaction', 'default _ pool _ size' بر اساس فرمول (RPS × W × 1. 3).
در «connectionTimeout≤250ms»، معاملات کوتاه (<100ms).
درخواست گزارش سنگین - استخر جداگانه/ماکت.
11. 3 gRPC داخلی
یک کانال (HTTP/2) در هر میزبان هدف با محدودیت موضوع 100-200.
مهلت در RPC در مسیر SLO، retray تنها idempotent.
نمونه برداری ردیابی RPC طولانی و معیارهای زمان نگهداری.
12) چک لیست پیاده سازی (0-30 روز)
0-7 روز
اندازه گیری «W» (زمان نگهداری) در مسیرهای کلیدی/مشتریان.
محاسبه 'N _ min = λ × W' و اضافه کردن 30-50٪ headroom.
فعال کردن زنده ماندن و قطع اتصال کوتاه.
8-20 روز
استخرهای جداگانه (سریع/آهسته/خارجی).
قطع کننده های مدار و بودجه های بازپرداخت را تایپ کنید.
داشبورد را اضافه کنید: استخر منتظر p95، نسبت استفاده مجدد، در پرواز.
21-30 روز
بار اجرا می شود با انفجار، آزمون هرج و مرج «سقوط از باطن».
بهینه سازی دم: جداسازی مسیرهای سنگین، انبارهای محلی.
فرمولها و محدودیتهای سند در runbook 'ax.
13) ضد الگوهای
اندازه استخر «به صورت تصادفی» و بدون سر و صدا.
زمان انتظار اتصال بزرگ → دم طولانی به جای شکست سریع.
بسیاری از عقب نشینی بدون لرزش و idemotency → طوفان.
یک استخر مشترک برای تمام انواع درخواست.
معاملات طولانی اتصال (DB) → گرسنگی بقیه را حفظ می کند.
غیرفعال نگه داشتن زنده یا بیکار خیلی کوچک → محدودیت های ریزش و رشد TTFB.
14) معیارهای بلوغ
استخر صبر کنید p95 در prod <10% از کل مسیر p95.
نسبت استفاده مجدد (> 90٪ برای HTTP داخلی ؛> 80٪ برای خارجی).
DB txn زمان p95 <100-200 ms ؛ درصد معاملات طولانی <1٪.
نرخ تکرار <5٪ (و ≤ بودجه)، خطاهای ناشی از وقفه ها پایدار و قابل پیش بینی هستند.
حل و فصل استخر مستند برای همه مشتریان مهم است.
15) نتیجه گیری
اتصال موثر اتصال به صف مهندسی + نظم و انضباط timeout است. اندازه گیری 'W'، محاسبه استخر 'λ × W' با حاشیه، روشن کردن keep-alive/HTTP2 +، مسیرهای آهسته جداگانه، نگه داشتن timeouts کوتاه و حداقل retras با jitter. اضافه کردن «استخر انتظار در مقابل تاخیر» قابلیت مشاهده و قطع کننده مدار - و شما TTFB کم، دم P99 کنترل و مقاومت در برابر افزایش بدون backends بیش از حد.