You are on page 1of 8

‫‪https://vrgl.

ir/xddzt‬‬ ‫
ویرگول ‪ -‬جایی برای نوشتن و خواندن‬

‫ماینیتوریگ ‪ Web API‬با ‪ Prometheus‬و ‪ - Grafana‬بخش ‪1‬‬

‫امروزه پایش لحظه ای سرویسهای نرم افزاری و اعالم سریع مشکالت به وجود اومده به گروه هدف (یه چیزی شبیه سیستم‬
‫های اعالن خطر) جز بخش بسیار مهم سرویس های نرم افزاری هستش چرا که تشخیص سریع مشکل باعث صرفه جویی در‬
‫وقت و هزینه مالکان و ذینفعان سرویس خواهد شد‪ .‬البته سیستم های مانیتورینگ مزایای خیلی بیشتری هم دارند که در‬
‫ادامه باهاشون روبرو خواهیم شد‪.‬‬

‫نمونه داشبوردی که قراره بسازیم‬

‫کارهایی که در طی این مقاله انجام میدیم اینطوریه که قراره چند تا ‪ instance‬از یه ‪ Web API‬بیاریم باال و یه سری ‪Metric‬‬
‫شبه واقعی برای مانیتورینگ سرویسمون تعریف کنیم‪ ،‬بعدش اونها رو بفرستیم روی ‪( Prometheus‬در واقع ‪Prometheus‬‬
‫اونها رو از ما بگیره و ذخیره کنه) و به کمک ‪ Grafana‬یه سری داشبورد مانیتورینگ برای سرویس(ها) بسازیم‪ .‬برای اینکه شما‬
‫درگیر راه اندازی سرویس ها نشید و بعد از مباحث ابتدایی بریم سراغ کوئری و داشبوردهای ‪ Prometheus‬کافیه فایل‬
‫‪ docker-compose‬رو باال بیارید و اتفاقاتی که افتاده رو ببینید‪ ،‬البته سورس کل کارها و توضیحات مراحل کار هم اینجا‬
‫نوشته میشه که برای درک بهتر کارهای انجام شده میتونه کمک کنه‪.‬‬
‫همه چیزهایی که گفتم توی گیتهاب این مقاله گذاشتم و میتونید ببینید و اگر براتون مفید بود بهش ستاره بدید‪.‬‬

‫‪1‬‬ ‫‪git clone https://github.com/naeemaei/MonitoringExample‬‬

‫بعد از دریافت سورس از گیت با این دستور از روت پروژه‪ ،‬سرویس ها ‪ pull‬و ‪ run‬خواهند شد‪ .‬اگه مشکلی با ‪docker-‬‬
‫‪ compose‬داشتید این لینک رو ببینید‬

‫‪1‬‬ ‫‪docker-compose -f "Prometheus\docker-compose.yml" up -d --build‬‬

‫به چه ابزارهایی نیاز داریم؟‬

‫‪1- VS Code‬‬

‫‪2- Docker‬‬

‫در طی این مجموعه مقاالت با موارد زیر آشنا خواهیم شد‪:‬‬

‫آشنایی با ‪ Time Serie Databases‬با محوریت ‪Prometheus‬‬

‫نحوه ارسال اطالعات متریک ها به ‪Prometheus‬‬

‫کار با ‪ Prometheus‬و تا حدودی زبان ‪Promql‬‬

‫کار با ‪ Alerting‬و ارسال هشدار به سرویس های ثانویه‬

‫کار با ‪ Grafana‬و ساختن داشبورد روی یک مسئله شبه واقعی نزدیک به دنیای واقعی‬

‫آشنایی با ‪Time Serie Databases‬‬

‫من راجع به دیتابیس های ‪ Time Serie‬مثل ‪ Prometheus‬و ‪ InfluxDB‬و شبیه اینها زیاد نمینویسم چون راجع بهشون‬
‫مقاله زیاد نوشته شده ولی به یک سری مسائل اصلی در موردشون اشاره میکنم‪ ،‬البته با محوریت ‪Prometheus‬‬

‫برای چه کارهایی و چه نوع دیتاهایی ازشون استفاده میکنیم؟‬

‫قبل از اینکه یکم بحث رو فنی کنیم لطفا به این دو تا مثال توجه کنید‪:‬‬
‫به ساعت هوشمندی که دارین دقت کنید‪ ،‬اونها ضربان قلب شما رو در هر لحظه نشون میدن‪ ،‬حاال اگر بخوایم‬
‫مقادیر ضربان رو در بازه زمانی طوالنی مدت ذخیره کنیم (مثال یک ماه)‪ ،‬باید در چه ساختاری ذخیره کنیم؟

‫یک ُبعد اصلی به نام زمان داریم (‪ )Key‬و یک مقدار داریم به نام تعداد ضربان (‪ .)Value‬در واقع در یک زمان‬
‫مشخص یک مقدار برای تعداد ضربان وجود داره‪ .‬احتماال شما رو به یاد یکی از ساختارهای نگهداری داده میندازه

‫عالوه بر این شاید بخوایم یک سری اطالعات دیگه رو در کنارش نگهداری کنیم‪ ،‬مثال شهری که االن توش هستیم‪ ،‬و‬
‫اینکه در چه حالی هستم (خواب‪ ،‬بیداری‪ ،‬پیاده روی‪ ،‬ورزش)

‫و در پایان هم میخوایم گزارش تهیه کنیم یا ماینتور کنیم‪
:‬‬
‫‪ .1‬میانگین ضربان قلب اون فرد در یک شهر ساحلی یا در یک شهر کوهستانی چقدر هستن‪
.‬‬
‫‪ .2‬نرخ کاهش یا افزایش ضربان قلب در ساعات شروع خواب‪ ،‬عمق خواب و پایانی خواب به چه صورت هستن‪
.‬‬
‫‪ .3‬نرخ ضربان قلب در یک ساعت اخیر چقدر بوده است‪.‬‬

‫‪. . . .‬‬

‫امروزه ساعت های هوشمند و حتی گوشی ها قدم های شما را هم ثبت می کنند و به شما گزارش می دهند در طول‬
‫یک روز چند قدم برداشتید‪
.‬‬
‫به چه روشی این دیتا ها رو ذخیره کنیم که بتونیم هم روی این اطالعات مانیتورینگ انجام بدیم و هم گزارشاتی مانند‬
‫مواردی که باال گفتم رو تهیه کنیم‬

‫آیا ‪ RDBMS‬های مثل ‪ MySQL‬و ‪ MSSQL‬برای نگهداری و گزارش گیری این نوع اطالعات مناسب هستند؟ در واقع ‪Time‬‬
‫‪ Serie Database‬ها برای چنین استفاده هایی طراحی و بهینه سازی شده اند و ‪ Prometheus‬یکی از اونهاست‪.‬‬

‫دقیقا چه اطالعاتی در ‪ Prometheus‬ذخیره میشود؟‬

‫‪ - 1‬نام متریک مثال ضربان قلب‬

‫‪ - 2‬زمان ذخیره سازی مثال ‪2021/07/14 17:45:46.125‬‬

‫‪ - 3‬چه اطالعات اضافه ای در کنارش ذخیره می شود؟ مثال شهر‪ ،‬وضعیت فرد (خواب‪ ،‬بیدار و‪ .)...‬به مواردی که در کنار‬
‫متریک ذخیره می شوند ‪ Label‬یا ‪ Tag‬میگیم‪.‬‬

‫‪ - 4‬مقدار متریک‪ ،‬مثال ‪103‬‬

‫بطور خالصه میشه گفت برای یک ‪ Value‬عالوه بر زمان یک سری ‪ Tag‬یا ‪ label‬هم میشه ذخیره کرد‪.‬‬

‫‪1‬‬ ‫‪2021/07/14 14:17:25.1000 => heart_rate{city=”shiraz",state=”sleep”} 103‬‬


‫‪( Metric Name: heart_rate‬ضربان قلب)

‫‪( Timestamp: 2021/07/14 14:17:25.1000‬زمان ثبت مقدار متریک)

‫‪
Tags: city, state‬‬
‫‪Value: 103‬‬

‫ضربان قلب در تاریخ ‪ 14:17:25.1000 2021/07/14‬در شهر شیراز و وضعیت خواب ‪ 103‬ثبت شده است‪.‬‬

‫در کل باید گفت در ‪ Time Serie Databases‬محور اصلی و کلید زمان هستش‪ ،‬به این تصویر توجه کنید‪:‬‬

‫نمونه ای از دیتای ذخیره شده‬

‫همونطور که در این تصویر میبینید‪ ،‬ما یه سری نقطه زمانی داریم از ‪ t0‬تا ‪ t6‬که در هر کدوم از این زمان ها اطالعات متریک‬
‫ها ذخیره میشه‪ ،‬مثال تعداد درخواستهای سرچی که تا لحظه ‪ t3‬وارد اپلیکیشن اندروید شده (سطر اول از پایین) ‪ 18‬تا‬
‫هستش که تا زمان ‪ t5‬این عدد به ‪ 22‬میرسه یعنی در (‪ )t5 - t3‬ثانیه ‪ 5‬تا درخواست سرچ جدید روی سرویس اندروید اومده‪
.‬‬
‫یه نکته هم که اهمیت داره بدونید اینه که در ‪ Prometheus‬یه مفهومی داریم به اسم ‪ Scrape‬که با کانفیگ کردن اون‬
‫مشخص میکنیم اطالعات متریک ها هر چند ثانیه از ‪ Exporter‬ها گرفته بشه و ذخیره بشه‪ .‬حاال باید ببینیم ‪ Exporter‬ها‬
‫چیا هستن؟ اما قبلش معماری کلی رو ببینیم‪:‬‬
‫معماری ‪Prometheus‬‬

‫سرویس ‪ Prometheus‬به دو روش دیتای متریک ها رو جمع آوری و ذخیره مکینه‬

‫روش ‪ :Pull‬در این روش هر سرویسی که قراره اطالعات متریک هاشو در اختیار ‪ Prometheus‬قرار بده به عنوان یک‬
‫‪ Exporter‬معرفی میشه و مقادیر متریک ها رو در یک قالب مشخص ایجاد میکنه و ‪ Prometheus‬در بازه های مشخصی‬
‫اطالعاتشو میخونه (‪ )Scrape‬و ذخیره میکنه‪.‬‬

‫روش ‪ :Push‬در این روش هر سرویس مقادیر متریک هاشو برای ‪ Pushgateway‬میفرسته و ‪ Prometheus‬با‬
‫‪ Pushgateway‬هم مثل یک ‪ Exporter‬برخورد میکنه و اطالعات رو در بازه زمانی مشخص ازش میخونه‪ .‬البته ما در این‬
‫پروژه از روش ‪ Pull‬استفاده خواهیم کرد‪.‬‬

‫نکته جذاب تر اینه که کتابخانه های جانبی زیادی وجود دارند که برای انواع مختلف سرویس ها ‪ Exporter‬ارائه میکنند‪ .‬مثال‬
‫شما اگر بخواین از بخشی اطالعات موجود در ‪ MSSQL‬در ‪ Prometheus‬استفاده کنید میتونید سرچ کنید و ‪Exporter‬‬
‫مناسب رو پیدا کنید‪ ،‬یا اگر بخواین سیستم عامل ویندوز رو مانیتور کنید میتونید از ‪ Windows Exporter‬استفاده کنید‪.‬‬
‫تقریبا برای اکثر سرویس های مهمی که میشناسید ‪ Exporter‬وجود داره و میشه به سادگی به ‪ Prometheus‬متصلش کرد‪.‬‬

‫یکی از بخش های دیگه ‪ Alertmanager‬هستش که وظیفه ی ارسال هشدار ها از طریق ایمیل‪ ،‬اسلک‪ ،‬اس ام اس و‪ ...‬رو‬
‫داره‪.‬‬

‫پرومتئوس از ‪ Service Discovery‬برای شناسایی ‪ Target‬ها و بررسی ‪ up‬یا ‪ down‬بودن اونها استفاده میکنه که امکان‬
‫‪ Integrate‬شدنش با ‪ Kubernetes، Consul‬وجود داره‪.‬‬
‫از ابزارهایی مثل ‪ Grafana‬هم برای نمایش اطالعات روی نمودار و داشبورد استفاده میشه‪ Prometheus .‬یه ‪HTTP Server‬‬
‫هم داره که از طریق اون کوئریها رو دریافت میکنه و خروجی مورد نیاز رو به گرافانا یا هر ‪ API‬دیگه ای ارائه میده‪ ،‬این کوئری‬
‫ها به زبان ‪ PromQL‬هستن که در ادامه باهاش آشنا میشیم

‫متریک ها چند نوع هستن‪ Counter، Gauge، Histogram :‬و ‪Summaries‬‬

‫یک‪ Counter .‬یک شمارنده ست که مقدارش در گذر زمان افزایش پیدا میکنه‪ ،‬برای مثال تعداد درخواستها وارد شده به‬
‫سرویس به ازای هر درخواست جدید که وارد سرویس میشه یک واحد افزایش پیدا میکنه‪ .‬مقادیر یه شمارنده همیشه‬
‫افزایشی است‪
.....10-9-8-7-6-5-4-3-2-1 :‬‬

‫‪1‬‬ ‫
‪# TYPE application_request_counter gauge‬‬
‫‪2‬‬ ‫"‪application_request_counter{endpoint="product-detail-page",responsecode="200‬‬

‫مثال باال به این معناست که برای ‪ Endpoint‬جزئیات محصول با پاسخ ‪ 200‬تا این لحظه ‪ 532‬تا درخواست وارد سیستم شده‬
‫و زمانی که درخواست جدیدی بیاد میشه ‪533‬‬

‫دو‪ Gauge .‬برای نگهداری مقادیر عددی متغیر استفاده میشه‪ ،‬مثل مصرف ‪ CPU‬در یک زمان خاص یا مدت زمانی که صرف‬
‫اجرای یک درخواست میشه‪400-125-1250-470-320-450 :‬‬

‫‪1‬‬ ‫
‪# TYPE application_request_duration gauge‬‬
‫‪2‬‬ ‫‪application_request_duration{endpoint="product-list-page"} 845‬‬

‫مثال باال هم به این معناست که مدت زمان اجرای یک درخواست نمایش محصوالت ‪ 845‬میلی ثانیه است‪.‬‬

‫سه و چهار‪ Summary .‬و ‪ Histogram‬متریک های ترکیبی هستند‪ ،‬یعنی اگر بخوایم مقدار یک متریک رو بسنجیم هم‬
‫تعدادش (‪ )count‬رو ثبت میکنه و هم مجموع رخداد (‪ )sum‬این متریک ثبت میشه‪ .‬که داشتن این دو مقدار به ما برای‬
‫رسیدن به میانگین اون متریک کمک میکنه‪ ،‬فرض کنید ما تعداد درخواستها رو داریم و در کنارش مجموع ‪Response Time‬‬
‫درخواست ها هم هست و با کمک این دوتا مقدار میتونیم به میانگین زمان پاسخ درخواست ها برسیم‪ .‬حاال تفاوت کجاست‪
.‬‬
‫در ‪ Histogram‬میتونیم در کنار موارد باال‪ ،‬مجموع تعداد درخواست در دسته های مختلف را هم داشته باشیم‪ ،‬مثال تعداد‬
‫درخواستهایی که زمان پاسخ کمتر از ‪ 50‬میلی ثانیه بوده‪ ،‬تعداد درخواستهایی که زمان پاسخ کمتر از ‪ 180‬میلی ثانیه و‪...‬‬
1 # TYPE application_request histogram

2 application_request_bucket{le="50"} 502

3 application_request_bucket{le="100"} 954

4 application_request_bucket{le="180"} 1166

5 application_request_bucket{le="250"} 1296

6 application_request_bucket{le="400"} 1383

7 application_request_bucket{le="800"} 1424

8 application_request_bucket{le="2000"} 1429

9 application_request_bucket{le="+Inf"} 1429

10 application_request_sum 25465

11 application_request_count 1429

‫) هم داریم که با عددی بین صفر و‬quantile( ‫ هم مجموع و تعداد رو داریم اما در کنارش یه دسته بندی کمی‬Summary ‫در‬
‫ یکم تعریفش گنگ بود با یک مثال فهمش‬،‫یک نشون میدیم که تا هر دهک درصدی میانگین زمان پاسخ سرویس چقدره‬

‫ برای میانگین زمان پاسخ به این شکل هستش که مثال ثبت میکنیم میانگین زمان پاسِخ‬Summary ‫ یک نمونه از‬.‫راحت تره‬
.‫ میلی ثانیه‬146 ‫ درصد درخواست ها‬95 ‫ میلی ثانیه هستش و میانگین زمان پاسِخ‬114 ‫ درصد درخواستها حدود‬50

1 # TYPE application_request_duration summary

2 application_request_duration_sum{app="MonitoringExample.Api"} 95743

3 application_request_duration_count{app="MonitoringExample.Api"} 1429

4 application_request_duration{app="MonitoringExample.Api",quantile="0.5"} 114

5 application_request_duration{app="MonitoringExample.Api",quantile="0.75"} 132
6 application_request_duration{app="MonitoringExample.Api",quantile="0.95"} 146
7 application_request_duration{app="MonitoringExample.Api",quantile="0.99"} 152

.‫توضیحات تکمیلی و مثالهایی از این متریک ها را در قسمتهای بعد سعی میکنم اضافه کنم‬

‫ اینجا لینک هر سرویس و‬.‫ میتونید سرویس ها رو در مرورگر ببینید‬docker-compose ‫شما بعد از اجرا شدن دستور‬
‫ وقتی وارد پنل گرافانا شدید‬.‫اطالعات جانبی برای ورود رو گذاشتم که برای مشاهده داشبورد اولیه الزمه وارد پنل گرافانا بشید‬
‫ میتونید نمودارهایی که قراره بسازیم رو ببینید تا در قسمت های بعد نحوه ساختن هر کدوم‬my api dshboard ‫در داشبورد‬
.‫رو توضیح بدیم‬

:‫در قسمت های بعد موارد زیر را بررسی میکنیم‬

Prometheus ‫ نحوه ارسال متریک ها با‬.۱

‫ بررسی سرویس هایی که قراره بیاریم باال‬.۲


‫‪ .۳‬کار با ‪ Prometheus‬و زبان ‪PromQL‬‬

‫‪ .۴‬طراحی داشبورد برای متریک ها و دیتای تولید شده‬

‫‪ .۵‬کار با ‪ AlertManager‬و ارسال هشدار از طریق ایمیل و اس ام اس


You might also like