نوید خلیلیان
نوید خلیلیان
خواندن ۹ دقیقه·۲ سال پیش

عملکرد API های خود را با NBomber آزمایش کنید


اگر سی شارپ زبان مورد استفاده شما نیست، نگران نباشید. فقط به اصول اولیه این تکنیک تست نیاز دارید. اگر می خواهید اصول اولیه تکنیک تست بار را یاد بگیرید، می توانم خواندن این مطلب را به شما توصیه کنم.


جهت جلوگیری از خستگی خواننده کل مطلب را در دو بخش تقسیم میکنم:

1- بخش اول شامل توضیح اصول تست و مشاهده یک نمونه(شما در حال خواندن این بخش هستید)

2- بخش دوم شامل آموزش تست نویسی واقعی و بررسی عمیق تر نتایج تست بار


تست بار چیست؟

تست بار ، تعاملات n کاربر با سیستم را شبیه سازی می کند و اطلاعاتی از قبیل زمان پاسخ دهی به کاربر را بر اساس معیارهایی مانند استفاده از RAM و CPU جمع آوری میکند. تست بار به شما کمک میکند تا مشکلات عملکردی را پیدا کنید که ممکن است فقط برای بیش از 1000 کاربر رخ دهد، و پس از آن باعث مشود مشکلات بزرگی برای عملکرد سرویس شما ایجاد کند. این تجربه برای ما یک کوئری نا کارآمد بود که باعث می شد به طور مکرر نیاز به راه اندازی مجدد سرویس و مقیاس بندی عمودی و افقی(سخت افزاری و نرم افزاری) شود.

موضوع تست بار چیزی فراتر از این است که بپرسیم آیا یک سرور می تواند اتصال همزمان n کاربر را مدیریت کند؟ بعنوان مثال ممکن است بگویید در عمل این اتفاق هیچ وقت برای سرویس من اتفاق نخواهد افتاد و نباید به آن اهمیت بدهیم!

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

ابزار NBomber عملکرد بسیار خوبی در شبیه سازی درخواست ها برای پیدا کردن مشکلات عملکردی سرویس شما دارد.

چرا باید سرویس خودمان را تست کنیم؟

یاکوب نیلسن(راجع به ایشان بیشتر بخوانید) سه محدودیت زمان پاسخ را برای برنامه ها تعریف کرده است:

  • 0.1(صد میلی ثانیه) حدود زمانی است که کاربر احساس کند سیستم به صورت آنی واکنش نشان میدهد، به این معنی که هیچ باز خورد خاصی(مثلا نمایش ProgressBar) به جز نمایش نتیجه درخواست لازم نیست.
  • 1(یک) ثانیه حدود زمانی برای بدون وقفه ماندن جریان فکری کاربر است.حتی اگر کاربر متوجه تاخیر شود. معمولا در تاخیر هعای بیش از 100 میلی ثانیه تا 1 ثانیه بازخورد خاصی لازم نیست، اما کاربر احساس کار کردن با سیستم بصورت آنی را از دست میدهد.
  • 10(ده) ثانیه حدود زمانی است که می توان توجه کاربر را بر روی سیستم متمرکز نگه داشت.برای تاخیر های طولانی تر کاربران معمولا می خواهند تا زمان اتمام درخواست کار دیگری انجام دهند.بنا بر این باید به آنها بازخورد داده شود که چه مدت زمان باید معطل بمانند. در طول تاخیر ، بازخورد دادن به کاربر بسیار مهم است مخصوصا مواقعی که زمان انجام کار بسیار متغیر باشد(مانند آپلود فایل که کاملا به سرعت شبکه و حجم فایل وابسته است)، زیرا کاربران نمیداند چه انتظاری از سیستم داشته باشند. شما نمی خواهید کاربران شما از سرویس شما به نحوی استفاده کننده که زمان پاسخ دهی آن بیشتر از 10 ثانیه باشد. بنابراین عملکرد سیستم می تواند تاثیر مستقیم روی جذب کاربر یا از دست دادن وی باشد.

تست بار ابزاری است که قابلیت آزمایش تست عملکرد سیستم در شرایط واقعی، بدون داشتن کاربران واقعی را به ما می دهد.

هنگامی که در یک استارت آپ هستید و در حال حاضر مانند من در حال آماده سازی برنامه خود برای انتشار هستید، آیا می توانید مطمعن باشید که این برنامه می تواند تعداد کاربران را که می خواهید داشته باشید مدیریت کند؟

برای من همیشه یک نگرانی بزرگ وجود داشت که آیا برنامه می تواند به 10 نفر سرویس دهی کند؟ برای 1000 نفر چطور؟ یا حتی بیشتر؟ آیا میتواندی چنین آزمایشی را چندین بار در روز انجام دهید؟ من اینطور فکر نمی کنم. شما هرگز نمی توانید این کار را انجام دهید چون هیچ راهی برای آزمایش دستی وجود ندارد. اینجاست که تست بار وارد عمل می شود. با تست بار می توانید برنامه خود را تست استرس کنید و با اطمینان بگویید که برای صدها کاربر کار خواهد کرد. این موضوع نه تنها قبل از راه اندازی یک سرویس مهم است، بلکه قبل از راه اندازی یک ویژگی جدید نیز اهمیت دارد. زیرا ممکن است عملکرد برنامه شما را تحت تاثیر قرارداده و خراب کند بطوری که قبل از بروزرسانی نسخه جدید متوجه آن نخواهید شد.


در بالا می‌توانید کاربری را مشاهده کنید که از برنامه‌ای که بدون آزمایش بارگذاری توسعه یافته است استفاده می‌کند. شما چنین کاربری را نمی خواهید! کاربرانی که قبلاً خوشحال بودند، اکنون می توانند ناراضی باشند، برنامه شما را ترک کنند یا ممکن است اشتراک را لغو کنند. مطمئناً امتیازات اعتماد کاربران خود را از دست خواهید داد. بنابراین پیشنهاد میکنم لطفاً برخی از تست های بار را نیز در CI خود ادغام کنید.


چرا از NBomber استفاده کنیم؟

بهتر است بگویم NBomber یک ابزار با کاربری راحت برای آزمایش عملکرد برنامه شماست که علاوه بر نوشتن و اجرا کردن سریع تست ها داده های مفیدی را در اختیار شما می گذارد تا با خیال راحت بصورت واقعی سرویس خود را تست کنید.

بزرگترین مزیت شبیه سازی تست بار این است که شما فقط 100 درخواست را بصورت همزان اجرا نمی کنید بلکه رفتار واقعی کاربران را با توجه به اطلاعات ارائه شده توسط NBomber شبیه سازی می کنید.

از آنجایی که خود تست ها به سادگی فراخوانی API های شماست، می توان گفت این یک تست از نوع جعبه سیاه است. این بدان معناست که با NBomber می توانید هر پروژه ای را بدون در نظر گرفتن زبان برنامه نویسی آن آزمایش کنید.


یک مثال ساده از NBomber ببینیم!

ابتدا یک پروژه Console Application ایجاد میکنیم.

dotnet new console -n [project_name] -lang [&quotF#&quot or &quotC#&quot]
dotnet new console -n NBomberTest -lang &quotF#&quot
cd NBomberTest

اضافه کردن پکیج NBomber

dotnet add package NBomber

مطمعن شوید که بسته Http را برای ارسال درخواست های http نصب کنید

dotnet add package NBomber.http

در مرحله بعد بیایید یک مثال اجرایی را از تست وب سایت NBomber ببینیم

using System; using NBomber; using NBomber.Contracts; using NBomber.CSharp; using NBomber.Plugins.Http.CSharp; using NBomber.Plugins.Network.Ping;namespace NBomberTest { class Program { static void Main(string[] args) { var step = Step.Create(&quotfetch_html_page&quot, clientFactory: HttpClientFactory.Create(), execute: context => { var request = Http.CreateRequest(&quotGET&quot, &quothttps://nbomber.com&quot) .WithHeader(&quotAccept&quot, &quottext/html&quot); return Http.Send(request, context); }); var scenario = ScenarioBuilder .CreateScenario(&quotsimple_http&quot, step) .WithWarmUpDuration(TimeSpan.FromSeconds(5)) .WithLoadSimulations( Simulation.InjectPerSec(rate: 100, during: TimeSpan.FromSeconds(30)) ); // creates ping plugin that brings additional reporting data var pingPluginConfig = PingPluginConfig.CreateDefault(new[] { &quotnbomber.com&quot }); var pingPlugin = new PingPlugin(pingPluginConfig); NBomberRunner .RegisterScenarios(scenario) .WithWorkerPlugins(pingPlugin) .Run(); } } }

کد بالا را در فایل Program.cs پروژه که ایجاد کردید کپی کنید.

مطمعن شوید که از C# نسخه 9 به بعد استفاده میکنید. اگر از نسخه قدیمی تر استفاده می کنید می توانید نسخه C# را در فایل .csproj پروژه خود به روز کنید.برای این کار تگ زیر را در فایل .csproj داخل تگ <PropertyGroup> کپی کنید یا در صورت وجود مقدار آن را تغییر دهید.

<LangVersion>10.0</LangVersion>

حالا پروژه را اجرا کنید تا نتیجه بمباران را مشاهده کنید. :)

نتیجه ای که در Console خواهید دید چیزی شبیه این می باشد:


12:24:20 [INF] NBomber '2.1.5' Started a new session: '2022-03-23_11.24.44_session_787459f0'. 12:24:21 [INF] NBomber started as single node. 12:24:21 [INF] Plugins: no plugins were loaded. 12:24:21 [INF] Reporting sinks: no reporting sinks were loaded. 12:24:21 [INF] Starting init... 12:24:21 [INF] Target scenarios: 'simple_http'. 12:24:21 [INF] Init finished. 12:24:21 [INF] Starting warm up... simple_http ---------------------------------------- 100% 00:00:30 load: keep_constant, copies: 112:24:53 [INF] Starting bombing... simple_http ---------------------------------------- 100% 00:01:01 load: keep_constant, copies: 112:25:54 [INF] Stopping scenarios... 12:25:54 [INF] Calculating final statistics...────────────────────────────────────────────────────── test info ───────────────────────────────────────────────────────test suite: 'nbomber_default_test_suite_name' test name: 'nbomber_default_test_name'──────────────────────────────────────────────────── scenario stats ────────────────────────────────────────────────────scenario: 'simple_http' duration: '00:01:00', ok count: 662, fail count: 0, all data: 0 MB load simulation: 'keep_constant', copies: 1, during: '00:01:00' ┌────────────────────┬────────────────────────────────────────────────────────┐ │ step │ ok stats │ ├────────────────────┼────────────────────────────────────────────────────────┤ │ name │ fetch_html_page │ │ request count │ all = 662, ok = 662, RPS = 11 │ │ latency │ min = 59,66, mean = 90,47, max = 367,5, StdDev = 32,04 │ │ latency percentile │ 50% = 79,61, 75% = 92,48, 95% = 158,98, 99% = 209,15 │ └────────────────────┴────────────────────────────────────────────────────────┘──────────────────────────────────────────────────────── hints ─────────────────────────────────────────────────────────
hint for Scenario 'simple_http': Step 'fetch_html_page' in scenario 'simple_http' didn't track status code. In order to track status code, you should use Response.Ok(statusCode: value)hint for Scenario 'simple_http': Step 'fetch_html_page' in scenario 'simple_http' didn't track data transfer. In order to track data transfer, you should use Response.Ok(sizeInBytes: value)12:25:55 [INF] Reports saved in folder:...

بنا بر این NBomber سرویس را آزمایش کرد و اطلاعاتی در مورد آن جمع آوری کرد.

برای درک خروجی تولید شده، اجازه دهید به اصول تست بار نگاه کنیم.


اصول اولیه تست بار:

در اسناد راهنمای NBomber توضیحات خوب و کاملی در مورد اصول اولیه تست بار وجود دارد. من سعی میکنم در اینجا به خلاصه ای از آنها اشاره کنم:

مهمترین معیارهای تست بار:

ابتدا نگاهی به آمار تولید شده در محله قبل داشته باشیم:

┌────────────────────┬────────────────────────────────────────────────────────┐
│ step │ ok stats │
├────────────────────┼────────────────────────────────────────────────────────┤
│ name │ fetch_html_page │
│ request count │ all = 662, ok = 662, RPS = 11 │
│ latency │ min = 59,66, mean = 90,47, max = 367,5, StdDev = 32,04 │
│ latency percentile │ 50% = 79,61, 75% = 92,48, 95% = 158,98, 99% = 209,15 │
└────────────────────┴────────────────────────────────────────────────────────┘


Request count
  • آمار مربوط به تعداد درخواست ها
RPS
  • تعداد درخواست های ارسال شده در ثانیه
all
  • تعداد همه درخواست هایی که در طول تست ارسال شده
ok
  • تعداد درخواست هایی که سیستم ما می تواند در یک ثانیه پاسخ دهد. این یک شاخص مهم برای ارزیابی عملکرد سیستم ما می باشد.
Latency
  • زمان بین ارسال درخواست و دریافت پاسخ. این پارامتر باید با تعداد در خواست در ثانیه(RPS) ارتباط خوبی داشته باشد.
Latency percentile
  • صدک تاخیر نشان دهنده چند درصد در یک زمان خاص است. بطور کلی نشان میدهد که ما چند درخواست را به خوبی پاسخ داده ایم و مدت زمان چند درصد پاسخ ها بد بوده است.این مثال فقط چند درخواست با تاخیر بیش از 200 میلی ثانیه دارد، اما نیمی از آن کمتر از 80 میلی ثانیه است.این به شما کمک میکند تا داده های فوق را طبقه بندی کنید.

تقسیم بندی سیستم خود را در تست بار بشناسید

  • در تست بار سیستم ها به دو نوع تقسیم بندی می شوند:
  • سیستم های بسته:

تعداد کاربران ثابتی دارند، هر کاربر یک درخواست ارسال می کند و سپس منتظر پاسخ می ماند.این ارتباط بین API و Database خواهد بود. بنابر این پایگاه داده یک سیستم بسته است.

  • سیستم های باز:

تعداد کابران مشخص نیست. هرچیزی که از پروتکل هایی مانند HTTP استفاده میکند باید یک سیستم باز در نظر گرفته شود(مانند وب سایت ها).

بر اساس این دانش نامه ما بعدا شبیه سازی صحیح را برای سیستم خود انتخاب خواهیم کرد. برای سیستم های بسته پارامتر های شبیه سازی می تواند بصورت ثابت در نظر گرفته شود، اما پیشنهاد من برای سیستم های باز استفاده از پارامتر های تصادفی است.

ادامه را در بخش دوم بخوانید!

load testperformance
Full Stack Developer - Dev Ops
شاید از این پست‌ها خوشتان بیاید