تریسینگ روشی برای مشاهده جریان درخواستها از طریق یک سیستم توزیعشده است، که در آن هر مرحله پردازش به عنوان یک رویداد جداگانه با برچسب زمان ثبت میشود. به گزارش OpenTelemetry، 2025، trace مسیر کامل درخواست را از نقطه ورود تا پاسخ نهایی ادغام میکند و از تمامی میکروسرویسها و فراخوانیهای خارجی عبور میکند. این به توسعهدهندگان امکان میدهد تنگناهها، تأخیرات و خطاها را در معماریهای پیچیده بکاندهای موبایل شناسایی کنند.
نکات کلیدی
تریسینگ روشی برای مشاهده توزیعشده است که در آن هر درخواست وارده از طریق تمامی سرویسها و جزئیات سیستم ردیابی میشود. بر خلاف متریکهایی که مقادیر تجمعی (زمان پاسخ میانگین، تعداد خطاها) را نشان میدهند، تریسینگ کنتکست کامل یک درخواست مشخص را حفظ میکند.
هر مرحله پردازش — فراخوانی پایگاه داده، درخواست HTTP به میکروسرویسی دیگر، اجرای یک وظیفه پسزمینه — به عنوان یک واحد جداگانه با برچسب زمان، وضعیت و ویژگیها ثبت میشود. به گزارش Google Dapper (انتشار اصلی 2010)، تریسینگ امکان میدهد تأخیرات را در سیستمهای توزیعشده با دقت تا یک فراخوانی مکانیابی کند.
تریسینگ بهویژه برای برنامههای موبایل حیاتی است که بکاند آنها از دهها میکروسرویس تشکیل شده است. یک عمل کاربر — مثلاً، ورود به حساب کاربری — میتواند از API Gateway، سرویس احراز هویت، پایگاه داده و سرویس Push عبور کند. بدون trace تعیین اینکه کدام جزء پاسخ را کند میکند تقریباً غیرممکن است.
واحد پایه تریسینگ span است. هر span یک عملیات منطقی را نمایش میدهد: درخواست HTTP، پرسان SQL، فراخوانی gRPC، سریالیسازی JSON. Span شامل یک شناسه یکتا، شناسه والد، نام عملیات، زمان شروع، مدت زمان، وضعیت و یک مجموعه ویژگی است.
همه spanهایی که به یک درخواست ریشه مربوط هستند در trace ادغام میشوند. span ریشه (root span) نقطه ورود را نمایش میدهد — درخواست HTTP از مشتری موبایل به API. spanهای فرزند یک درخت تشکیل میدهند که در آن هر span از طریق فیلد parent_span_id به والد خود اشاره میکند.
مدت زمان trace برابر مجموع مدت زمان بخشهای زمانی منحصربهفرد همه spanهاست. اگر دو span فرزند به صورت موازی اجرا شوند، زمان آنها جمع نمیشود — این برای تجزیه و تحلیل درست تأخیرات ناشی از فراخوانیهای موازی میکروسرویسها بسیار مهم است.
هر span میتواند شامل ویژگیها باشد — جفت کلید-مقدار با اطلاعات فرامتا: URL درخواست، ID کاربر، نسخه API، نام میزبان. ویژگیها برای فیلتراسیون و گروهبندی traceها استفاده میشوند. علاوه بر ویژگیها، span از رویدادها پشتیبانی میکند — برچسبهای زمانی با توصیف متنی، مثل «از دست رفتن کش» یا «تلاش مجدد برای اتصال».
Distributed tracing مسئله اتصال spanهایی را که در فرآیندهای مختلف و رایانههای مختلف ایجاد میشوند حل میکند. مکانیسم بر پایه انتقال کنتکست است: هنگام فراخوانی سرویس B از سرویس A، یک سربرگی با شناسه trace فعلی و span والد به درخواست خروجی اضافه میشود.
پروتکلهای استاندارد انتقال کنتکست — W3C Trace Context (سربرگیهای traceparent و tracestate) و Zipkin B3 (سربرگیهای X-B3-TraceId، X-B3-SpanId). W3C Trace Context در سال 2021 توسط کنسرسیوم W3C به عنوان یک استاندارد پذیرفته شد و توسط همه ارائهدهندگان عمده تلمتری پشتیبانی میشود.
پس از دریافت درخواست، سرویس B trace_id را از سربرگی استخراج کرده و یک span فرزند با این trace_id ایجاد میکند. بنابراین، پس از تکمیل درخواست، همه spanها از سرویسهای مختلف در یک trace در طرف کلکتور ادغام مییابند. این نیازمند آن است که هر سرویس با همان کتابخانه tracing ابزارداری شده باشد.
در توسعه موبایل، انتقال کنتکست نه تنها بکاند، بلکه ارتباط مشتری-سرور را نیز پوشش میدهد. برنامه موبایل میتواند trace_id را در سربرگی هر درخواست API ارسال کند، که این امکان را فراهم میکند تا عمل مشتری را با پردازش سرور مرتبط کنیم. OpenTelemetry SDK برای iOS و Android از ایجاد و انتقال خودکار کنتکست trace از طریق مشتریان HTTP پشتیبانی میکند.
import io.opentelemetry.api.trace.Span
import io.opentelemetry.api.trace.Tracer
import io.opentelemetry.context.Context
class TracingInterceptor : Interceptor {
private val tracer: Tracer = OpenTelemetry.getTracer("mobile-app")
override fun intercept(chain: Interceptor.Chain): Response {
val span = tracer.spanBuilder("HTTP POST /api/login")
.setParent(Context.current())
.startSpan()
return chain.proceed(chain.request())
.also { span.end() }
}
}
Interceptor ارائهشده در Kotlin برای هر درخواست HTTP به سرور یک span ایجاد میکند. کنتکست والد از کد فراخواننده از طریق Context.current() انتقال داده میشود، که به شما امکان میدهد trace طرف مشتری را با trace طرف سرور مرتبط کنید.
OpenTelemetry استاندارد در ارائه برای جمعآوری دادههای trace است. آن یک API واحد برای تولید spanها، ابزارداری خودکار کتابخانههای محبوب و یک مکانیسم انعطافپذیر برای صادرات داده به بکاندهای مختلف ارائه میدهد: Jaeger، Zipkin، Grafana Tempo، Datadog، New Relic.
OpenTelemetry از ایجاد خودکار spanها برای چارچوبهای محبوب پشتیبانی میکند: Spring Boot، Ktor، Flask، Express، gRPC. توسعهدهنده فقط باید یک وابستگی به پروژه اضافه کند، و کتابخانه به طور مستقل درخواستهای ورودی و خروجی را رهگیری میکند. Auto-instrumentation برای جاوا از javaagent استفاده میکند که bytecode را بدون تغییر منبع در حال اجرا تغییر میدهد.
برای پلتفرمهای موبایل، OpenTelemetry Swift SDK و Kotlin SDK را ارائه میدهد. آنها به طور خودکار برای درخواستهای شبکه (URLSession، OkHttp)، کار با پایگاه داده (CoreData، Room) و وظایف پسزمینه span ایجاد میکنند. توسعهدهنده میتواند برای منطق کسب و کار spanهای سفارشی اضافه کند.
spanهای جمعآوری شده از طریق پروتکل OTLP (OpenTelemetry Protocol) به کلکتور ارسال میشوند. کلکتور میتواند دادهها را بافر کند، فیلتر کند و به یک یا چند سیستم ذخیرهسازی هدایت کند. به گزارش مستندات OpenTelemetry، تأخیر تیپیکی از تولید span تا نمایش آن در داشبورد با استفاده از صادرات gRPC ۲–۵ ثانیه است.
import OpenTelemetryApi
import OpenTelemetrySdk
import URLSessionInstrumentation
let instrumentation = URLSessionInstrumentation()
instrumentation.enable()
let tracer = OpenTelemetry.instance.tracerFactory
.get("mobile-monitoring")
let span = tracer.spanBuilder("fetch-user-profile")
.setAttribute(key: "user.id", value: userId)
.startSpan()
span.end()
کد در Swift ابزارداری خودکار لایه شبکه را فعال میکند و یک span سفارشی برای عملیات دریافت پروفایل کاربر ایجاد میکند. ویژگی user.id به شما امکان میدهد بعداً traceها را بر اساس کاربر مشخص فیلتر کنید.
در سیستمهای با بار بالا، تریسینگ هر درخواست غیرممکن است — این بار غیرقابل قبولی بر ذخیرهسازی و شبکه ایجاد میکند. نمونهبرداری این مشکل را حل میکند و تنها بخشی از traceها را ذخیره میکند. انتخاب راهبرد مستقیماً بر کاملیت دادهها و هزینه زیرساخت تأثیر میگذارد.
تصمیم درباره ذخیره trace در لحظه ایجاد آن — در span ریشه گرفته میشود. سادهترین و متداولترین رویکرد: درصد ثابتی از درخواستها (مثل ۵٪) ذخیره میشود، باقی دور انداخته میشوند. عیب — نمیتوان ضمانت داد که خطاهای نادر گیر افتاده باشند. Probability sampler در OpenTelemetry از تنظیم احتمال از ۰.۰ تا ۱.۰ پشتیبانی میکند.
تصمیم تا پایان تمامی spanهای trace به تعویق افتاده است. تحلیلگر بررسی میکند که آیا trace حاوی خطاها، تجاوز زمان یا ویژگیهای مورد علاقه است و تنها در آن صورت آن را ذخیره میکند. این رویکرد نیازمند بافرینگ تمامی spanها در کلکتور است که مصرف حافظه را افزایش میدهد. به گزارش Grafana Labs، tail-based sampling در سیستمهایی با خطاهای نادر اما بسیار مهم به لحاظ نسبت «قیمت به دادههای مفید» ۴۰–۶۰% بهینهتر است.
| راهبرد | مزایا | معایب |
|---|---|---|
| Fixed probability | سادگی، بار قابل پیشبینی | حوادث نادر را از دست میدهد |
| Rate limiting | حجم داده ضمانی | پوشش نامتوازن |
| Tail-based | گیرندازی همه خطاها | مصرف بالای حافظه |
| Adaptive | تعادل هزینه و پوشش | پیچیدگی تنظیمات |
ثبت رویداد رویدادهای جداگانه را با سطح اهمیت (info، warn، error) ثبت میکند، اما آنها را در کنتکست یک درخواست به هم مرتبط نمیکند. تریسینگ در عوض، یک درخت ساختاریافته از عملیات متعلق به یک درخواست انتهابه ایجاد میکند. در عمل، این دو رویکرد یکدیگر را نفی نمیکنند، بلکه همدیگر را تکمیل میکنند.
لاگها برای تجزیه و تحلیل مشخص یک خطا مؤثر هستند: توسعهدهنده پیام دقیق، پیش رویداد، مقادیر متغیرها را میبیند. Tracing به سوال «چرا درخواست ۵ ثانیه طول میکشد» پاسخ میدهد — نشان میدهد که کدام میکروسرویس یا فراخوانی بیشترین زمان را گرفته است. به گزارش Honeycomb (2024)، تیمهایی که از tracing همراه با ثبت رویداد استفاده میکنند، علت ریشه حوادث را ۲.۳ بار سریعتر پیدا میکنند.
رویکرد مدرن — observability — tracing، متریکها و لاگها را در یک سیستم واحد ادغام میکند. OpenTelemetry از همبستگی بین این سه سیگنال پشتیبانی میکند: هر span میتواند شامل ارتباطاتی به لاگهای مرتبط باشد، و متریکها میتوانند برای رسیدن به traceهای مشخص با trace_id برچسبگذاری شوند.
سوالات متداول
نمایش متریکهای تجمعی سیستم را نشان میدهد — زمان پاسخ میانگین، تعداد خطا در دقیقه، بار CPU. Tracing مسیر یک درخواست مشخص را از طریق تمامی جزئیات نشان میدهد. نمایش به سوال «چه اتفاقی افتاده،» و tracing به سوال «چرا این اتفاق افتاده؟» پاسخ میدهد.
برای سیستمهای تولید، ۱–۵% درخواستها در head-based sampling کافی است. اگر سیستم به ندرت خطا میدهد، tail-based sampling با تمرکز بر گیرندازی همه traceهای خطا توصیه میشود. برای محیط staging، trace ۱۰۰% درخواستها بدون محدودیت مجاز است.
ابزارهای اصلی: Jaeger (راهحل اوبر، منبع باز)، Grafana Tempo (ذخیرهسازی مقیاسپذیر trace)، Datadog APM، New Relic Distributed Tracing، AWS X-Ray و Honeycomb. همه آنها از استاندارد OpenTelemetry برای دریافت دادهها پشتیبانی میکنند.
بله، تریسینگ محلی داخل یک فرآیند کار میکند. OpenTelemetry SDK برای iOS و Android برای عملیات محلی سپان ایجاد میکند: خواندن از پایگاه داده، پردازش تصاویر، درخواستهای شبکه. چنین traceهایی توزیعنشده اند، اما برای دیاگنوزیک عملکرد طرف مشتری مفید هستند.
کتابخانههای مدرن tracing در head-based sampling کمتر از ۱% سرریاد اضافه میکنند. OpenTelemetry از صادرات ناهمگام داده استفاده میکند که جریان اصلی را بلوک نمیکند. برای دستگاههای موبایل، محدود کردن دفعه ایجاد spanها و استفاده از راهبرد نمونهبرداری تطبیقی توصیه میشود.
نتایج
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.
همچنین بخوانید