متعادلکننده (Balancer)
متعادلکننده یک گروه خروجی است که اتصالها را میان اعضایش پخش میکند. برای هر اتصال یک عضو
را برمیگزیند و برای این کار از نتایج تست پایش هیدیفای استفاده میکند.
این یک outbound است: "type": "balancer" در فهرست outbounds.
چرا از آن استفاده کنیم
- ترافیک را میان چند سرور پخش کنید، بهجای اینکه همهاش روی یکی باشد.
- هر سایت، یا هر دستگاه و سایت، روی یک سرور بماند تا ورودها و نشستها قطع نشوند.
- همیشه از سریعترین سرور استفاده کنید، بدون برنامهٔ تست جداگانهٔ گروه URL test.
اپ هیدیفای از آن برای گروههای «کمترین تأخیر» و «تقسیم بار» استفاده میکند.
چطور از فیلترینگ عبور میکند
خودش عبور نمیدهد. فقط میان خروجیهایی انتخاب میکند که این کار را میکنند. وقتی بعضی از سرورهای شما مسدودند کمک میکند: اعضایی که در تست رد میشوند کنار گذاشته میشوند.
چطور کار میکند
پایش همهٔ خروجیها را تست میکند و نتیجه را به گروه میدهد. متعادلکننده برای هر عضو از تأخیر آخرین تست استفاده میکند:
- عضوی که در تست رد شده، یا هنوز نتیجهٔ تستی ندارد، مرده حساب میشود.
- به نتیجهای که هنگام شروع از کش خوانده شده و هنوز دوباره تست نشده، ۲۰٬۰۰۰ میلیثانیه اضافه میشود. تست تازه همیشه بر نتیجهٔ قدیمی برتری دارد.
- تأخیر قابلقبول برابر است با تأخیر سریعترین عضو (دستکم ۱۰۰ میلیثانیه) ضرب در
delay_acceptable_ratio. این مقدار همیشه زیر مقدار timeout میماند، پس عضو مرده هرگز قابلقبول نیست. عضوی که تأخیرش از تأخیر قابلقبول بیشتر نباشد، زنده حساب میشود.
برای اتصالهای UDP، گروه فقط از اعضایی استفاده میکند که UDP را پشتیبانی میکنند، اگر چنین عضوی باشد.
وقتی باز کردن اتصال از طریق یک عضو ناموفق باشد، آن عضو بیدرنگ دوباره تست میشود. اتصال روی عضو دیگری تکرار نمیشود.
کدام اتصالها بسته میشوند
هر اتصال زیر عضوی که از آن رفته ردیابی میشود. عضوی که سریعتر شده فقط اتصالهای تازه را میگیرد: هیچ اتصالی به خاطر سرعت بسته نمیشود، پس تماس یا دانلودی که از سرور سالمی میرود ادامه مییابد. اتصالها فقط در دو حالت بسته میشوند:
- عضوی که تستش شکست میخورد اتصالهایش بسته میشود؛ اتصالهای اعضای دیگر میمانند.
- یک بار پس از شروع: تستهای اول ممکن است انتخاب را چند بار جابهجا کنند، در حالی که
اتصالهایی که روی انتخاب موقت باز شدهاند هنوز روی آن هستند. ۳۰ ثانیه پس از شروع، وقتی
عضوی نتیجهای از همین اجرا دارد، اتصالهای اعضایی که گروه دیگر استفاده نمیکند (در
lowest-delayاعضای انتخابنشده، در بقیه اعضای بیرون از تأخیر قابلقبول) یک بار بسته میشوند. تا وقتی نتیجهای از این اجرا نباشد، این کار تا بهروزرسانی بعدی صبر میکند.
interrupt_exist_connections میگوید در این حالتها اتصالهایی هم که از inboundها آمدهاند
بسته شوند یا نه؛ اتصالهایی که درون خود sing-box باز شدهاند همیشه بسته میشوند.
هنگام دورهٔ تست
نتیجههای یک دورهٔ تست منظم یکییکی میرسند. lowest-delay و round-robin هر کدام را همان لحظه به کار نمیبرند: تا وقتی دوره در جریان است، عضوهایی را که به کار میبرند تا وقتی در این اجرا پاسخ میدهند نگه میدارند، و وقتی دوره تمام شد با همهٔ نتیجهها دوباره انتخاب میکنند. عضوِ در حال استفادهای که ناموفق شود، یا هنوز نتیجهای از این اجرا ندارد (در شروع، عضو کششده یا عضو اول)، همان لحظه با بهترین عضوی که تا آن وقت شناخته شده جایگزین میشود، تا دوره تمام شود و بهترینِ همه انتخاب شود. lowest-delay فقط تا وقتی نگه میدارد که دوره عضوِ در حال استفاده را تست کند: از آن پس عضو سریعتر همان لحظه انتخاب را میگیرد، مثل بیرون از دوره. نگه داشتن در تمام دوره، عضوی را که وقتی عضو سریع پاسخ نمیداد (تست ناموفق) انتخاب شده بود، تا مدتها پس از پاسخ دوبارهٔ عضو سریع نگه میداشت. تستهای بیرون از دوره، مثل تستی که کاربر میخواهد، همان لحظه اعمال میشوند.
دورهٔ اول پس از شروع، و دورهای که پس از تغییر شبکه اجرا میشود، نگه داشته نمیشوند: هنوز انتخابی نیست که ارزش نگه داشتن داشته باشد، و هر نتیجه همانطور که میرسد، پس از debounce رویدادهای گروه، به کار میرود.
هیدیفایکور گروه round-robin را در برنامه با سریعترین عضوش نشان میدهد و آن عضو را نگه میدارد تا عضو دیگری بیش از بزرگترِ ۵۰ میلیثانیه و یکدهم تأخیرش سریعتر باشد، یا خودش دیگر پاسخ ندهد؛ هنگام دورهٔ منظم، تا وقتی دیگر پاسخ ندهد.
راهبردها
round-robin(پیشفرض): اعضا بر اساس تأخیر مرتب میشوند و اتصالها به نوبت میان اعضای زنده میچرخند. تا رسیدن اولین نتایج تست، همهٔ اعضا به ترتیب پیکربندی نوبت میگیرند.lowest-delay: همهٔ اتصالها از عضوی با کمترین تأخیر میروند. در شروع، عضوی استفاده میشود که در نتایج کششده سریعترین بوده، و اگر نتیجهای نباشد عضو اول. آن عضو تا وقتی پاسخ میدهد نگه داشته میشود: عضو دیگری فقط وقتی انتخاب را میگیرد که هم بیش ازtoleranceو هم بیش ازtolerance_ratioاز تأخیر عضو انتخابشده سریعتر باشد (هر کدام بزرگتر است)، پس نوسان پینگ بین دو سرور نزدیک به هم گروه را جابهجا نمیکند. عضوی که تستش شکست خورده بیدرنگ به نفع سریعترین عضو زنده رها میشود؛ وقتی هیچ عضوی زنده نباشد، انتخاب همان میماند. عضوی که با پینگ واقعی انتخاب را گرفته تا وقتی پاسخ میدهد ۳۰ ثانیه میماند، هر نتیجهٔ سریعتری هم که برسد، و بعد بهترینِ شناختهشده جایش را میگیرد: نتیجههای دورهٔ اول یکییکی میرسند و انتخاب با هر نتیجهٔ سریعتر میپرید. پینگی که از اجرای قبل کش شده هیچ تصمیمی نمیگیرد و نشان داده نمیشود: فقط عضوها را تا رسیدن پینگهای واقعی مرتب میکند (انتخاب اول در شروع، و ترتیب تست دوره). انتخاب کششده به نفع کششدهٔ بهتر و به نفع اولین پینگ واقعیِ موفق، هرچقدر هم کند، رها میشود؛ پینگ کششده هرگز عضوی را که پینگ واقعیاش پاسخ میدهد نمیگیرد.consistent-hashing: عضو از روی مقصد انتخاب میشود: دامنهٔ قابلثبت آن (مثلاًexample.comبرایwww.example.com) یا نشانی IP آن. یک مقصد تا وقتی عضوش زنده است همیشه همان عضو را میگیرد. اگر مرده باشد، گروه تاmax_retryانتخاب دیگر از هش را امتحان میکند و سپس اولین عضو زندهٔ فهرست را. اگر هیچ عضوی زنده نباشد، باز هم همان عضو هششده را به کار میبرد.sticky-sessions: عضو از روی آنچهsticky_hashنام میبرد انتخاب میشود، بدون تنظیم نشانی مبدأ و مقصد با هم. یک کلید تازه عضوی تصادفی میگیرد و گروه آن را، برای حداکثر ۱٬۰۰۰ کلید، به مدتttlبه خاطر میسپارد. اگر عضو بهخاطرسپرده مرده باشد، با عضو زندهٔ دیگری جایگزین میشود که به همان روش بالا انتخاب میشود.pool: تعداد ثابتی جایگاه (pool، بهطور پیشفرض ۳، حداکثر به تعداد اعضا) که هر کدام را یک عضو سالم در دست دارد. هر اتصال به جایگاهی میرود که با هش آنچهsticky_hashنام میبرد انتخاب شده، پس یک برنامه یا سایت عضوش را نگه میدارد.- عضو تا وقتی پاسخ میدهد جایگاهش را نگه میدارد، پس اتصالهای جایگاههای دیگر هرگز جابهجا نمیشوند.
- عضو مرده در جایگاهش با یک عضو سالم بیرون از pool جایگزین میشود. تا وقتی چنین عضوی نباشد، آن جایگاه رد میشود: اتصالهایش، هر بار به همان شکل، میان جایگاههای سالم پخش میشوند و وقتی عضو دوباره پاسخ دهد برمیگردند.
- بدون
tolerance، جایگاهها اولین اعضای سالم را به ترتیب پیکربندی نگه میدارند. با آن، عضو بیرونی فقط وقتی جای عضو یک جایگاه را میگیرد که بیش ازtoleranceوtolerance_ratioاز تأخیر عضو جایگاه سریعتر باشد، مثلlowest-delay. sticky_hashفهرستی ازprocess،domain(دامنهٔ قابلثبت)،source_ip،dest_ipوdest_portاست؛ پیشفرض pool["process", "domain"]است.["none"]اتصالها را به نوبت (round-robin) میان جایگاههای سالم میفرستد.- پر کردن دوبارهٔ یک جایگاه اتصالها را قطع نمیکند.
پیکربندی
{
"type": "balancer",
"tag": "balance",
"outbounds": ["server-a", "server-b", "server-c"],
"strategy": "round-robin",
"delay_acceptable_ratio": 2
}
| فیلد | نوع | پیشفرض | معنی |
|---|---|---|---|
outbounds |
list of strings | الزامی | تگ اعضا. |
strategy |
string | "round-robin" |
round-robin، lowest-delay، consistent-hashing، sticky-sessions یا pool. |
pool |
int | 3 |
برای pool: تعداد جایگاهها. |
sticky_hash |
list of strings | pool ["process", "domain"]، sticky-sessions ["source_ip", "domain"] |
برای pool و sticky-sessions: اتصال بر چه اساسی به عضوش میچسبد. ["none"] چسبیدن را خاموش میکند. |
delay_acceptable_ratio |
number | 2 |
یک عضو چقدر میتواند از سریعترین عضو کندتر باشد و باز هم استفاده شود. 2 یعنی تا دو برابر تأخیر سریعترین. خالی یا 0 همان 2 است. |
max_retry |
int | 0 |
برای consistent-hashing و sticky-sessions: چند انتخاب دیگر از هش، پیش از رفتن سراغ فهرست، امتحان شود. |
ttl |
duration | 0 (بدون انقضا) |
برای sticky-sessions: هر جفت چه مدت عضوش را نگه میدارد. |
interrupt_exist_connections |
bool | false |
وقتی عضوی میمیرد، یا در همان یک جابهجایی پس از شروع، اتصالهایی را هم که از inboundها آمدهاند ببند. بدون آن، فقط اتصالهایی بسته میشوند که درون خود sing-box باز شدهاند. |
tolerance |
int | 50 |
برای lowest-delay: عضو دیگر چند میلیثانیه باید سریعتر باشد تا انتخاب را بگیرد. |
tolerance_ratio |
number | 0.1 |
برای lowest-delay: عضو دیگر چه سهمی از تأخیر عضو انتخابشده باید سریعتر باشد تا انتخاب را بگیرد. بزرگترِ دو تلرانس اعمال میشود. |