本书是作者基于其在Uber跟踪团队担任技术主管时的个人经历而写的。本书分4部分共14章,内容包括:为什么需要分布式跟踪、跟踪一次HotROD之旅、分布式跟踪基础、OpenTracing的埋点基础、异步应用程序埋点、跟踪标准与生态系统、使用服务网格进行跟踪、关于采样、跟踪的价值、分布式上下文传播、集成指标与日志、通过数据挖掘提炼洞见、在大型组织中实施跟踪、分布式跟踪系统的底层架构。希望读者能通过本书了解分布式跟踪及其相关应用的基本原则和设计思路,从而找到将其应用到自己的项目和系统中的有效方法。本书的目标读者包括应用程序开发人员、SRE工程师、DevOps工程师、框架和基础设施开发人员、技术经理和管理人员、跟踪团队等。
Yuri Shkuro是Uber的软件工程师,专注于分布式跟踪、可观察性、可靠性和性能领域的研究。他是Uber 跟踪团队的技术负责人。在加入Uber之前,Yuri曾在华尔街工作了15年,为顶级投资银行、高盛、摩根大通和摩根士丹利的衍生业务构建了交易和风险管理系统。Yuri在开源社区中的贡献包括,成为OpenTracing项目的联合创始人,以及Jaeger(Uber开发的分布式跟踪平台)的创建者和技术领导者。以上两个项目都基于云原生技术基金会(CNCF,Cloud Native Computing Foundation)。Yuri也是W3C分布式跟踪工作组的特邀专家。
冯文辉,现任ThoughtWorks中国区资深架构咨询师,具有11年的软件行业经验,曾服务于多个世界500强企业,覆盖银行、保险、通信、汽车、物流等行业。为客户提供敏捷开发、DevOps、架构设计与数字化转型等咨询服务。热衷于探索更好的架构设计方法,助力企业的数字化转型。译有《SRE生存指南:系统中断响应与正常运行时间最大化》。
I 引言 1
1 为什么需要分布式跟踪 2
微服务与云原生应用程序 3
什么是可观测性 5
微服务的可观测性挑战 7
传统的监控工具 9
指标 10
日志 11
分布式跟踪 12
我在跟踪领域的经历 14
为何编写本书 17
总结 18
参考资料 19
2 跟踪一次HotROD之旅 20
先决条件 21
从预打包的二进制文件运行 21
从Docker镜像运行 22
从源代码运行 22
启动Jaeger 24
初识HotROD 26
架构 29
数据流 30
上下文日志 32
span标记与日志 35
确定延迟的来源 37
资源使用属性 50
总结 53
参考资料 54
3 分布式跟踪基础 55
想法 56
请求相关性 56
黑盒推理 57
特定于域的模式 57
元数据传播 57
剖析分布式跟踪 59
采样 60
保留因果关系 60
请求间因果关系 62
跟踪模型 63
事件模型 63
span模型 65
时钟偏差调整 67
跟踪分析 69
总结 70
参考资料 70
Ⅱ 数据收集问题 73
4 OpenTracing的埋点基础 74
先决条件 76
项目源代码 76
Go开发环境 77
Java开发环境 78
Python开发环境 78
MySQL数据库 78
查询工具(curl或wget) 79
跟踪后端(Jaeger) 79
OpenTracing 80
练习1:Hello应用程序 83
用Go语言实现Hello应用程序 84
用Java语言实现Hello应用程序 88
用Python语言实现Hello应用程序 92
练习总结 94
练习2:第一个跟踪 94
步骤1:创建跟踪器实例 94
步骤2:启动span 99
步骤3:注释span 102
练习总结 107
练习3:跟踪函数和传递上下文 108
步骤1:跟踪单个函数 109
步骤2:将多个span合并为一个跟踪 111
步骤3:传播进程内上下文 115
练习总结 123
练习4:跟踪RPC请求 124
步骤1:拆解单体 124
步骤2:在进程之间传递上下文 127
步骤3:应用OpenTracing推荐的标记 136
练习总结 141
练习5:使用baggage 141
在Go中使用baggage 142
在Java中使用baggage 142
在Python中使用baggage 143
练习总结 143
练习6:自动埋点 143
Go中的开源埋点 144
Java中的自动埋点 146
Python中的自动埋点 148
练习7:额外练习 151
总结 151
参考资料 152
5 异步应用程序埋点 153
先决条件 154
项目源代码 154
Java 开发环境 155
Kafka、ZooKeeper、Redis与Jaeger 155
Tracing Talk聊天应用程序 156
实现 158
运行应用程序 162
观察跟踪 163
使用OpenTracing埋点 166
Spring埋点 167
tracer resolver 167
Redis埋点 168
Kafka埋点 170
埋点异步代码 178
总结 183
参考资料 183
6 跟踪标准与生态系统 184
埋点形式 185
分析跟踪部署和互操作性 188
跟踪的五种含义 190
了解受众 192
生态系统 193
跟踪系统 193
X-Ray、Stackdriver等 194
标准项目 194
总结 200
参考资料 201
7 使用服务网格进行跟踪 202
服务网格 203
服务网格的可观测性 206
先决条件 207
项目源代码 207
Java开发环境 208
Kubernetes 208
Istio 208
Hello应用程序 210
使用Istio进行分布式跟踪 213
使用Istio生成服务图 223
分布式上下文和路由 225
总结 228
参考资料 228
8 关于采样 230
基于头部的一致性采样 231
概率采样 231
速率限制采样 232
保证吞吐量的概率采样 234
自适应采样 235
上下文敏感的采样 244
实时采样或调试采样 244
如何处理过采样 247
基于尾部的一致性采样 249
部分采样 253
总结 253
参考资料 253
Ⅲ 从跟踪中获取价值 255
9 跟踪的价值 256
作为知识库的跟踪 257
服务图 257
深度,路径感知服务图 259
检测架构问题 262
性能分析 263
关键路径分析 263
识别跟踪模式 265
范例 269
延迟直方图 271
长期性能分析 273
总结 273
参考资料 274
10 分布式上下文传播 275
布朗跟踪平面 276
Pivot Tracing 280
混沌工程 283
流量标记 285
生产环境测试 286
生产环境调试 287
在生产环境中进行开发 288
总结 289
参考资料 289
11 集成指标与日志 291
可观测性的三大支柱 292
先决条件 294
项目源代码 294
Java开发环境 295
在Docker中运行服务器 295
在Kibana中声明索引模式 296
运行客户端 297
Hello应用程序 298
与指标集成 299
通过跟踪埋点实现标准指标 299
向标准指标中添加上下文 303
上下文感知的指标API 308
与日志集成 309
结构化日志记录 309
将日志与跟踪上下文关联起来 311
上下文感知的日志API 316
在跟踪系统中捕获日志 316
是否需要单独的日志记录和跟踪后端 318
总结 319
参考资料 320
12 通过数据挖掘提炼洞见 321
特征提取 322
数据挖掘管道的组件 323
跟踪后端 324
跟踪完成触发器 324
特征提取器 325
聚合器 326
特征提取练习 326
先决条件 328
项目源代码 328
在Docker中运行服务器 329
在Elasticsearch中定义索引映射 330
Java开发环境 331
微服务模拟器 331
在Kibana中定义索引模式 334
span计数作业 336
跟踪完成触发器 338
特征提取器 340
观测趋势 341
谨防推断 349
历史分析 350
实时分析 350
总结 353
参考资料 353
Ⅳ 部署和维护跟踪基础设施 355
13 在大型组织中实施跟踪 356
为什么很难部署跟踪埋点 357
减少采用障碍 358
标准框架 359
内部适配器库 360
默认启用跟踪 361
monorepo 361
与现有的基础设施集成 362
从哪里开始 362
构建文化 364
解释价值 364
与开发人员工作流集成 365
跟踪质量指标 366
故障排除指南 369
跳出关键路径 369
总结 369
参考资料 370
14 分布式跟踪系统的底层架构 371
为什么需要自己“造轮子” 372
定制和集成 372
带宽成本 372
把控数据 373
押注新兴标准 373
架构和部署模式 374
基本架构:代理+收集器+查询服务 374
流式架构 377
多租户 378
安全 381
在多个数据中心运行 382
监控和故障诊断 384
弹性 386
过采样 386
调试跟踪 387
数据中心故障转移导致的流量峰值 387
无休止的跟踪 387
长跟踪 388
总结 388
参考资料 388
后记 390
参考资料 393