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

پراکسی برای تست بار در k6 و JMeter: تنظیمات و محدودیت‌های روش

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

📅۱۲ آبان ۱۴۰۵

وقتی تست بار به محدودیت نرخ، WAF یا تعادل جغرافیایی می‌رسد، اولین فکر این است که «ترافیک را با IPهای مختلف راه‌اندازی کنم». به نظر منطقی می‌آید، اما در عمل پروکسی در k6 و JMeter فقط مجموعه محدودی از وظایف را حل می‌کند و بقیه را باید با معماری تست تعمیر کرد. در این مقاله بررسی می‌کنیم که چگونه به‌طور فنی پروکسی را به هر دو ابزار متصل کنیم، چه نوع IPهایی برای این کار مناسب هستند و مسئولیت پروکسی سرور کجا به پایان می‌رسد.

چرا تست بار به IPهای مختلف نیاز دارد

به‌طور پیش‌فرض k6 و JMeter تمام ترافیک را از یک IP آدرس ارسال می‌کنند — سروری که تست روی آن اجرا می‌شود (یا ماشین ابری در CI/CD). این برای 90% سناریوها عادی است، اما در چند مورد یک IP کافی نیست:

  • محدودیت نرخ در سطح IP. بسیاری از APIها و تعادل‌کننده‌ها (nginx limit_req، AWS WAF، Cloudflare) تعداد درخواست‌ها را از یک آدرس در ثانیه محدود می‌کنند. کاربران واقعی از هزاران IP مختلف می‌آیند، اما تست شما از یک IP می‌آید و زودتر به محدودیت می‌رسد تا به گلوگاه واقعی برنامه.
  • تست منطق وابسته به جغرافیا. CDN، محتوای هدفمند، قیمت‌های منطقه‌ای، geo-blocking — همه اینها باید با IP از کشورهای خاص بررسی شوند، نه از دیتاسنتری که تست رانر شما فیزیکی در آن قرار دارد.
  • بررسی تعادل‌کننده و شبکه anycast. اگر زیرساخت ترافیک را بر اساس IP مشتری در مناطق توزیع کند، تست از یک آدرس فقط یک مسیر را بررسی می‌کند، نه تمام شبکه.
  • شبیه‌سازی توزیع واقعی ترافیک. ترافیک تولیدی IPها را بین ارائه‌دهندگان، زیرشبکه‌ها و گاهی اوقات بین اپراتورهای موبایل توزیع می‌کند — این بر رفتار CDN، کش‌ها و منطق edge تأثیر می‌گذارد.

مهم است که بلافاصله تفکیک کنید: اگر شما در حال تست عملکرد backend هستید (چقدر RPS API شما تحمل می‌کند)، پروکسی تقریباً هرگز لازم نیست — در آنجا بار خالص مهم است، نه تنوع منابع. پروکسی زمانی لازم است که سناریوی تست دقیقاً به IP آدرس مشتری وابسته باشد.

کدام پروکسی‌ها مناسب هستند: دیتاسنتر، مسکونی، موبایل

انتخاب نوع پروکسی به‌طور مستقیم بر آنچه که شما تست می‌کنید تأثیر می‌گذارد — ظرفیت زیرساخت یا رفتار سیستم تحت IPهای «زنده».

نوع پروکسی تاخیر و سرعت کی باید در تست‌های بار استفاده شود
پروکسی دیتاسنتر تاخیر کم، ظرفیت بالا بررسی محدودیت نرخ، دور زدن محدودیت «N درخواست از IP»، تولید حجم بالای RPS از زیرشبکه‌های مختلف
پروکسی‌های مسکونی تاخیر بیشتر، سرعت محدود به کانال کاربر واقعی تست منطق جغرافیایی، بررسی CDN و سیستم‌های ضد ربات که به دامنه‌های مسکونی بیشتر از دیتاسنتر اعتماد دارند
پروکسی‌های موبایل بالاترین تاخیر، سرعت ناپایدار سناریوهای خاص: تست API موبایل، رفتار در هنگام تغییر مکرر IP (اپراتورها آدرس مشتری را به‌طور دینامیک تغییر می‌دهند)

برای بررسی خالص RPS و محدودیت نرخ تقریباً همیشه پروکسی دیتاسنتر کافی است — آنها تاخیر پایینی و ثابتی را ارائه می‌دهند و نتایج تست را با ناپایداری شبکه خارجی تحریف نمی‌کنند. IPهای مسکونی و موبایل واقع‌گرایی را در تست‌های جغرافیایی اضافه می‌کنند، اما تاخیر خاص خود را به همراه دارند که باید در تجزیه و تحلیل متریک‌ها در نظر گرفته شود — در غیر این صورت به راحتی می‌توان «شبکه پروکسی کند است» را با «سرور شما کند است» اشتباه گرفت.

تنظیم پروکسی در k6

k6 یک ابزار مبتنی بر JavaScript است (موتور آن به زبان Go نوشته شده و اسکریپت‌ها به زبان JS نوشته می‌شوند) و به‌طور پیش‌فرض پشتیبانی داخلی از پروکسی HTTP از طریق گزینه‌های اسکریپت ندارد: پروکسی در k6 از طریق متغیرهای محیطی یا تنظیمات سیستم تعیین می‌شود، زیرا در زیر کاپوت k6 از کلاینت HTTP زبان Go استفاده می‌کند.

ساده‌ترین روش — متغیرهای محیطی:

export HTTP_PROXY="http://login:password@proxy-host:port"
export HTTPS_PROXY="http://login:password@proxy-host:port"

k6 run script.js

این روش تمام ترافیک تست را از طریق یک پروکسی هدایت می‌کند — مناسب است اگر شما فقط نیاز دارید که از IP «سفید» سرور خارج شوید. اما اگر هدف توزیع کاربران مجازی (VU) بین IPهای مختلف باشد، به یک لیست پروکسی و منطق انتخاب در سطح اسکریپت نیاز دارید. k6 به‌طور مستقیم از پروکسی per-VU «از جعبه» پشتیبانی نمی‌کند، بنابراین راه‌حل رایج این است که چندین فرآیند k6 را به‌طور همزمان اجرا کنید، هر کدام با متغیر محیطی خود و پروکسی خود از استخر:

// run-with-proxies.sh
PROXIES=("proxy1:port" "proxy2:port" "proxy3:port")

for proxy in "${PROXIES[@]}"; do
  HTTP_PROXY="http://user:pass@$proxy" \
  HTTPS_PROXY="http://user:pass@$proxy" \
  k6 run --vus 50 --duration 5m script.js &
done
wait

این رویکرد به خوبی در کنار k6 Cloud یا ارکستراسیون از طریق Kubernetes/Docker Compose مقیاس‌پذیر است — هر کانتینر با متغیر پروکسی خود راه‌اندازی می‌شود. اگر نیاز به چرخش IP در یک اجرای اسکریپت باشد، منطقی‌تر است که پروکسی را با چرخش در سمت خود ارائه‌دهنده پروکسی بگیرید (جلسه چسبنده با TTL)، نه اینکه چرخش را درون کد JS ایجاد کنید.

تنظیم پروکسی در JMeter

در JMeter پروکسی به‌طور بومی، بدون متغیرهای محیطی، از طریق عنصر HTTP Request Defaults یا به‌طور مستقیم در تنظیمات HTTP Request Sampler تنظیم می‌شود:

  1. عنصر پیکربندی HTTP Request Defaults را به Thread Group اضافه کنید.
  2. در فیلدهای Proxy Server میزبان و پورت پروکسی را مشخص کنید.
  3. اگر پروکسی نیاز به احراز هویت دارد — عنصر HTTP Authorization Manager را با نام کاربری و رمز عبور برای این میزبان اضافه کنید.
  4. تمام HTTP Request Samplers درون Thread Group به‌طور خودکار تنظیمات پروکسی را به ارث می‌برند.

برای توزیع بار بین چندین پروکسی در JMeter، استفاده از CSV Data Set Config راحت است — فایلی با لیست پروکسی به متغیرهای میزبان و پورت برای هر رشته اضافه می‌شود:

proxy_host,proxy_port,proxy_user,proxy_pass
proxy1.example.com,8000,user1,pass1
proxy2.example.com,8000,user2,pass2
proxy3.example.com,8000,user3,pass3

CSV Data Set Config را به Thread Group متصل کنید، متغیرهای ${proxy_host} و ${proxy_port} را در فیلدهای Proxy Server/Proxy Port سمپلر مشخص کنید — هر رشته JMeter خط خود را از فایل می‌گیرد و از طریق IP خود می‌رود. برای راه‌اندازی از طریق خط فرمان (حالت headless، که برای اجراهای بار واقعی توصیه می‌شود) پروکسی همچنین می‌تواند با پرچم‌ها منتقل شود:

jmeter -n -t test_plan.jmx -l results.jtl \
  -H proxy-host -P port \
  -u username -a password

این روش یک پروکسی مشترک برای کل تست تعیین می‌کند — برای سناریوهای چند پروکسی، به هر حال باید از CSV Data Set Config یا تست توزیع شده (چندین JMeter-برده، هر کدام با پروکسی خود در پیکربندی) استفاده کنید.

چرخش IP و توزیع بار

دو رویکرد اصولی متفاوت برای توزیع IP در تست بار وجود دارد:

  • چسباندن ثابت IP به رشته/VU. هر کاربر مجازی یک IP یکسان در طول جلسه دریافت می‌کند — شبیه‌سازی یک کاربر واقعی با یک آدرس. از طریق پروکسی جلسه چسبنده یا فقط یک لیست ثابت در CSV/متغیرهای محیطی تنظیم می‌شود.
  • چرخش IP برای هر درخواست. پروکسی آدرس خروجی را برای هر درخواست HTTP تغییر می‌دهد — برای بررسی حفاظت در برابر محدودیت نرخ مفید است، اما به‌خوبی رفتار واقعی کاربران را منعکس نمی‌کند، که IP آنها هر ثانیه تغییر نمی‌کند.

برای یک تست بار واقع‌گرایانه در 90% موارد بهتر است IP را برای VU/رشته در طول جلسه ثابت نگه دارید — اینگونه تست به‌طور عادلانه رفتار تعداد زیادی از کاربران مستقل را منعکس می‌کند و نه اینکه نویز مصنوعی ایجاد کند. چرخش برای هر درخواست تنها در سناریوهای خاص منطقی است — مثلاً در بررسی هدفمند برای فعال شدن قوانین محدودیت نرخ.

چیزهایی که پروکسی قطعاً جایگزین نمی‌کند

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

  • ظرفیت تست رانر شما. اگر تولیدکننده بار (خود ماشین با k6/JMeter) به CPU، حافظه یا کارت شبکه برخورد کند — پروکسی این را اصلاح نمی‌کند. پروکسی یک پرش شبکه اضافی و تاخیر خود را اضافه می‌کند، نه اینکه بار را از رانر بردارد.
  • ظرفیت واقعی سرور تست شده. سرور یا بار را تحمل می‌کند یا نه — آدرس IP مشتری بر این موضوع تأثیری ندارد، به جز در موارد محدودیت نرخ واضح بر اساس IP.
  • دقت متریک‌های زمان پاسخ. پروکسی تاخیر خود را اضافه می‌کند (به‌ویژه مسکونی و موبایل)، که به گزارش‌های شما به‌عنوان بخشی از زمان پاسخ وارد می‌شود. اگر تاخیر پروکسی به‌طور جداگانه کسر نشود، گزارش نهایی تاخیر تحریف خواهد شد و برای مقایسه با متریک‌های تولیدی غیرقابل استفاده خواهد بود.
  • مقیاس‌پذیری زیرساخت برای ترافیک واقعی. تست بار با پروکسی رفتار را تحت یک الگوی خاص از درخواست‌ها نشان می‌دهد، اما جایگزین برنامه‌ریزی ظرفیت، مقیاس‌پذیری خودکار و پروفایل‌های بار که بر اساس لاگ‌های واقعی تولیدی ساخته شده‌اند نمی‌شود.
  • بررسی صحت منطق کسب‌وکار تحت بار. شرایط رقابتی، قفل‌ها در پایگاه داده، کاهش صف‌ها — اینها در تست‌های رقابتی و پروفایل‌سازی قرار دارند، نه تغییر آدرس IP خروجی.

پروکسی ابزاری برای یک وظیفه خاص «شبیه‌سازی ترافیک با IPهای مختلف» است، نه یک تقویت‌کننده جهانی تست بار. اگر هدف این است که بفهمید backend چقدر RPS را تحمل می‌کند، پروکسی در اکثر موارد اصلاً لازم نیست: کافی است چند تست رانر بدون پروکسی با تنظیمات صحیح keep-alive و استخر اتصالات داشته باشید.

اشتباهات متداول در تست از طریق پروکسی

در عمل، بیشتر مشکلات با پروکسی در تست‌های بار به چندین اشتباه تکراری مربوط می‌شود.

  • ترکیب تاخیر پروکسی با تاخیر سرویس تست شده. بدون اندازه‌گیری پایه (درخواست مستقیم بدون پروکسی) نمی‌توان فهمید که پروکسی سرور خود چند میلی‌ثانیه اضافه می‌کند.
  • استفاده از پروکسی‌های موبایل یا مسکونی در جایی که ظرفیت خالص نیاز است. چنین پروکسی‌ها محدود به کانال واقعی دستگاه نهایی هستند و فیزیکی نمی‌توانند ده‌ها هزار RPS را تحمل کنند — برای بار خالص به پروکسی‌های دیتاسنتر نیاز است.
  • استخر ناکافی IP برای تعداد زیادی VU. اگر برای 5000 کاربر مجازی 10 آدرس پروکسی وجود داشته باشد، تست به هر حال به همان محدودیت نرخ برخورد می‌کند، فقط با تاخیر — سرویس به سرعت الگوی «10 IP، هزاران درخواست» را مشاهده خواهد کرد.
  • نادیده گرفتن زمان‌های تایم‌اوت در سمت پروکسی. در بار رقابتی بالا، پروکسی سرور ممکن است خود شروع به رد اتصالات کند — مهم است که از قبل محدودیت‌های جلسات همزمان را از ارائه‌دهنده پروکسی بپرسید.
  • راه‌اندازی تست بدون بررسی whitelisting/احراز هویت. اگر پروکسی نیاز به احراز هویت بر اساس IP داشته باشد و تست از CI/CD با آدرس دینامیک رانر راه‌اندازی شود — درخواست‌ها با 407 Proxy Authentication Required سقوط خواهند کرد و نتایج تست بی‌معنا خواهد بود.

چک‌لیست قبل از راه‌اندازی تست

  • تعیین کردید که آیا واقعاً وظیفه نیاز به IPهای مختلف دارد یا اینکه تست از یک آدرس کافی است.
  • نوع پروکسی را برای وظیفه انتخاب کردید: دیتاسنتر برای RPS و محدودیت نرخ، مسکونی/موبایل برای منطق جغرافیایی.
  • اندازه‌گیری پایه بدون پروکسی انجام دادید تا تاخیر شبکه را از تاخیر پروکسی جدا کنید.
  • محدودیت‌های اتصالات همزمان را از ارائه‌دهنده پروکسی برای سطح مورد نیاز VU بررسی کردید.
  • احراز هویت پروکسی (نام کاربری/رمز عبور یا whitelisting IP رانر) را تنظیم کردید.
  • تصمیم گرفتید که آیا به جلسه چسبنده بر روی VU نیاز دارید یا چرخش برای هر درخواست.
  • تست را در یک بازه کوتاه (1-2 دقیقه) قبل از اجرای کامل راه‌اندازی کردید تا پیکربندی را بررسی کنید.

نتیجه‌گیری

پروکسی در k6 و JMeter یک روش کارآمد برای شبیه‌سازی ترافیک از IPهای مختلف، بررسی رفتار محدودیت نرخ و منطق وابسته به جغرافیا است. اما این جایگزین برنامه‌ریزی صحیح تست بار نیست: ظرفیت سرور، ثبات backend تحت بار رقابتی و برنامه‌ریزی واقعی ظرفیت را پروکسی بررسی نمی‌کند و بهبود نمی‌بخشد. از آنها به‌طور نقطه‌ای استفاده کنید — جایی که تست واقعاً به IP آدرس مشتری وابسته است، نه به‌عنوان یک ابزار جهانی «برای صداقت».

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