博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
zipkin Span 分析
阅读量:3576 次
发布时间:2019-05-20

本文共 10699 字,大约阅读时间需要 35 分钟。

zipkin 的Span有两个版本V1及V2,但是最终再代码的运转亦或是ES中存储的所体现的其实都是V2的Span,下面我们来分析分析这两个Span有什么异同。

V1的Span 应该是我们所熟悉的,它就是来源与谷歌的那篇论文,拥有CR,CS,SR,SS等Annotation,同时还拥有BinaryAnnotation。我们来看看其主要成员。

public final long traceIdHigh;  public final long traceId;    public final String name;   @Nullable  public final Long parentId;   @Nullable  public final Long timestamp;    @Nullable  public final Long duration;   public final List
annotations; public final List
binaryAnnotations; @Nullable public final Boolean debug;

来看一个存储的Span

两个SPANTrace e8d779e43243cd5b[  {    "traceId": "e8d779e43243cd5b",    "id": "e8d779e43243cd5b",    "name": "ttt",    "timestamp": 1553414640395000,    "duration": 96581,    "binaryAnnotations": [      {        "key": "chane",        "value": "1234",        "endpoint": {          "serviceName": "shopservicename",          "ipv4": "192.168.88.103"        }      },      {        "key": "lc",        "value": "tttttt",        "endpoint": {          "serviceName": "shopservicename",          "ipv4": "192.168.88.103"        }      }    ]  },  {    "traceId": "e8d779e43243cd5b",    "id": "ac75f268aab05339",    "name": "queryflowprcpln",    "parentId": "e8d779e43243cd5b",    "timestamp": 1553414640399000,    "duration": 94000,    "annotations": [      {        "timestamp": 1553414640399000,        "value": "cs",        "endpoint": {          "serviceName": "shopservicename",          "ipv4": "192.168.88.103"        }      },      {        "timestamp": 1553414640493000,        "value": "cr",        "endpoint": {          "serviceName": "shopservicename",          "ipv4": "192.168.88.103"        }      }    ]  }]

我们再来看看V2 的Span

// Custom impl to reduce GC churn and Kryo which cannot handle AutoValue subclass  // See https://github.com/openzipkin/zipkin/issues/1879  final String traceId, parentId, id;  final Kind kind;  final String name;  final long timestamp, duration; // zero means null, saving 2 object references  final Endpoint localEndpoint, remoteEndpoint;  final List
annotations; final Map
tags; final int flags; // bit field for timestamp and duration, saving 2 object references

实际存储

{    "took": 3,    "timed_out": false,    "_shards": {        "total": 20,        "successful": 20,        "skipped": 0,        "failed": 0    },    "hits": {        "total": 2,        "max_score": 0,        "hits": [            {                "_index": "zipkin:span-2019-03-24",                "_type": "span",                "_id": "xHu6rmkB4ZW4b3UBVS-t",                "_score": 0,                "_source": {                    "traceId": "e8d779e43243cd5b",                    "duration": 94000,                    "localEndpoint": {                        "serviceName": "shopservicename",                        "ipv4": "192.168.88.103"                    },                    "timestamp_millis": 1553414640399,                    "kind": "CLIENT",                    "name": "queryflowprcpln",                    "id": "ac75f268aab05339",                    "parentId": "e8d779e43243cd5b",                    "timestamp": 1553414640399000                }            },            {                "_index": "zipkin:span-2019-03-24",                "_type": "span",                "_id": "xXu6rmkB4ZW4b3UBVS-t",                "_score": 0,                "_source": {                    "traceId": "e8d779e43243cd5b",                    "duration": 96581,                    "localEndpoint": {                        "serviceName": "shopservicename",                        "ipv4": "192.168.88.103"                    },                    "timestamp_millis": 1553414640395,                    "name": "ttt",                    "id": "e8d779e43243cd5b",                    "timestamp": 1553414640395000,                    "tags": {                        "chane": "1234",                        "lc": "tttttt"                    }                }            }        ]    }}

两者有比较大的不一样。当zipkin Server 接收到V1 时会有一个转换器将其转换成V2。那这两者是怎么转换的呢。

CR 及 CS 的Annoation 会转换成Kind 为Client。其次CR 及CS 下的EndPoint 会被转换为localEndpoint。

至于我们经常用来存储key-value 的BinaryAnnoation 也会被转换成tags中的一条Entry<String,String>。

zipkin 采用的ES来进行存储,我们来看看其在ES中的索引是怎么定义的。

{    "zipkin:span-2019-03-24": {        "aliases": {},        "mappings": {            "span": {                "_source": {                    "excludes": [                        "_q"                    ]                },                "dynamic_templates": [                    {                        "strings": {                            "match": "*",                            "match_mapping_type": "string",                            "mapping": {                                "ignore_above": 256,                                "norms": false,                                "type": "keyword"                            }                        }                    }                ],                "properties": {                    "_q": {                        "type": "keyword"                    },                    "annotations": {                        "type": "object",                        "enabled": false                    },                    "duration": {                        "type": "long"                    },                    "id": {                        "type": "keyword",                        "ignore_above": 256                    },                    "kind": {                        "type": "keyword",                        "ignore_above": 256                    },                    "localEndpoint": {                        "dynamic": "false",                        "properties": {                            "serviceName": {                                "type": "keyword"                            }                        }                    },                    "name": {                        "type": "keyword"                    },                    "parentId": {                        "type": "keyword",                        "ignore_above": 256                    },                    "remoteEndpoint": {                        "dynamic": "false",                        "properties": {                            "serviceName": {                                "type": "keyword"                            }                        }                    },                    "tags": {                        "type": "object",                        "enabled": false                    },                    "timestamp": {                        "type": "long"                    },                    "timestamp_millis": {                        "type": "date",                        "format": "epoch_millis"                    },                    "traceId": {                        "type": "keyword"                    }                }            },            "_default_": {                "dynamic_templates": [                    {                        "strings": {                            "match": "*",                            "match_mapping_type": "string",                            "mapping": {                                "ignore_above": 256,                                "norms": false,                                "type": "keyword"                            }                        }                    }                ]            }        },        "settings": {            "index": {                "number_of_shards": "5",                "provided_name": "zipkin:span-2019-03-24",                "mapper": {                    "dynamic": "false"                },                "creation_date": "1553400823203",                "requests": {                    "cache": {                        "enable": "true"                    }                },                "analysis": {                    "filter": {                        "traceId_filter": {                            "type": "pattern_capture",                            "preserve_original": "true",                            "patterns": [                                "([0-9a-f]{1,16})$"                            ]                        }                    },                    "analyzer": {                        "traceId_analyzer": {                            "filter": "traceId_filter",                            "type": "custom",                            "tokenizer": "keyword"                        }                    }                },                "number_of_replicas": "1",                "uuid": "eRkq_bCyTuuPByMREL4M_w",                "version": {                    "created": "6020399"                }            }        }    }}

 

有一个需要主要的是zipkin 会将annoation 及tags。一起写如es的一个字段“_q”,方便查询

* 

Ex {@code curl -s localhost:9200/zipkin:span-2017-08-11/_search?q=_q:error=500} */ static byte[] prefixWithTimestampMillisAndQuery(Span span, long timestampMillis) { Buffer query = new Buffer(); JsonWriter writer = JsonWriter.of(query); try { writer.beginObject(); if (timestampMillis != 0L) writer.name("timestamp_millis").value(timestampMillis); if (!span.tags().isEmpty() || !span.annotations().isEmpty()) { writer.name("_q"); writer.beginArray(); for (Annotation a : span.annotations()) { if (a.value().length() > 255) continue; writer.value(a.value()); } for (Map.Entry

tag : span.tags().entrySet()) { if (tag.getKey().length() + tag.getValue().length() + 1 > 255) continue; writer.value(tag.getKey()); // search is possible by key alone writer.value(tag.getKey() + "=" + tag.getValue()); } writer.endArray(); } writer.endObject(); } catch (IOException e) { // very unexpected to have an IOE for an in-memory write assert false : "Error indexing query for span: " + span; if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "Error indexing query for span: " + span, e); } return SpanBytesEncoder.JSON_V2.encode(span); } byte[] document = SpanBytesEncoder.JSON_V2.encode(span); if (query.rangeEquals(0L, ByteString.of(new byte[] {'{', '}'}))) { return document; } byte[] prefix = query.readByteArray(); byte[] newSpanBytes = new byte[prefix.length + document.length - 1]; int pos = 0; System.arraycopy(prefix, 0, newSpanBytes, pos, prefix.length); pos += prefix.length; newSpanBytes[pos - 1] = ','; // starting at position 1 discards the old head of '{' System.arraycopy(document, 1, newSpanBytes, pos, document.length - 1); return newSpanBytes; }

由于tags。是不可搜索的,所以针对tags.我们可以利用_q进行搜索。针对文中的tag。可以这么搜索

 "term": {

                "_q": "chane"
              }

 "term": {

                "_q": "chane=1234"
              }

转载地址:http://yhagj.baihongyu.com/

你可能感兴趣的文章
服务器安装mysql 5.7.34的历程,不是8.0.25
查看>>
wentao的日记
查看>>
使用spring-data-elasticsearch时jar包版本冲突的相关总结
查看>>
spring中导入配置文件的区别
查看>>
自定义ArrayList类,实现自动扩容
查看>>
nginx跨域配置
查看>>
如何在一台服务器上部署多个项目而共用一个域名
查看>>
web.xml中的基本配置
查看>>
Springmvc.xml中的配置
查看>>
java泛型的基本概念
查看>>
java精确计算的问题
查看>>
oracle之concat()函数
查看>>
Oracle创建和查询索引
查看>>
linux上连接oracle数据库的步骤
查看>>
使用plsql导出表结构和表数据和存储过程
查看>>
oracle中实例和表空间和用户的关系
查看>>
bme框架常见问题
查看>>
oracle中的函数trunk()和.truncate()和add_months()
查看>>
nginx常用命令
查看>>
OutputStreamWriter和InputStreamReader
查看>>