(4条消息) ZipKin原理学习

ZipKin入门介绍

Zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper的论文设计而来,由 Twitter 公司开发贡献。其主要功能是聚集来自各个异构系统的实时监控数据。分布式跟踪系统还有其他比较成熟的实现,例如:Naver的Pinpoint、Apache的HTrace、阿里的鹰眼Tracing、京东的Hydra、新浪的Watchman,美团点评的CAT,skywalking等。

ZipKin架构

ZipKin可以分为两部分,一部分是zipkin server,用来作为数据的采集存储、数据分析与展示;zipkin client是zipkin基于不同的语言及框架封装的一些列客户端工具,这些工具完成了追踪数据的生成与上报功能,架构如下:

Zipkin Server主要包括四个模块:
(1)Collector 接收或收集各应用传输的数据
(2)Storage 存储接受或收集过来的数据,当前支持Memory,MySQL,Cassandra,ElasticSearch等,默认存储在内存中。
(3)API(Query) 负责查询Storage中存储的数据,提供简单的JSON API获取数据,主要提供给web UI使用

(4)Web 提供简单的web界面

服务追踪流程如下:

  1. ┌─────────────┐ ┌───────────────────────┐ ┌─────────────┐ ┌──────────────────┐
  2. │ User Code │ │ Trace Instrumentation │ │ Http Client │ │ Zipkin Collector │
  3. └─────────────┘ └───────────────────────┘ └─────────────┘ └──────────────────┘
  4. │ │ │ │
  5. ┌─────────┐
  6. │ ──┤GET /foo ├─▶ │ ────┐ │ │
  7. └─────────┘ │ record tags
  8. │ │ ◀───┘ │ │
  9. ────┐
  10. │ │ │ add trace headers │ │
  11. ◀───┘
  12. │ │ ────┐ │ │
  13. │ record timestamp
  14. │ │ ◀───┘ │ │
  15. ┌─────────────────┐
  16. │ │ ──┤GET /foo ├─▶ │ │
  17. │X-B3-TraceId: aa │ ────┐
  18. │ │ │X-B3-SpanId: 6b │ │ │ │
  19. └─────────────────┘ │ invoke
  20. │ │ │ │ request │
  21. │ │ │ │ │
  22. ┌────────┐ ◀───┘
  23. │ │ ◀─────┤200 OK ├─────── │ │
  24. ────┐ └────────┘
  25. │ │ │ record duration │ │
  26. ┌────────┐ ◀───┘
  27. │ ◀──┤200 OK ├── │ │ │
  28. └────────┘ ┌────────────────────────────────┐
  29. │ │ ──┤ asynchronously report span ├────▶ │
  30. │ │
  31. │{ │
  32. │ "traceId": "aa", │
  33. │ "id": "6b", │
  34. │ "name": "get", │
  35. │ "timestamp": 1483945573944000,│
  36. │ "duration": 386000, │
  37. │ "annotations": [ │
  38. │--snip-- │
  39. └────────────────────────────────┘

Instrumented client和server是分别使用了ZipKin Client的服务,Zipkin Client会根据配置将追踪数据发送到Zipkin  Server中进行数据存储、分析和展示。

ZipKin几个概念

    在追踪日志中,有几个基本概念spanId、traceId、parentId

    traceId:用来确定一个追踪链的16字符长度的字符串,在某个追踪链中保持不变。

    spanId:区域Id,在一个追踪链中spanId可能存在多个,每个spanId用于表明在某个服务中的身份,也是16字符长度的字符串。

    parentId:在跨服务调用者的spanId会传递给被调用者,被调用者会将调用者的spanId作为自己的parentId,然后自己再生成spanId。

    如下图:

    刚发起调用时traceId和spanId是一致,parentId不存在。

    被调用者的traceId和调用者的traceId时一致的,被调用者会产生自己的spanId,并且被调用者的parentId是调用者的spanId

安装

1、下载:

    下载地址:https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec

2、运行:java -jar  zipkin-server-2.8.3-exec.jar

    

3、访问:zipkin Server 运行后默认的访问地址:http://localhost:9411

4、调用链分析

    启动4个服务,调用关系如下:brave-webmvc-example服务调用brave-webmvc-example2,brave-webmvc-example2分别调用brave-webmvc-example3和brave-webmvc-example4(代码地址),链路关系如下图:

右上角JSON节目可以看到4个服务的调用数据如下图:

  1. [
  2. {
  3. "traceId": "a4aa11d855699355",
  4. "id": "a4aa11d855699355",
  5. "name": "get /start",
  6. "timestamp": 1526110753393795,
  7. "duration": 3873359,
  8. "annotations": [
  9. {
  10. "timestamp": 1526110753393795,
  11. "value": "sr",
  12. "endpoint": {
  13. "serviceName": "brave-webmvc-example",
  14. "ipv4": "192.168.1.101"
  15. }
  16. },
  17. {
  18. "timestamp": 1526110757267154,
  19. "value": "ss",
  20. "endpoint": {
  21. "serviceName": "brave-webmvc-example",
  22. "ipv4": "192.168.1.101"
  23. }
  24. }
  25. ],
  26. "binaryAnnotations": [
  27. {
  28. "key": "ca",
  29. "value": true,
  30. "endpoint": {
  31. "serviceName": "",
  32. "ipv6": "::1",
  33. "port": 64570
  34. }
  35. },
  36. {
  37. "key": "http.method",
  38. "value": "GET",
  39. "endpoint": {
  40. "serviceName": "brave-webmvc-example",
  41. "ipv4": "192.168.1.101"
  42. }
  43. },
  44. {
  45. "key": "http.path",
  46. "value": "/start",
  47. "endpoint": {
  48. "serviceName": "brave-webmvc-example",
  49. "ipv4": "192.168.1.101"
  50. }
  51. },
  52. {
  53. "key": "mvc.controller.class",
  54. "value": "HomeController",
  55. "endpoint": {
  56. "serviceName": "brave-webmvc-example",
  57. "ipv4": "192.168.1.101"
  58. }
  59. },
  60. {
  61. "key": "mvc.controller.method",
  62. "value": "start",
  63. "endpoint": {
  64. "serviceName": "brave-webmvc-example",
  65. "ipv4": "192.168.1.101"
  66. }
  67. }
  68. ]
  69. },
  70. {
  71. "traceId": "a4aa11d855699355",
  72. "id": "cf49951d471ac7c5",
  73. "name": "get /foo",
  74. "parentId": "a4aa11d855699355",
  75. "timestamp": 1526110753583404,
  76. "duration": 3650640,
  77. "annotations": [
  78. {
  79. "timestamp": 1526110753583404,
  80. "value": "cs",
  81. "endpoint": {
  82. "serviceName": "brave-webmvc-example",
  83. "ipv4": "192.168.1.101"
  84. }
  85. },
  86. {
  87. "timestamp": 1526110754327066,
  88. "value": "sr",
  89. "endpoint": {
  90. "serviceName": "brave-webmvc-example2",
  91. "ipv4": "192.168.1.101"
  92. }
  93. },
  94. {
  95. "timestamp": 1526110757234044,
  96. "value": "cr",
  97. "endpoint": {
  98. "serviceName": "brave-webmvc-example",
  99. "ipv4": "192.168.1.101"
  100. }
  101. },
  102. {
  103. "timestamp": 1526110757235819,
  104. "value": "ss",
  105. "endpoint": {
  106. "serviceName": "brave-webmvc-example2",
  107. "ipv4": "192.168.1.101"
  108. }
  109. }
  110. ],
  111. "binaryAnnotations": [
  112. {
  113. "key": "ca",
  114. "value": true,
  115. "endpoint": {
  116. "serviceName": "",
  117. "ipv4": "127.0.0.1",
  118. "port": 64578
  119. }
  120. },
  121. {
  122. "key": "http.method",
  123. "value": "GET",
  124. "endpoint": {
  125. "serviceName": "brave-webmvc-example",
  126. "ipv4": "192.168.1.101"
  127. }
  128. },
  129. {
  130. "key": "http.method",
  131. "value": "GET",
  132. "endpoint": {
  133. "serviceName": "brave-webmvc-example2",
  134. "ipv4": "192.168.1.101"
  135. }
  136. },
  137. {
  138. "key": "http.path",
  139. "value": "/foo",
  140. "endpoint": {
  141. "serviceName": "brave-webmvc-example",
  142. "ipv4": "192.168.1.101"
  143. }
  144. },
  145. {
  146. "key": "http.path",
  147. "value": "/foo",
  148. "endpoint": {
  149. "serviceName": "brave-webmvc-example2",
  150. "ipv4": "192.168.1.101"
  151. }
  152. },
  153. {
  154. "key": "mvc.controller.class",
  155. "value": "HomeController",
  156. "endpoint": {
  157. "serviceName": "brave-webmvc-example2",
  158. "ipv4": "192.168.1.101"
  159. }
  160. },
  161. {
  162. "key": "mvc.controller.method",
  163. "value": "foo",
  164. "endpoint": {
  165. "serviceName": "brave-webmvc-example2",
  166. "ipv4": "192.168.1.101"
  167. }
  168. }
  169. ]
  170. },
  171. {
  172. "traceId": "a4aa11d855699355",
  173. "id": "c2c029d693ecc49b",
  174. "name": "get /bar",
  175. "parentId": "cf49951d471ac7c5",
  176. "timestamp": 1526110754397322,
  177. "duration": 1583187,
  178. "annotations": [
  179. {
  180. "timestamp": 1526110754397322,
  181. "value": "cs",
  182. "endpoint": {
  183. "serviceName": "brave-webmvc-example2",
  184. "ipv4": "192.168.1.101"
  185. }
  186. },
  187. {
  188. "timestamp": 1526110755367168,
  189. "value": "sr",
  190. "endpoint": {
  191. "serviceName": "brave-webmvc-example3",
  192. "ipv4": "192.168.1.101"
  193. }
  194. },
  195. {
  196. "timestamp": 1526110755810759,
  197. "value": "ss",
  198. "endpoint": {
  199. "serviceName": "brave-webmvc-example3",
  200. "ipv4": "192.168.1.101"
  201. }
  202. },
  203. {
  204. "timestamp": 1526110755980509,
  205. "value": "cr",
  206. "endpoint": {
  207. "serviceName": "brave-webmvc-example2",
  208. "ipv4": "192.168.1.101"
  209. }
  210. }
  211. ],
  212. "binaryAnnotations": [
  213. {
  214. "key": "ca",
  215. "value": true,
  216. "endpoint": {
  217. "serviceName": "",
  218. "ipv4": "127.0.0.1",
  219. "port": 64583
  220. }
  221. },
  222. {
  223. "key": "http.method",
  224. "value": "GET",
  225. "endpoint": {
  226. "serviceName": "brave-webmvc-example2",
  227. "ipv4": "192.168.1.101"
  228. }
  229. },
  230. {
  231. "key": "http.method",
  232. "value": "GET",
  233. "endpoint": {
  234. "serviceName": "brave-webmvc-example3",
  235. "ipv4": "192.168.1.101"
  236. }
  237. },
  238. {
  239. "key": "http.path",
  240. "value": "/bar",
  241. "endpoint": {
  242. "serviceName": "brave-webmvc-example2",
  243. "ipv4": "192.168.1.101"
  244. }
  245. },
  246. {
  247. "key": "http.path",
  248. "value": "/bar",
  249. "endpoint": {
  250. "serviceName": "brave-webmvc-example3",
  251. "ipv4": "192.168.1.101"
  252. }
  253. },
  254. {
  255. "key": "mvc.controller.class",
  256. "value": "HomeController",
  257. "endpoint": {
  258. "serviceName": "brave-webmvc-example3",
  259. "ipv4": "192.168.1.101"
  260. }
  261. },
  262. {
  263. "key": "mvc.controller.method",
  264. "value": "bar",
  265. "endpoint": {
  266. "serviceName": "brave-webmvc-example3",
  267. "ipv4": "192.168.1.101"
  268. }
  269. }
  270. ]
  271. },
  272. {
  273. "traceId": "a4aa11d855699355",
  274. "id": "e3968cec8747ce95",
  275. "name": "get /tar",
  276. "parentId": "cf49951d471ac7c5",
  277. "timestamp": 1526110756017988,
  278. "duration": 1194871,
  279. "annotations": [
  280. {
  281. "timestamp": 1526110756017988,
  282. "value": "cs",
  283. "endpoint": {
  284. "serviceName": "brave-webmvc-example2",
  285. "ipv4": "192.168.1.101"
  286. }
  287. },
  288. {
  289. "timestamp": 1526110757081683,
  290. "value": "sr",
  291. "endpoint": {
  292. "serviceName": "brave-webmvc-example4",
  293. "ipv4": "192.168.1.101"
  294. }
  295. },
  296. {
  297. "timestamp": 1526110757212859,
  298. "value": "cr",
  299. "endpoint": {
  300. "serviceName": "brave-webmvc-example2",
  301. "ipv4": "192.168.1.101"
  302. }
  303. },
  304. {
  305. "timestamp": 1526110757222145,
  306. "value": "ss",
  307. "endpoint": {
  308. "serviceName": "brave-webmvc-example4",
  309. "ipv4": "192.168.1.101"
  310. }
  311. }
  312. ],
  313. "binaryAnnotations": [
  314. {
  315. "key": "ca",
  316. "value": true,
  317. "endpoint": {
  318. "serviceName": "",
  319. "ipv4": "127.0.0.1",
  320. "port": 64584
  321. }
  322. },
  323. {
  324. "key": "http.method",
  325. "value": "GET",
  326. "endpoint": {
  327. "serviceName": "brave-webmvc-example4",
  328. "ipv4": "192.168.1.101"
  329. }
  330. },
  331. {
  332. "key": "http.method",
  333. "value": "GET",
  334. "endpoint": {
  335. "serviceName": "brave-webmvc-example2",
  336. "ipv4": "192.168.1.101"
  337. }
  338. },
  339. {
  340. "key": "http.path",
  341. "value": "/tar",
  342. "endpoint": {
  343. "serviceName": "brave-webmvc-example4",
  344. "ipv4": "192.168.1.101"
  345. }
  346. },
  347. {
  348. "key": "http.path",
  349. "value": "/tar",
  350. "endpoint": {
  351. "serviceName": "brave-webmvc-example2",
  352. "ipv4": "192.168.1.101"
  353. }
  354. },
  355. {
  356. "key": "mvc.controller.class",
  357. "value": "HomeController",
  358. "endpoint": {
  359. "serviceName": "brave-webmvc-example4",
  360. "ipv4": "192.168.1.101"
  361. }
  362. },
  363. {
  364. "key": "mvc.controller.method",
  365. "value": "tar",
  366. "endpoint": {
  367. "serviceName": "brave-webmvc-example4",
  368. "ipv4": "192.168.1.101"
  369. }
  370. }
  371. ]
  372. }
  373. ]

 

5、zipkin client采集

 

    目前官方提供了如下客户端插件进行追踪数据的采集(https://github.com/openzipkin/brave/tree/master/instrumentation)

 

 

题外话:由于项目需要和本人推动,尝试,官方在 2.15 版本添加支持 ActiveMQ 支持追踪日志收集

 

(0)

相关推荐