ردیابی توزیعشده: عبور یک درخواست از چند سرویس

جلسهای که هر تیمی با معماری چندسرویسی بالاخره تجربه میکند: کاربر میگوید ثبت سفارش هشت ثانیه طول کشید. تیم سرویس سفارش نمودارش را نشان میدهد، ۹۰ میلیثانیه. تیم پرداخت هم همینطور. تیم موجودی هم.
همه راست میگویند. و هشت ثانیه هم واقعی بود.
مشکل این است که هیچکس کل مسیر را نمیبیند. هر تیم تکهٔ خودش را میبیند و زمانی که بین تکهها گم میشود — در صف، در انتظار قفل، در تلاش دوبارهٔ بیصدا — در هیچ نموداری نیست.
اسپن و ردیابی
دو واژه کافی است.
اسپن یک کار مشخص است با شروع و پایان: یک فراخوان HTTP، یک پرسوجو، یک پردازش داخلی.
ردیابی مجموعهٔ همهٔ اسپنهای یک درخواست است، با رابطهٔ پدر و فرزندشان. یعنی یک درخت، که وقتی رسمش کنید دقیقاً میگوید وقت کجا رفت:
ثبت سفارش ──────────────────────────────── ۸٫۱s
├─ اعتبارسنجی ۲۰ms
├─ فراخوان سرویس موجودی ──────── ۴٫۹s
│ └─ (انتظار برای قفل) ──── ۴٫۷s ← اینجا
├─ فراخوان درگاه پرداخت ── ۲٫۱s
│ └─ تلاش دوم بعد از وقفه ── ۱٫۸s ← و اینجا
└─ ثبت نهایی ۹۰ms
حالا معلوم است. سرویس موجودی «سریع» بود چون زمان انتظار برای قفل را به حساب خودش نمیگذاشت، و درگاه پرداخت یک بار بیصدا دوباره تلاش کرده بود — چیزی که در لاگ هیچ سرویسی بهعنوان خطا ثبت نشده بود.
این دو الگو، در تجربهٔ ما، بیشتر از هر چیز دیگری در سامانههای چندسرویسی پیدا میشوند.
انتقال زمینه: تنها بخشی که واقعاً کار دارد
برای اینکه اسپنها به هم بچسبند، هر سرویس باید شناسهٔ ردیابی را از سرویس قبلی بگیرد و به بعدی بدهد. این کار از طریق سرآیند استاندارد HTTP انجام میشود و کتابخانههای OpenTelemetry بیشترش را خودکار انجام میدهند.
سه جا معمولاً زنجیره پاره میشود، و هر سه را باید دستی درست کنید:
صفها. وقتی پیام در صف میرود و بعداً مصرف میشود، سرآیند HTTP وجود ندارد. باید شناسه را در خود پیام بگذارید. اگر کارهای پسزمینه دارید، این حتماً موردتان هست.
مرز نخ و کار ناهمزمان. زمینه به نخ گره خورده؛ وقتی کار به استخر نخ میرود، جا میماند.
سرویسهای قدیمی. آن سرویسی که کسی دست نمیزند، سرآیند را دور میریزد و ردیابی از وسط قطع میشود.
توصیهٔ عملی ما: زنجیره را زود آزمایش کنید. یک درخواست بفرستید و ببینید چند اسپن برگشت. اگر کمتر از انتظارتان بود، همین سه مورد را بگردید.
نمونهگیری، و تلهاش
نگه داشتن همهٔ ردیابیها گران است. پس نمونه میگیرید — و اینجا یک تلهٔ ساده هست که تیمها در آن میافتند.
اگر تصادفی یک درصد را نگه دارید، همان یک درصد را از همهچیز نگه میدارید: شامل ۹۹ درصدِ درخواستهای سالم و کسلکننده. آن ردیابیِ هشتثانیهای که دنبالش بودید، با احتمال ۹۹ درصد دور ریخته شده.
راه درست این است که بعد از تمام شدن ردیابی تصمیم بگیرید: هر ردیابی که خطا داشت یا از آستانهای کندتر بود، کامل نگه داشته شود؛ از بقیه نمونه بگیرید. این کار در Collector انجام میشود، نه در کد برنامه — که یکی از دلایل اصلی وجود Collector است.
به لاگ وصلش کنید
اگر trace_id در هر خط لاگتان باشد، از یک خطای لاگ مستقیم به کل مسیر آن
درخواست میرسید و برعکس. این یک فیلد، بیشتر از هر داشبوردی در زمان قطعی به
شما کمک میکند — و در
مدیریت متمرکز لاگ گفتهایم چرا آن را
مهمترین فیلد لاگ میدانیم.
آیا شما به این نیاز دارید؟
صادقانه: اگر یک برنامهٔ یکپارچه دارید، احتمالاً نه. APM همین کار را داخل یک فرایند انجام میدهد و راهاندازیاش سادهتر است.
ردیابی توزیعشده وقتی لازم میشود که یک درخواست از مرز فرایند رد شود: چند سرویس، یا حتی یک برنامه که به چند سامانهٔ بیرونی وصل است. و اگر به این وضعیت رسیدهاید، این دیگر تجملات نیست.
میگوییم صریح: سامانهٔ چندسرویسی بدون ردیابی، قابل پشتیبانی نیست. نه سخت است، قابل پشتیبانی نیست — چون هیچ روشی برای جواب دادن به «وقت کجا رفت» ندارید جز حدس زدن. اگر تصمیم به تقسیم سامانه دارید و در یکپارچه در برابر میکروسرویس هنوز مرددید، هزینهٔ ردیابی را جزو هزینهٔ تقسیم حساب کنید، نه جدا از آن.
چه چیزی نصب کنیم
تولید داده را استاندارد نگه دارید — ردیابی پختهترین سیگنال OTel است و در بیشتر زبانها پایدار، پس اینجا ریسکی نمیکنید.
برای مقصد، اگر میخواهید در زیرساخت خودتان بماند گزینههای متنباز بالغی وجود دارد که ما در پشتههای سنجه و لاگ، کنار هم کنارشان گذاشتهایم. Sentry هم ردیابی کارایی دارد و اگر از قبل برای خطا نصبش کردهاید، شروع کردن با همان کمهزینهترین راه است.
آنچه در انتخاب مقصد واقعاً اهمیت دارد یک چیز است: چقدر سریع میشود از «این درخواست کند بود» به «این اسپن مقصر بود» رسید. ابزاری که برای این کار پنج کلیک لازم دارد، ساعت دو بامداد استفاده نمیشود.
اگر تازه شروع میکنید، همهٔ سامانه را ابزارگذاری نکنید. یک مسیر را انتخاب کنید — پرارزشترین، معمولاً همان که پول از آن رد میشود — و کامل ردیابیاش کنید. یک ردیابی کامل از یک مسیر، بیشتر از ابزارگذاری نیمهکارهٔ بیست سرویس ارزش دارد.