Traces distribuées
Traces distribuées
1) Pourquoi et ce que c'est
La trace distribuée est un moyen de relier les opérations tout au long du chemin de requête : front → API passerelle → microservices → OBD/cache → courtiers → jobs/piplines.
Le résultat est la trace (trace) des spans (span), où chaque span enregistre le fonctionnement du composant avec les attributs, les événements et l'état. Cela accélère le RCA, aide à garder le SLO et réduit le MTTR.
- Visibilité de la voie critique et des « goulets d'étranglement ».
- Corrélation des symptômes (métriques) avec les causes (dormeurs) et les détails (logs).
- L'analyse des retraits, des files d'attente, du DLQ, des fans, des scies de latence.
2) Modèle de données de trace
Trace est une colonne d'appels avec 'trace _ id'.
Span — операция: `name`, `kind` (SERVER/CLIENT/PRODUCER/CONSUMER/INTERNAL), `start/end`, `status`, `attributes`, `events`, `links[]`.
Attributes - clé-valeur (route, db. system, messaging. system, cloud. région, etc.).
Events - marques instantanées à l'intérieur du span (par exemple, "retry", "cache _ miss').
Span Links - liens en dehors du « parent-enfant » (batchi, retrai, fan-in/out).
Ressource - métadonnées de processus/service ('service. name ', version, environnement).
3) Contexte et portabilité
3. 1 W3C Trace Context
Titres :- 'Traceparent ':' version-traceid-spanid-flags '(les drapeaux incluent le sampling).
- « tracestate » : condition spécifique au vendeur (au minimum).
- Baggage - clés pour le contexte d'affaires (limité, sans PII/secrets).
3. 2 Défiler le contexte
HTTP: `traceparent`/`tracestate`; gRPC : métadonnées ; WebSocket : lors de la mise à niveau et dans les messages ;
Messages : dans les headers (Kafka/NATS/RabbitMQ) - nous conservons le contexte initial sous PRODUCER et le transférons sous CONSUMER.
Bases : ne « portent » pas le contexte - nous logions les attributs dans le span (query, rows, db. system), mais pas la valeur.
4) Semer : Comment ne pas ruiner
Head sampling (à l'entrée) : probabiliste/selon les règles (route, tenant, endpoint).
Tail sampling (sur le collecteur) : nous gardons les trajets « intéressants » - erreurs, longues p95/p99, chemins rares.
Exemples : les métriques d'histogramme stockent des références à des 'trace _ id'spécifiques.
Recommandation : combiner - head 5-20 % + règles de tail 100 % pour 5xx/timeout/p99.
5) Attributs et taxonomie (minimum obligatoire)
Général :- `service. name`, `service. version`, `deployment. environment`, `cloud. region`, `http. route`, `http. method`, `http. status_code`, `db. system`, `db. statement '(raccourci/sans données),' messaging. system`, `messaging. operation`, `peer. service`, `net. peer. name`, `tenant. id`, `request. id`.
Labels d'affaires : soigneusement, sans PII. Exemple : 'order. segment`, `plan. tier`.
6) Scripts asynchrones, files d'attente et batchs
PRODUCTEUR → CONSOMMATEUR : nous créons un span PRODUCTEUR avec un contexte ; le message est headers (traceparent, baggage). CONSUMER démarre SERVER/CONSUMER-span avec link sur PRODUCER (sauf hiérarchie stricte).
Fan-out : une entrée - beaucoup d'outputs → des spans enfants ou des liens.
Batch : CONSUMER lit un paquet de N messages → un span avec 'events' pour chaque messageId ou 'links' sur N contextes distincts.
DLQ : span 'messaging séparé. dlq. publish` с reason и count.
Retrai : 'event : retry' + 'retry. count'attribut ; de préférence un nouveau CHILD-span à essayer.
7) Intégration avec logs et métriques
Les logs écrivent JSON avec 'trace _ id '/' span _ id' → nous allons dans les logs en un clic.
Les métriques RED/USE contiennent des exemples → des pics de p99 vont aux « mauvais » spans.
Les pistes génèrent des signaux techniques (erreurs de dépendance) et des signaux métiers (conversion) à travers les événements.
8) Performance et coût
Semer et rater des événements.
Réduction de la cardinalité des attributs (pas de 'user _ id '/' session _ id' comme label !).
Compression/trempage par l'exportateur ; les limites du temps d'exportation.
Stockage : chaud 1-7 jours, puis - les agrégats/seulement les tracés « problématiques ».
Catégories de dépenses : collecteurs, index, stockage, egress.
9) Sécurité et vie privée
In Transit: TLS 1. 3/mTLS kollektor↔agenty ; At Rest : cryptage, clés propres (voir « Cryptage In Transit/At Rest »).
PII et secrets : ne pas écrire dans les attributs/événements ; Tokenization/masquage sur le fabricant.
Polyvalence : 'tenant. id'en tant que label de ressources et isolation des espaces, politiques de lecture ; audit de l'accès à la piste (voir « Audit et journaux immuables »).
10) Schémas de mise en œuvre (référence)
10. 1 SDK OpenTelemetry (pseudo-code)
python from opentelemetry import trace from opentelemetry. sdk. trace import TracerProvider from opentelemetry. sdk. resources import Resource from opentelemetry. sdk. trace. export import BatchSpanProcessor from opentelemetry. exporter. otlp. proto. grpc. trace_exporter import OTLPSpanExporter
provider = TracerProvider(resource=Resource. create({
"service. name":"checkout","service. version":"1. 12. 0","deployment. environment":"prod"
}))
provider. add_span_processor(BatchSpanProcessor(OTLPSpanExporter(endpoint="otel-collector:4317", insecure=True)))
trace. set_tracer_provider(provider)
tr = trace. get_tracer("checkout")
with tr. start_as_current_span("POST /pay", attributes={
"http. route":"/pay","http. method":"POST","tenant. id":"t-42"
}):
business logic, external API call and pass DB
10. 2 Collecteur OTel - tail sampling (fragment)
yaml processors:
tailsampling:
decision_wait: 2s policies:
- type: status_code status_codes: [ERROR]
- type: latency threshold_ms: 900
- type: probabilistic sampling_percentage: 10 exporters:
otlphttp: { endpoint: http://trace-backend:4318 }
service:
pipelines:
traces:
receivers: [otlp]
processors: [batch, tailsampling]
exporters: [otlphttp]
10. 3 Kafka - transfert de contexte (concept)
PRODUCTEUR : nous ajoutons les headers 'traceparent', 'baggage'.
CONSUMER : Si le message initie un nouveau flux - un nouveau SERVEUR/CONSUMER-span c link par contexte à partir de headers.
11) Data/ETL и ML
Pour les piplines de batch : span sur batch/partition avec 'dataset. urn`, `run. id`, `rows. in/out`, `freshness. lag`.
Pour ML : spanas d'entraînement/inference, version modèle, laticy, feature store.
Lien avec Lineage : 'run. id` и `dataset. les urn'permettent de passer de la trace au graphique d'origine des données.
12) Plate-forme de trace SLO
Disponibilité de l'ingestion : ≥ 99. 9%
Délai d'indexation : ≤ 60 s p95
Couverture head-sample : ≥ 5-10 % des itinéraires clés
100 % de sauvegarde des tracés avec le statut ERROR et avec latency> seuil sur le catalogue des « chemins critiques »
Les alertes de la plate-forme : la croissance des drops, les délais d'exportation, l'indexeur, la surchauffe de la cardinalité.
13) Test et vérification
Contrat de traçage en CI : présence de spans sur les endpoints clés, attributs obligatoires, le « traceparent » correct vole par la passerelle/proxy.
Échantillons synthétiques/rum : on recueille les tracés à l'extérieur.
Chaos/incidents : Désactiver les dépendances, vérifier que tail-sampler « ramasse » les erreurs.
Smoke dans la vente : après la sortie - « y a-t-il des spans » et exemplar → traîneau.
14) Chèques-feuilles
Avant la vente
- Le W3C Trace Context est maudit partout ; pour les messages - headers.
- La tête d'échantillonnage de base est incluse ; Les règles tail pour 5xx/p99 sont configurées.
- Attributs obligatoires : route, method, status, service. version, tenant. id.
- Logs JSON avec 'trace _ id '/' span _ id', métriques avec exemplars.
- Désinfectants PII ; cryptage en transit/au repos ; les politiques d'accès.
- Dashboards : « chemin critique », « erreurs de dépendance », « retrai/timaouta ».
Exploitation
- Examen mensuel de la cardinalité des attributs ; quotas.
- Tuning tail-sempling par SLO (moins de bruit, tout « chaud » est dans l'échantillon).
- Formation RCA avec transition métrique → exemplar → trace → logs.
- Vérification des revêtements pour files d'attente, DLQ, jobs ETL.
15) Runbook’и
RCA : croissance p99 sur/pay
1. Ouvrir le RED-dashboard ; de bin p99 passer par examplar à la piste.
2. Trouvez le span CLIENT « étroit » (par exemple, 'gateway. call '), vérifiez' retry. count ', timaoutes.
3. Comparer les versions du service/dépendances, région/zone.
4. Activer la dégradation (réponse de mise en cache/limite RPS), avertir les propriétaires de dépendance.
5. Après le fix - RCA et les tiquets pour l'optimisation.
Sursaut de DLQ
1. Filtre des pistes par 'messaging. dlq. publish`.
2. Vérifiez les raisons (événements), corrélez avec la version.
3. Exécutez reprocess, augmentez temporairement le délai chez CONSUMER, prévenez les propriétaires de downstream.
16) Erreurs fréquentes
Il n'y a pas de contexte à travers les passerelles/courtiers. Solution : middleware/intersepteurs, bibliothèques uniques.
Toutes les remorques sont 100 %. Cher et inutile - utilisez tail-sampling.
Logs sans 'trace _ id'. La corrélation → MTTR ↑ est perdue.
PII dans les attributs. Masquer/Tokeniser ; ne garder que le contexte technique.
Des jobs de fond muets. Ajoutez des spans au batch/partition et au 'run. id`.
C'est différent. Entrez le dictionnaire des noms de span et des clés d'attribut.
17) FAQ
Q : L'échantillonnage de tête ou de tail est-il meilleur ?
A : Combinaison. Head donne la couche de base, tail garantit la conservation des anomalies/erreurs.
Q : Comment tracer à travers Kafka sans hiérarchie rigide ?
R : Utilisez les liens span entre le PRODUCTEUR et le CONSOMMATEUR ; le contexte est dans les headers.
Q : Que faire avec les SQL sensibles ?
O : 'db. statement 'raccourci/normalisé (sans valeur) ou' db. opération '+ dimensions/temps.
Q : Comment lier avec les métriques d'entreprise ?
R : Ajoutez des attributs de domaine sans PII (plan/segment), utilisez les événements « d'étape professionnelle » à l'intérieur du span et passez des métriques de conversion par examplar.
- « Observabilité : logs, métriques, tracés »
- Audit et journaux invariables
- « Cryptage In Transit/At Rest »
- Origine des données (Lineage)
- «Privacy by Design (GDPR)»
- « Gestion des secrets »