Get a quote

تتبع الطلبات الموزعة في خدمات Go على AWS ECS باستخدام OpenTelemetry

بمجرد أن يكون لديك أكثر من خدمتين من خدمات Go تتحدثان عبر ECS، يصبح تحديد الطلبات البطيئة أمرًا شاقًا. هذه هي الطريقة التي نربط بها التتبع الموزع عبر الخدمات مع OpenTelemetry.

بمجرد أن يكون لديك أكثر من خدمتين من خدمات Go تتحدثان مع بعضها على AWS ECS، يصبح تحديد الطلبات البطيئة تحديًا حقيقيًا. ترى استجابة بطيئة في سجلات موازن التحميل، لكن لا تعرف هل المشكلة في خدمة الطلبات، أم في خدمة المخزون، أم في استعلام PostgreSQL بطيء بداخل إحداهما. بدون التتبع الموزع، أنت تعتمد على طوابع الوقت في السجلات والتخمين.

هذا المقال يشرح كيفية ربط التتبع الموزع مع OpenTelemetry عبر خدمات Go على ECS Fargate، ونقل سياق التتبع عبر استدعاءات HTTP وgRPC، وتشغيل الكولكتور كـ sidecar.

لماذا يهم التتبع الموزع في بيئة الخدمات المصغرة؟

طلب المستخدم الواحد عادةً يعبر من ثلاث إلى ست خدمات داخلية في بنية SaaS الإنتاجية. خدمة الطلبات تستدعي المخزون، والمخزون يتحقق من قاعدة التسعير، وكل ذلك يكتب إلى PostgreSQL. السجلات تخبرك بما حدث. التتبع يخبرك أين ذهب الوقت.

OpenTelemetry هو المعيار الصناعي لهذا. يوفر API محايدة للبائعين، وSDK لـ Go، ونقل تلقائي لسياق HTTP وgRPC، وعفريت كولكتور يجمع ويصدر الـ spans إلى أي خلفية.

كيف تضبط OpenTelemetry SDK في خدمة Go؟

الإعداد ينقسم إلى جزأين: تهيئة مزود التتبع عند بدء التشغيل، ثم استخدام المتتبع داخل المعالجات وطبقات الخدمة.

أولًا، قم بتهيئة المزود في main.go:

func InitTracer(ctx context.Context, serviceName, endpoint string) (*sdktrace.TracerProvider, error) {
    exp, err := otlptracehttp.New(ctx,
        otlptracehttp.WithEndpoint(endpoint),
        otlptracehttp.WithInsecure(),
    )
    if err != nil {
        return nil, fmt.Errorf("create exporter: %w", err)
    }
    tp := sdktrace.NewTracerProvider(
        sdktrace.WithBatcher(exp),
        sdktrace.WithSampler(sdktrace.ParentBased(sdktrace.TraceIDRatioBased(0.20))),
    )
    otel.SetTracerProvider(tp)
    return tp, nil
}

معدل أخذ العينات هنا 20 بالمئة. لمنصة SaaS تحت 50,000 طلب يوميًا على ECS Fargate، هذا يبقي تكاليف تخزين التتبع تحت 5 دولارات شهريًا.

كيف تنقل سياق التتبع عبر استدعاءات HTTP؟

نقل سياق التتبع هو المكان الذي يرتكب فيه معظم مطوري Go خطأً. لا يمكنك فقط تمرير معرف التتبع في رأس مخصص. معيار W3C Trace Context يحدد رأس traceparent الذي يحمل معرف التتبع ومعرف الـ span الأصلي وعلامات أخذ العينات.

لعميل HTTP الصادر، قم بتغليف http.Client بـ OTel transport:

func NewHTTPClient() *http.Client {
    return &http.Client{
        Transport: otelhttp.NewTransport(http.DefaultTransport),
        Timeout:   10 * time.Second,
    }
}

للخدمة المستقبلة، قم بتغليف موجه HTTP بـ otelhttp.NewHandler.

بهذين الجزأين، كل استدعاء HTTP بين خدماتك يُدرج ويستخرج رأس traceparent تلقائيًا. معرف التتبع يبقى كما هو عبر جميع حدود الخدمات.

كيف تضيف spans مخصصة لاستدعاءات قاعدة البيانات؟

لأي شيء أكثر تحديدًا، مثل استعلام PostgreSQL بطيء أو تقييم قاعدة أعمال حرجة، تضيف spans يدوية:

func (s *OrderService) CreateOrder(ctx context.Context, req CreateOrderRequest) (*Order, error) {
    ctx, span := otel.Tracer("orders-svc").Start(ctx, "CreateOrder")
    defer span.End()

    span.SetAttributes(
        attribute.String("tenant_id", req.TenantID.String()),
        attribute.Int("item_count", len(req.Items)),
    )
    // ...
    return order, nil
}

إضافة tenant_id كـ attribute مفيدة بشكل خاص في SaaS متعدد المستأجرين. عند رؤية trace بطيء، يمكنك التصفية فورًا حسب المستأجر وتحديد ما إذا كان البطء خاصًا بمستأجر معين.

كيف تشغل كولكتور OTel كـ sidecar في ECS؟

يعمل OpenTelemetry Collector كحاوية ثانية في تعريف مهمة ECS. يستقبل الـ spans من خدمة Go على localhost:4318، ويجمعها ويصدرها إلى خلفية التتبع.

نحن نضع essential: false على الكولكتور لأن ذلك يعني أنه إذا تعطل pipeline التتبع، فإن حاوية منطق الأعمال تستمر في العمل. التتبع بنية تحتية للمراقبة، وليس وظيفة منتج.

ما الذي يبدو عليه هذا في الممارسة العملية لفرق SaaS في المنطقة؟

لأحد عملائنا في لبنان يشغل منصة إدارة مطاعم عبر 12 موقعًا، كان التتبع الموزع أول ما كشف لنا مشكلة حقيقية: استعلام المخزون المخصص للمستأجر كان بطيئًا تحديدًا لمستأجرَين لديهما أكثر من 50,000 حركة مخزون في قاعدة البيانات. أظهر الـ trace أن span الـ inventory-svc كان 280ms بينما كان نفس الـ span للمستأجرين الآخرين 18ms. وقادنا هذا مباشرةً إلى فهرس مركب مفقود على (tenant_id, created_at) في جدول stock_movements.

الدروس الرئيسية من الإنتاج

التتبع الموزع يسترد تكلفة إعداده خلال أول حادثة إنتاج تحتاجه فيها. ابدأ بالأدوات التلقائية لـ HTTP، أضف spans يدوية حول استدعاءات قاعدة البيانات والمنطق التجاري الحرج، واستخدم معرف المستأجر كـ attribute من البداية.

هل تحتاج إلى مساعدة في البناء؟

فوكسير تبني وتشغل أنظمة Go الخلفية لمنصات SaaS في لبنان ومنطقة الشرق الأوسط وشمال إفريقيا. إذا كنت تشغل خدمات على ECS وتريد إضافة المراقبة، تواصل معنا.

https://voxire.com/get-a-quote/

العودة إلى المدونة
Chat on WhatsApp