הערה: כאשר זמן האחזור p95 של שירות מיקרוסרוויס קופץ במפתיע ל-10 שניות והלוגים ב-Order Service נקיים לחלוטין — מתחיל מצוד הרפאים. במצבים כאלה, אנו מפעילים מעקב מבוזר: OpenTelemetry + Jaeger (או Zipkin) לראייה מלאה. מידע נוסף על מעקב מבוזר ניתן למצוא בויקיפדיה. כל בקשה משאירה שובל דיגיטלי על פני כל השירותים — מ-API Gateway ועד Payment Service — עם חותמות זמן. אתה רואה ש-80% מהזמן מושקע בשאילתת Elasticsearch אחת, לא בנעילה מבוזרת. לאחר היישום, לקוחות מצמצמים את זמן האבחון משלושה שבועות ליומיים — פי 3 מהר יותר. לקוח אחד השיג הפחתה משמעותית בעלויות השנתיות על ידי מזעור זמן השבתה. לקוח אחר עם 25 מיקרוסרוויסים קיצץ את זמן האבחון ב-70%.
אילו בעיות מעקב מבוזר פותר
מצב טיפוסי: שאילתת N+1 ב-Inventory Service הופכת את התגובה ל-5 שניות. או שמטמון Redis נכשל בגלל TTL שגוי — מעקב יראה החמצת מטמון. מעקב מבוזר חושף זמן בכל שירות, קריאות DB (PostgreSQL, MongoDB), API חיצוניים, והעברת קונטקסט. אתה רואה ש-80% מהזמן הולך לשאילתת Elasticsearch אחת, לא לנעילה מבוזרת. אנו מגדירים מעקב כדי לזהות צווארי בקבוק בשעות, לא בשבועות. דוגמה קונקרטית: עבור לקוח עם 15 מיקרוסרוויסים, מעקב מבוזר הראה ש-40% מהבקשות נתקעו בגלל timeout שגוי ב-HTTP client. התיקון לקח שעתיים במקום שבוע של ניחושים.
למה OpenTelemetry הוא התקן דה-פקטו?
OpenTelemetry (OTel) הוא SDK נייטרלי-ספק שמאפשר לשלוח מעקבים לכל backend ללא שינויי קוד. אנו משתמשים בו בכל הפרויקטים: משלבים פעם אחת, ואז בוחרים Jaeger לפיתוח, Datadog לייצור — ללא שכתוב. התמיכה כיום מכסה 20+ שפות ואינטגרציות. בהשוואה ל-SDK קנייניים, OpenTelemetry מקצר את זמן האינטגרציה פי 2 ומפשט הגירה בין backends. הניסיון שלנו בעשרות פרויקטים מאשר את אמינות הגישה הזו.
איך ליישם OpenTelemetry ב-Node.js: שלב אחר שלב
- התקן חבילות:
npm install @opentelemetry/sdk-node @opentelemetry/auto-instrumentations-node @opentelemetry/exporter-trace-otlp-http. - צור קובץ
tracing.ts(ייבוא ראשון). - הגדר exporter: ציין כתובת Jaeger או backend אחר.
- הוסף auto-instrumentations עבור HTTP, Express, PostgreSQL, Redis וכו'.
- הפעל SDK עם
sdk.start().
דוגמת אתחול עבור Order Service:
// tracing.ts — инициализация, импортировать до всего остального import { NodeSDK } from '@opentelemetry/sdk-node'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { Resource } from '@opentelemetry/resources'; import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; const sdk = new NodeSDK({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'order-service', }), traceExporter: new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://jaeger:4318/v1/traces', }), instrumentations: [ getNodeAutoInstrumentations({ '@opentelemetry/instrumentation-http': { enabled: true }, '@opentelemetry/instrumentation-express': { enabled: true }, '@opentelemetry/instrumentation-pg': { enabled: true }, '@opentelemetry/instrumentation-redis': { enabled: true }, }), ], }); sdk.start(); Auto-instrumentations מיירטים Express, pg, redis, axios ללא כתיבת קוד.
יצירת Span ידנית
עבור פעולות עסקיות שאינן מכוסות על ידי auto-instrumentation:
import { trace, SpanStatusCode, context } from '@opentelemetry/api'; const tracer = trace.getTracer('order-service'); async function processOrder(orderId: string): Promise<void> { const span = tracer.startSpan('processOrder', { attributes: { 'order.id': orderId, 'service.operation': 'process' } }); try { await context.with(trace.setSpan(context.active(), span), async () => { const order = await loadOrder(orderId); // дочерний span создаётся авто await validateOrder(order); await reserveInventory(order); // вызов другого сервиса с propagation await chargePayment(order); }); span.setStatus({ code: SpanStatusCode.OK }); } catch (error) { span.recordException(error); span.setStatus({ code: SpanStatusCode.ERROR, message: error.message }); throw error; } finally { span.end(); } } איך לבחור Backend: Jaeger או Zipkin?
| Zipkin | Jaeger | |
|---|---|---|
| אחסון | MySQL, Elasticsearch, Cassandra | Elasticsearch, Cassandra, Kafka |
| ממשק משתמש | בסיסי | עשיר יותר |
| תמיכת OTel | כן | טבעית |
| דגימה | בסיסית | מתקדמת |
לפרויקטים חדשים — Jaeger. Zipkin אם כבר בשימוש או נדרשת תאימות. Jaeger מהיר פי 1.5–2 בממוצע לפריסה ומספק לוחות מחוונים מפורטים יותר. אנו מבטיחים שה-backend הנבחר ישולב בצורה אופטימלית בתשתית שלך.
איך להגדיר דגימה תחת עומס?
מפרט OpenTelemetry ממליץ על דגימה מבוססת ראש (head-based) למערכות בעומס גבוה.
| אסטרטגיה | אחוז לכידה | משאבים | מתי להשתמש |
|---|---|---|---|
| מבוססת ראש (הסתברותית) | 1–10% | נמוכים | מערכות עם תעבורה גבוהה ונפח מעקב גדול |
| מבוססת זנב | 100% עם סינון | גבוהים | צורך בכל מעקבי השגיאות, אירועים נדירים |
דוגמה להגדרת דגימה מבוססת ראש עם OpenTelemetry:
import { ParentBasedSampler, TraceIdRatioBased } from '@opentelemetry/sdk-trace-base'; const sampler = new ParentBasedSampler({ root: new TraceIdRatioBased(0.1) }); זה עוקב אחר 10% מהבקשות, אבל תמיד אם ההורה כבר במעקב.
דוגמת הגדרת דגימה מבוססת זנב עם OpenTelemetry Collector
דגימה מבוססת זנב דורשת OpenTelemetry Collector עם מעבד tail_sampling. הגדרה:
processors: tail_sampling: decision_wait: 30s num_traces: 100 expected_new_traces_per_sec: 10 policies: - name: sample_errors type: status_code properties: status_codes: [ERROR] - name: sample_slow type: latency properties: threshold_ms: 500 מה כלול בהקמת מעקב?
אנו מספקים:
- בחירה ופריסה של backend (Jaeger/Zipkin) עם אחסון (Elasticsearch/Cassandra)
- אינטגרציה של OpenTelemetry SDK עם auto-instrumentations לכל השירותים
- אינסטרומנטציה ידנית של פעולות עסקיות קריטיות
- הגדרת העברת קונטקסט דרך כותרות HTTP (W3C Trace Context)
- הגדרת דגימה תחת עומס
- תיעוד תפעולי ולוחות מחוונים של Grafana
- הדרכת צוות על עבודה עם מעקבים
לוחות זמנים משוערים
- OpenTelemetry SDK + Jaeger + auto-instrumentations עבור 3–5 שירותים: 3–5 ימים
- אינסטרומנטציה ידנית של פעולות עסקיות + הגדרת דגימה: 3–5 ימים נוספים
- הגדרת התראות על p95 latency דרך Prometheus + Grafana: 2–3 ימים
קבל ייעוץ מהנדס — אנו// tracing.ts — инициализация, импортировать до всего остального import { NodeSDK } from '@opentelemetry/sdk-node'; import { getNodeAutoInstrumentations } from '@opentelemetry/auto-instrumentations-node'; import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http'; import { Resource } from '@opentelemetry/resources'; import { SEMRESATTRS_SERVICE_NAME } from '@opentelemetry/semantic-conventions'; const sdk = new NodeSDK({ resource: new Resource({ [SEMRESATTRS_SERVICE_NAME]: 'order-service', }), traceExporter: new OTLPTraceExporter({ url: process.env.OTEL_EXPORTER_OTLP_ENDPOINT || 'http://jaeger:4318/v1/traces', }), instrumentations: [ getNodeAutoInstrumentations({ '@opentelemetry/instrumentation-http': { enabled: true }, '@opentelemetry/instrumentation-express': { enabled: true }, '@opentelemetry/instrumentation-pg': { enabled: true }, '@opentelemetry/instrumentation-redis': { enabled: true }, }), ], }); sdk.start(); נקבל תמונה מלאה של ביצועי המיקרוסרוויסים. צור קשר כדי להעריך את הפרויקט שלך וללמוד כיצד מעקב מבוזר יקצר את זמן הדיבאג במערכת שלך.







