کاربر میگوید صفحه سفارشها کند است. داشبورد سرور را باز میکنید: CPU عادی است، حافظه کافی دارید و هیچ سرویسی هم Down نشده است. لاگها را بررسی میکنید؛ بیشتر درخواستها با کد ۲۰۰ تمام شدهاند. بااینحال، بازشدن صفحه گاهی چند ثانیه طول میکشد. زمان دقیقاً کجا مصرف میشود؟ در کد برنامه، دیتابیس، انتظار برای اتصال یا یک API خارجی؟
APM یا مانیتورینگ عملکرد اپلیکیشن برای پاسخ به همین سؤال به کار میآید. با اندازهگیری رفتار درخواستها و عملیات داخلی برنامه، کمک میکند محدوده مشکل را از «سرویس کند است» به یک مسیر، وابستگی یا عملیات مشخص برسانید.
در این راهنما ابتدا مفهوم APM را روشن میکنیم، سپس یک سناریوی عیبیابی را قدمبهقدم پیش میبریم و در پایان میبینیم چه زمانی به آن نیاز دارید و از کجا باید شروع کنید.
APM چیست؟
APM مخفف Application Performance Monitoring است؛ یعنی پایش مداوم عملکرد اپلیکیشن هنگام اجرا. هدف آن شناخت زمان پاسخ، خطاها، حجم درخواستها و رفتار بخشهایی است که در اجرای عملیات نقش دارند. در بعضی منابع، همین مخفف برای Application Performance Management به کار میرود که مدیریت و بهبود عملکرد را هم در بر میگیرد.
برای یک فروشگاه، APM میتواند نشان دهد کدام مسیر کند شده، چه سهمی از درخواستها خطا میدهند و در نمونههای ثبتشده، زمان در کدام فراخوانیها صرف شده است. کاربرد آن محدود به HTTP نیست؛ پردازش Job، مصرف پیام از صف و عملیات پسزمینه هم میتوانند پایش شوند.
مانیتورینگ سرور وضعیت منابع را نشان میدهد؛ APM رفتار برنامه را هنگام استفاده از آن منابع و انتظار برای وابستگیها بررسی میکند.
تفاوت APM با مانیتورینگ سرور، لاگ و RUM
| روش | سؤال اصلی | نمونه کاربرد |
|---|---|---|
| مانیتورینگ سرور | منابع و سیستمعامل چه وضعیتی دارند؟ | کمبود حافظه، فشار دیسک یا اشباع CPU |
| APM | کدام عملیات برنامه کند یا ناموفق است؟ | پیداکردن Queryهای تکراری در درخواست سفارشها |
| لاگ | چه رویدادی با چه جزئیاتی رخ داده است؟ | متن Exception یا دلیل ردشدن یک عملیات |
| RUM | کاربر واقعی در مرورگر چه تجربهای دارد؟ | کندی نمایش صفحه یا خطای JavaScript |
| Synthetic Monitoring | آیا سناریوی آزمایشی هنوز درست اجرا میشود؟ | اجرای دورهای ورود و ثبت سفارش |
این مرزبندی مفهومی است؛ ممکن است یک پلتفرم چند قابلیت را کنار هم ارائه کند. همچنین زمان پاسخ Backend با زمان کامل تجربه کاربر برابر نیست. شبکه کاربر، دانلود فایلها و اجرای JavaScript میتوانند صفحه را کند کنند، حتی وقتی API سریع پاسخ میدهد.
اگر هنوز پایش منابع را راهاندازی نکردهاید، مقاله مانیتورینگ سرور در سه سطح نقطه شروع مناسبی است. APM این دید را کامل میکند.
APM چگونه داخل برنامه را قابل مشاهده میکند؟
با Instrumentation، نقاطی از اجرای برنامه اندازهگیری میشوند. بخشی از این کار برای کتابخانههای پشتیبانیشده بهصورت خودکار انجام میشود و برای منطق اختصاصی میتوان اندازهگیری دستی اضافه کرد. میزان پوشش به زبان، کتابخانه، نسخه و تنظیمات بستگی دارد؛ نصب یک Agent به معنی دیدهشدن تمام خطوط کد نیست.
Trace و Span به زبان ساده
Trace مسیر یک عملیات را با مجموعهای از Spanها توصیف میکند. هر Span یک بخش زماندار مانند فراخوانی دیتابیس یا سرویس دیگر است و میتواند مشخصاتی مانند نام عملیات و وضعیت داشته باشد. رابطه میان Spanها کمک میکند ترتیب و وابستگی کارها را ببینید.
برای ادامهیافتن Trace در چند سرویس، Context باید میان آنها منتقل شود. اگر این انتقال قطع شود، ممکن است بخشهای یک درخواست را به شکل Traceهای جدا ببینید. در پردازش پیامها و کارهای غیرهمزمان هم حفظ این ارتباط به Instrumentation مناسب نیاز دارد. منبع: مفاهیم Trace در OpenTelemetry.
نمای Waterfall معمولاً زمان شروع و مدت Spanها را کنار هم نمایش میدهد. در تفسیر آن دقت کنید: مدت یک Span الزاماً مصرف CPU نیست؛ انتظار شبکه، قفل یا منابع دیگر هم میتواند در آن باشد. همچنین زمان Spanهای تودرتو یا موازی را نباید ساده با هم جمع کرد.
چه متریکهایی را باید در APM ببینیم؟
برای شروع، هر مسیر مهم را با سه سؤال بررسی کنید: چند بار فراخوانی میشود، چند بار شکست میخورد و چقدر زمان میبرد؟ سپس نشانههای اشباع منابع برنامه را کنار آن قرار دهید.
- حجم درخواست: تعداد درخواست در بازه مشخص؛ برای تفسیر تغییرات کندی و خطا ضروری است.
- نرخ خطا: نسبت درخواستهای ناموفق به کل درخواستهای همان دامنه و بازه. تعریف شکست باید روشن باشد.
- زمان پاسخ: میانه و صدکهای بالا مانند p95، در کنار تعداد نمونه.
- اشباع: مانند تعداد کارهای منتظر در صف یا انتظار برای دریافت اتصال از Pool.
در p95، حدود ۹۵ درصد مشاهدات زمان پاسخ کمتر یا مساوی مقدار گزارششده دارند. این شاخص رفتار درخواستهای کندتر را بهتر از میانگین آشکار میکند. با ترافیک خیلی کم، صدکهای بالا ناپایدارند؛ عدد را بدون تعداد درخواست و بازه اندازهگیری تفسیر نکنید. تأکید بر تأخیر، ترافیک، خطا و اشباع با چهار سیگنال طلایی Google SRE همراستاست.
دادههای نمودار زیر فرضی و آموزشی هستند. از ساعت ۱۰:۱۵، کندی بخشی از درخواستها شدید شده اما میانگین تغییر بسیار کمتری دارد. نمودار بهتنهایی علت تغییر را ثابت نمیکند.
مثال عملی: چرا صفحه سفارشها دو ثانیه طول میکشد؟
فرض کنید مسیر GET /api/orders کند شده است. مثال زیر یک سناریوی آموزشی است، نه گزارش مشتری یا نتیجه تست محصول. هدف این است که از مشاهده متریک به یک فرضیه قابلآزمایش برسیم.
قدم اول: محدوده مشکل را مشخص کنید
ابتدا بازه شروع کندی، محیط Production و نسخه برنامه را مشخص کنید. آیا همه مسیرها کند شدهاند یا فقط سفارشها؟ آیا نرخ خطا هم تغییر کرده است؟ حجم درخواست و اندازه پاسخ چه تفاوتی کردهاند؟ در این سناریو، Login طبیعی است و مشکل بیشتر در فهرست سفارشهای طولانی دیده میشود.
قدم دوم: یک Trace کند را با نمونه عادی مقایسه کنید
در یک درخواست کند، دریافت فهرست سفارشها ۱۰۰ میلیثانیه طول میکشد؛ سپس برنامه برای هرکدام از ۲۰ سفارش، اطلاعات تکمیلی را با یک Query جداگانه میخواند. هر Query فقط ۷۰ میلیثانیه طول میکشد، اما اجرای متوالی آنها مجموعاً ۱۴۰۰ میلیثانیه زمان میگیرد. یک API خارجی ۳۵۰ میلیثانیه و بقیه پردازش ۱۵۰ میلیثانیه زمان میبرد.
برای سادهماندن مثال، این مراحل متوالی و بدون همپوشانی فرض شدهاند و مجموع آنها ۲۰۰۰ میلیثانیه است. بخش «سایر پردازشها» زمان باقیمانده مثال است و الزاماً یک Span خودکار مستقل نیست.
قدم سوم: فرضیه N+1 را بررسی کنید
تکرار Query مشابه به تعداد سفارشها، سرنخ الگوی N+1 است: ابتدا یک Query برای فهرست و سپس N Query برای جزئیات. ممکن است هیچکدام بهتنهایی از آستانه Slow Query عبور نکنند، اما مجموع زمان آنها تجربه کاربر را خراب کند.
تعداد Queryها را در درخواستهای کوچک و بزرگ مقایسه کنید و مسیر کد را ببینید. راه اصلاح میتواند دریافت گروهی دادهها، Join مناسب یا تغییر شیوه بارگذاری ارتباطها باشد. انتخاب درست به مدل داده و حجم نتیجه بستگی دارد. اجرای همه Queryها با Promise.all هم همیشه مناسب نیست؛ ممکن است فشار همزمان بیشتری به Pool و دیتابیس وارد کند.
قدم چهارم: اصلاح را با شرایط مشابه بسنجید
بعد از تغییر، فقط یک درخواست سریع را معیار موفقیت قرار ندهید. با حجم سفارش و بار مشابه، تعداد Query، زمان پاسخ مسیر، نرخ خطا و مصرف دیتابیس را مقایسه کنید. اگر اندازه پاسخ یا ترکیب کاربران تغییر کرده باشد، مقایسه قبل و بعد میتواند گمراهکننده باشد.
اگر Trace بهجای Queryهای تکراری، انتظار طولانی نشان داد، وضعیت Connection Pool و قفلهای دیتابیس را بررسی کنید. مقاله Connection Leak چیست و چگونه تشخیص داده میشود؟ برای دنبالکردن این مسیر مفید است.
چه زمانی به APM نیاز دارید؟
تعداد سرورها معیار کافی نیست. حتی یک برنامه روی یک سرور ممکن است چند دیتابیس و API خارجی داشته باشد و عیبیابی آن دشوار شود. معیار عملیتر این است: آیا میتوانید با داده موجود مشخص کنید زمان و خطا در کدام بخش عملیات ایجاد شده است؟
| نشانه در تیم شما | ارزش APM | نقطه شروع |
|---|---|---|
| کاربر کندی گزارش میکند اما منابع عادیاند | تفکیک زمان عملیات و وابستگیها | مسیر پرتکرار مورد شکایت |
| بعد از انتشار نسخه، عملکرد افت میکند | مقایسه رفتار مسیرها بین نسخهها | ثبت نسخه در دادههای سرویس |
| تشخیص مسئول مشکل بین چند سرویس طول میکشد | دنبالکردن درخواست میان سرویسها | یک جریان کامل مانند ثبت سفارش |
| خطاها در محیط توسعه تکرار نمیشوند | حفظ نمونه اجرای ناموفق در محیط واقعی | Trace همراه با لاگ مرتبط |
| API خارجی گاهی Timeout میشود | مشاهده تأخیر و اثر وابستگی | فراخوانی خروجی و Timeout آن |
| تیم برای هر Incident ساعتها لاگ میگردد | محدودکردن جستوجو به عملیات مشخص | ارتباط trace_id با لاگ |
چه زمانی شروع سادهتر کافی است؟
برای سایتی با محتوای عمدتاً ثابت و Backend بسیار محدود، پایش دسترسیپذیری، خطا و منابع ممکن است اولویت بالاتری داشته باشد. برای محصول تازه هم لازم نیست همه سرویسها را از ابتدا با بیشترین جزئیات پوشش دهید. یک مسیر حیاتی را انتخاب کنید و بررسی کنید داده جدید واقعاً زمان عیبیابی را کاهش میدهد یا نه.
اگر مشکل اصلی در بارگذاری یا تعامل مرورگر است، دادههای RUM و بررسی Frontend را جدی بگیرید. اگر مشکل مصرف CPU داخل یک تابع است، ممکن است پس از محدودکردن محل مشکل به Profiling نیاز داشته باشید. APM نقطه شروع تحقیق است و همیشه بهتنهایی علت ریشهای را اثبات نمیکند.
نقش OpenTelemetry در APM چیست؟
OpenTelemetry مجموعه ابزارها، APIها و SDKهایی برای تولید و انتقال دادههای مشاهدهپذیری است. خودش بهتنهایی یک محصول کامل ذخیرهسازی و تحلیل APM نیست؛ دادهها باید به Backend مناسب ارسال شوند. استفاده از آن امکان جداسازی بخش جمعآوری داده از مقصد تحلیل را فراهم میکند. منبع: مستندات OpenTelemetry.
در یک راهاندازی معمول، Instrumentation داخل برنامه داده تولید میکند و Exporter آن را مستقیم یا از مسیر Collector به مقصد میفرستد. قبل از فعالسازی، پشتیبانی زبان و کتابخانهها و روش دریافت داده در مقصد را بررسی کنید. برای منطق اختصاصی مثل محاسبه قیمت، ممکن است لازم باشد Span دستی اضافه کنید.
چکلیست شروع APM در یک سرویس واقعی
- یک مسیر حیاتی انتخاب کنید: مانند ورود، جستوجو یا ثبت سفارش؛ با مسئول مشخص و تعریف موفقیت.
- سرویس را قابل شناسایی کنید: نام پایدار، محیط و نسخه انتشار را ثبت کنید تا دادههای تست و Production مخلوط نشوند.
- پوشش را بررسی کنید: ورود درخواست، دیتابیس و فراخوانی خروجی را ببینید؛ سپس برای بخشهای مبهم اندازهگیری دستی اضافه کنید.
- ارتباط دادهها را برقرار کنید: trace_id را در لاگهای مرتبط داشته باشید و ادامه Trace میان سرویسها را آزمایش کنید.
- داشبورد کوچک بسازید: ترافیک، نرخ خطا و صدک زمان پاسخ برای همان مسیر، همراه با نسخه و وابستگیهای اصلی.
- داده را اعتبارسنجی کنید: در محیط تست یک درخواست موفق، یک خطای کنترلشده و یک تأخیر کنترلشده ایجاد کنید و مطمئن شوید درست دیده میشوند.
- یک چرخه عیبیابی کامل انجام دهید: از متریک غیرعادی به Trace، سپس لاگ یا کد مرتبط بروید و نتیجه اصلاح را بسنجید.
برای نامگذاری مسیر، از الگوی /orders/:id استفاده کنید؛ واردکردن شناسه هر سفارش در Label متریک میتواند تعداد سریهای زمانی را بهشدت افزایش دهد. مقادیر بسیار متنوع مانند User ID یا Request ID را Label عمومی متریک قرار ندهید.
Sampling، هزینه و اطلاعات حساس را چگونه مدیریت کنیم؟
ثبت همه Traceها در ترافیک بالا میتواند پرهزینه باشد. Sampling بخشی از آنها را نگه میدارد. تصمیم Head Sampling در ابتدای Trace گرفته میشود؛ Tail Sampling پس از مشاهده دادههای Trace میتواند براساس ویژگیهایی مثل تأخیر یا خطا تصمیم بگیرد، اما به پردازش و نگهداری موقت بیشتری نیاز دارد. دادهای که پیشتر حذف شده، در مرحله بعد قابل بازیابی نیست. منبع: Sampling در OpenTelemetry.
اگر بیشتر Traceهای خطادار را نگه میدارید، نسبت خطا در Traceهای ذخیرهشده نماینده نرخ خطای کل ترافیک نیست. برای هشدار عمومی از متریکهایی استفاده کنید که دامنه اندازهگیری و اثر نمونهبرداری آنها روشن است.
هزینه فقط حجم ذخیرهسازی نیست. مصرف CPU و حافظه برنامه، تعداد Span در هر درخواست و ترافیک خروجی را هم قبل و بعد از فعالسازی در بار مشابه بسنجید. درباره سربار، درصد ثابت و قابلتعمیمی برای همه برنامهها وجود ندارد.
برای Attributeها فهرست مجاز مشخص کنید. رمز عبور، Authorization Header، Cookie، توکن و بدنه حساس درخواست نباید بیمحابا ثبت شوند. متن Query و پارامترها هم ممکن است اطلاعات شخصی داشته باشند؛ حذف یا ماسککردن آنها را پیش از ارسال انجام دهید و دسترسی و مدت نگهداری را محدود کنید.
برای APM چه هشدارهایی بسازیم؟
هشدار باید مسئلهای را نشان دهد که اقدام مشخص دارد. یک درخواست کند بهتنهایی معمولاً دلیل مناسبی برای بیدارکردن تیم نیست. تغییر را در یک بازه زمانی، با حجم درخواست کافی و متناسب با اهمیت مسیر بررسی کنید.
- افت موفقیت عملیات حیاتی: افزایش پایدار شکست در ثبت سفارش، همراه با تعداد کل تلاشها.
- عبور تأخیر از هدف سرویس: برای مسیر مشخص و در بازه معنادار؛ هدف گزارشگیری با هدف Login یکسان نیست.
- اختلال وابستگی: رشد Timeout یک سرویس خارجی که روی درخواستهای کاربران اثر گذاشته است.
برای مثال آموزشی میتوان هشدار «نرخ خطای سرور مسیر سفارش بیش از ۲ درصد در ۱۰ دقیقه، با حداقل ۵۰۰ درخواست» تعریف کرد. این اعداد استاندارد عمومی نیستند؛ آنها را براساس ترافیک، هدف دسترسیپذیری و هزینه خطا تعیین کنید. هر پیام هشدار باید نام مسیر، محیط، بازه، لینک بررسی و مسئول پاسخگویی داشته باشد.
کد HTTP هم تمام حقیقت نیست. پاسخ ۲۰۰ ممکن است نتیجه کسبوکاری ناموفق داشته باشد و هر ۴۰۰ هم خرابی سرویس نیست. موفقیت فنی و موفقیت عملیات محصول را جدا تعریف کنید. برای مشکلات هشداردهی، مقاله ۵ اشتباه پنهان که مانیتورینگ شما را بیاثر میکنند را بخوانید.
APM در Watchlog
در APM واچلاگ میتوانید Trace و نمای Waterfall را بررسی کنید، زمان پاسخ مسیرها را ببینید و فراخوانیهای دیتابیس و وابستگیهای سرویس را دنبال کنید. پشتیبانی از OpenTelemetry هم برای ارسال Traceهای سرویسهای Instrumentشده ارائه شده است.
برای شروع، یک مسیر مهم را به جمعآوری داده متصل کنید و کیفیت پوشش آن را بسنجید: آیا درخواست کند را پیدا میکنید؟ آیا فراخوانی دیتابیس دیده میشود؟ آیا میتوانید تشخیص دهید کدام بخش به بررسی بیشتر نیاز دارد؟ پاسخ این سؤالها از تعداد نمودارهای داشبورد مهمتر است.
سؤالات متداول
آیا APM فقط برای میکروسرویسهاست؟
خیر. در یک Monolith هم Queryهای تکراری، انتظار Pool یا API خارجی میتوانند کندی ایجاد کنند. پیچیدگی مسیر اجرا و هزینه عیبیابی مهمتر از تعداد سرویسهاست.
آیا داشتن لاگ برای عیبیابی کافی نیست؟
لاگ ساختاریافته بسیار مفید است، اما بازسازی زمانبندی و ارتباط چند عملیات از روی لاگها میتواند دشوار باشد. Trace مسیر بررسی را مشخصتر میکند و لاگ جزئیات رویدادهای مرتبط را کامل میکند.
آیا APM تمام توابع برنامه را نشان میدهد؟
خیر. فقط بخشهایی دیده میشوند که Instrumentation آنها را پوشش داده است. برای منطق اختصاصی به Span دستی و برای تحلیل دقیق مصرف CPU ممکن است به Profiler نیاز داشته باشید.
آیا APM جای مانیتورینگ دیتابیس را میگیرد؟
خیر. APM میتواند فراخوانی کند را در مسیر درخواست نشان دهد، اما بررسی Execution Plan، قفلها، I/O و وضعیت داخلی دیتابیس به دادهها و ابزارهای تکمیلی نیاز دارد.
آیا با نصب APM برنامه سریعتر میشود؟
نصب ابزار بهخودیخود گلوگاه را اصلاح نمیکند. ارزش آن در پیدا کردن شواهد، اولویتبندی اصلاحات و اندازهگیری نتیجه تغییر است.
اول کدام مسیر را مانیتور کنیم؟
مسیری را انتخاب کنید که شکست یا کندی آن برای کاربر و کسبوکار هزینه دارد و تیم مسئولش مشخص است. پوشش کامل یک جریان مهم، نقطه شروع عملیتری از جمعآوری ناقص داده از همه سرویسهاست.
جمعبندی
APM کمک میکند بفهمید کدام عملیات کند یا ناموفق شده و برای پیدا کردن علت از کجا باید شروع کنید. اگر کاربران مشکل گزارش میکنند اما متریکهای سرور پاسخ روشنی ندارند، یا دنبالکردن درخواست میان سرویسها وقت زیادی میگیرد، زمان مناسبی برای اضافهکردن این لایه از مانیتورینگ است.
از یک مسیر حیاتی شروع کنید، دادهها را اعتبارسنجی کنید و یک مشکل واقعی را تا اصلاح و اندازهگیری نتیجه دنبال کنید. معیار موفقیت APM این است که تیم با شواهد روشنتر و زمان کمتر به تصمیم برسد.





