Tempo - 分布式Loki链路追踪利器

Tempo是Grafana Labs在ObservabilityCON 2020大会上新开源的一个用于做分布式式追踪的后端服务。它和Cortex、Loki一样,Tempo也是一个兼备高扩展低成本效应的系统。之前小白有提到Grafana Labs的云原生Observability宇宙只剩下trace部分,那么今天就拿Loki的分布式追踪来体验下这Observability的最后一环吧。

关于Tempo

Tempo本质上来说还是一个存储系统,它兼容一些开源的trace协议(包含Jaeger、Zipkin和OpenCensus等),将他们存在廉价的S3存储中,并利用TraceID与其他监控系统(比如Loki、Prometheus)进行协同工作。

image.png

可以看到Tempo的架构仍然分为distributoringesterqueriertempo-querycompactor这几个架构,熟悉Loki和Cortex的朋友可能光看名字就知道他们大概是做什么的。不熟悉的同学也没关系,下面简单说下各模块的作用:

  • distributor

启动多个端口,分别接受来自Jaeger、Zipkin和OpenCensus协议的数据,按照TraceID进行哈希并映射到哈希环上,并交由ingester进行存储处理。当前distributor支持的trace协议如下:

Protocol Port
OpenTelemetry 55680
Jaeger - Thrift Compact 6831
Jaeger - Thrift Binary 6832
Jaeger - Thrift HTTP 14268
Jaeger - GRPC 14250
Zipkin 9411
  • ingester

具体负责trace数据的块存储(memcache、GCS、S3)、缓存(Memcache)和索引的处理

  • querier

负责从ingester和后端存储里面捞取trace数据,并提供api给查询者

  • compactor

负责后端存储块的压缩,减少数据块数量

  • tempo-query

tempo的一个可视化界面,用的jaeger query,可以在上面查询tempo的trace数据。

Loki链路跟踪

要体验的同学,可以先下载小白在GitHub上的Docker-Compose,推荐配合本篇内容一起实践
https://github.com/CloudXiaobai/loki-cluster-deploy/tree/master/demo/docker-compose-with-tempo

Loki方面

在做之前我们先看下Loki的文档是怎么描述的:

The tracing_config block configures tracing for Jaeger. Currently limited to disable auto-configuration per environment variables only.

可以看到当前Loki对于Trace的支持集中在Jaeger,而且配置是默认开启的,并且只能在环境变量里面读取jaeger的信息。docker-compose下的案例如下:

querier-frontend:
  image: grafana/loki:1.6.1
  runtime: runc
  scale: 2
  environment:
    - JAEGER_AGENT_HOST=tempo    \\tempo的地址
    - JAEGER_ENDPOINT=http://tempo:14268/api/traces
    - JAEGER_SAMPLER_TYPE=const   \\采样率类型
    - JAEGER_SAMPLER_PARAM=100    \\采样率100

API网关方面

API网关并不是Loki的原生组件,而是在Loki分布式部署的情况下,需要有一个统一的入口对接口进行路由。之前小白用的Nginx,但是原生的Nginx并不支持OpenTracing。小白根据nginx1.14版本做了一个带jaeger模块的镜像用于Loki入口的trace生成和日志采集。

gateway:
  image: quay.io/cloudxiaobai/nginx-opentracing:1.14.0
  runtime: runc
  restart: always
  ports:
    - 3100:3100
  volumes:
    - ./nginx.conf:/etc/nginx/nginx.conf
    - ./jaeger-config.json:/etc/jaeger-config.json
    - 'gateway_trace_log:/var/log/nginx/'

对于支持OpenTracing的Nginx,我们需要修改nginx.conf配置文件如下:

...
#加载opentracing库
load_module modules/ngx_http_opentracing_module.so;
http {
 
  #启用opentracing
  opentracing on;
 
  #加载jaeger库
  opentracing_load_tracer /usr/local/lib/libjaegertracing_plugin.so /etc/jaeger-config.json;
 
  #日志格式,打印traceid
  log_format opentracing '"traceID":"$opentracing_context_uber_trace_id"';
 
  server {
    listen               3100 default_server;
    location = / {
      #向upstream转发时带上trace的头信息
      opentracing_operation_name $uri;
      opentracing_trace_locations off;
      opentracing_propagate_context;
      proxy_pass      http://querier:3100/ready;
    }
  }
}

以上小白只截取了Nginx部分配置,完整的要参考docker-compose里的nginx.conf

此外,nginx还需要一个jaeger-config.json,用于将trace数据转给agent处理。

{
  "service_name": "gateway", \\服务名
  "diabled": false,
  "reporter": {
    "logSpans": true,
    "localAgentHostPort": "jaeger-agent:6831"  \\jaeger-agent地址
  },
  "sampler": {
    "type": "const",
    "param": "100"  \\采样率
  }
}

为了方便演示,小白配置的采样率均为100%

最后,我们为API网关启用一个Jaeger-agent用于收集trace信息并转给Tempo,它的配置如下:

jaeger-agent:
  image: jaegertracing/jaeger-agent:1.20
  runtime: runc
  restart: always
  # 转发给tempo
  command: ["--reporter.grpc.host-port=tempo:14250"]
  ports:
    - "5775:5775/udp"
    - "6831:6831/udp"
    - "6832:6832/udp"
    - "5778:5778"

为什么API网关不直接发给Tempo要经过Jaeger-agent转发一下,小白认为用agent的方式更加灵活一些。

以上,我们就完成了Loki分布式追踪的配置部分,接下来我们用docker-compose up -d将服务都运行起来。

Grafana方面

当docker的所有服务运行正常后,我们访问grafana并添加两个数据源

  • 添加tempo数据源
image.png
  • 添加Loki数据源,并解析API网关TraceID
image.png
image.png

Loki提取TraceID的正则部分是从API网关的日志中匹配

体验Tempo

数据源设置OK后,我们进入Explore选择loki查询trace.log就可以得到API网关的日志了。


image.png

从Parsed Fields里面我们就可以看到,Grafana从API网关的日志里面提取了16位字符串作为TraceID了,而它关联了Tempo的数据源,我们点击Tempo按钮就可以直接切到Trace的信息如下:

image.png

展开Trace信息,我们可以看到Loki的一次查询的链路会经过下面几个部分

gateway -> query-frontend -> querier -> ingester
                                    |-> SeriesStore.GetChunkRefs

并且得出结论,本次查询的耗时主要落在Ingeter上,原因是查询的日志还没被flush到存储当中,querier需从ingester中取日志的数据。


image.png

我们再来看一个Loki接收日志的案例:


image.png

从trace的链路来看,当日志采集端往Loki Post日志时,请求的链路会经过如下部分:

gateway -> distributor -> ingester

同时,我们还看到了这次的提交的日志流经过两个ingester实例的处理,且处理时间没有明显差异。

总结

关于LoggingTracing两部分在Grafana上的展示还没有达到ObservabilityCON 2020上的流畅度,不过根据会上的消息,更精细话的trace <--> logmetrics <--> tracemetrics <--> log这三部分互相协作部分应该很快会发布。届时Grafana将是云上可观测性应用系统里的王者级产品(虽然有额外的各种查询语句学习成本)。


关注公众号「云原生小白」,获取更多精彩内容

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351