微服务追踪:Spring Cloud Sleuth

要重新更新文章了,边学习边更。
参考文章:Tracing In Microservices With Spring Cloud Sleuth

微服务增长时,开发者遇到的一个问题就是如何追踪从一个服务到另一个服务的请求。想要知道请求是如何在微服务中穿行是一件困难的事,尤其是你对微服务内部如何调用还不是很深入的时候。

Spring Cloud Sleuth就是为了帮助解决这个问题,它在微服务的logging引入唯一性的id让你知道一个请求如何从一个微服务到另一个微服务。

Spring Cloud Sleuth添加2种类型id到你的日志中,一个是trace id 另一个是span id,span id是最基本单元,例如发送一个http请求,一个trace id包含多个span id,类似树结构。trace id在各个服务交互中保持一致。让我们来看一下如何用sleuth来追求请求的简单例子。

首先建立一个spring boot项目添加spring-cloud-starter-slueth依赖。最好给你的程序设置一个名字通过 spring.application.name,这个名字会显示在追踪信息中。

现在让我们添加一些打印日志

@SpringBootApplication
@RestController
public class SleuthSampleApplication {
    public static void main(String[] args) {
        SpringApplication.run(SleuthSampleApplication.class, args);
    }

    @RequestMapping("/")
    public String home() {
        LOG.log(Level.INFO, "you called home");
    return "Hello World";
    }
}

启动项目,访问http://localhost:8080你会看到 Hello World.同时会打印出日志

2016-06-15 16:55:56.334  INFO [slueth-sample,44462edc42f2ae73,44462edc42f2ae73,false] 13978 --- [nio-8080-exec-1] com.example.SleuthSampleApplication      : calling home

可以看到日志中多了 [slueth-sample,44462edc42f2ae73,44462edc42f2ae73,false]。这些有什么含义呢?首先第一部分是application name(yml中通过spring.application.name设置的)。第二部分是trace id。第三个部分是span id。最后的false代表span是否开放给zipkin(后面会讲到)

除了添加追踪信息到日志之外,Sleuth还提供了一些其他的帮助。记住我们的真正问题不是在单个服务中辨认log而是追踪跨越多个服务的请求链。微服务之间一般用rest api同步交互或者通过消息中间件异步交互。Seluth都提供了支持 下面的例子我们看一下rest api如何追踪的。

这个简单例子我们通过RestTemplate来调用自己。我们修改一下代码

private static final Logger LOG = Logger.getLogger(SleuthSampleApplication.class.getName());

@Autowired
private RestTemplate restTemplate;

public static void main(String[] args) {
SpringApplication.run(SleuthSampleApplication.class, args);
}

@Bean
public RestTemplate getRestTemplate() {
    return new RestTemplate();
}

@RequestMapping("/")
public String home() {
LOG.log(Level.INFO, "you called home");
    return "Hello World";
}

@RequestMapping("/callhome")
public String callHome() {
LOG.log(Level.INFO, "calling home");
    return restTemplate.getForObject("http://localhost:8080", String.class);
}

看到上面的代码你第一件事可能会问:为什么要使用RestTemplate? 这是必须的因为Sleuth会在request的headers里面添加trace id和span id.

启动项目 访问 http://localhost:8080/callhome 你会看到2条日志

2016-06-17 16:12:36.902  INFO [slueth-sample,432943172b958030,432943172b958030,false] 12157 --- [nio-8080-exec-2] com.example.SleuthSampleApplication      : calling home
2016-06-17 16:12:36.940  INFO [slueth-sample,432943172b958030,b4d88156bc6a49ec,false] 12157 --- [nio-8080-exec-3] com.example.SleuthSampleApplication      : you called home

注意2条日志的trace id是一样的但是span id不一样。trace id就是你能够追踪一个请求从一个服务到另一个服务的原因所在。span id不同是因为我们有2次不同的“工作单元”,即2个请求

如果你打开浏览器debug工具看一下 /callhome请求的headers你会发现2个headers在response中

X-B3-SpanId: fbf39ca6e571f294
X-B3-TraceId: fbf39ca6e571f294

这些headers就是Sleuth能够在微服务中追踪请求的原因。

如果你在用Feign,追踪信息同样会添加到这些请求中。同样的Zuul也会trace和span headers通过代理转发给其他服务。

Zipkin

日志中的这些附加信息确实很好但是想要理解所有信息非常麻烦。用类似ELK之类的工具进行收集和分析会帮助很大。这样通过trace id 你就可以非常简单搜索到收集的日志并查看http请求是如何从一个微服务到另一个的。

然而你要是想看时间信息呢?你当然可以自己计算但是非常痛苦。好消息是已经有一个叫Zipkin的项目可以帮助我们了。Sleuth会把追踪信息发送到你指定的zipken服务当你依赖了 spring-cloud-sleuth-zipkin。默认Sleuth会假定你的zipkin服务运行在 http://localhost:9411。 地址可以通过spring.zipkin.baseUrl进行配置。

我们可以用zipkin收集上面例子的追踪信息。创建一个新的spring boot项目依赖zipin ui和zipkin server。设置端口为9411。启动项目浏览器输入 http://localhost:9411 你会看到 zipkin ui

ui

让我们上面的例子开启发送追踪信息到zipkin server。打开pom添加

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>

此外我们需要告诉我们的应用程序需要发送哪些信息给zipkin。因为是个demo,所以让我们发送全部通过创建一个AlwaysSampler

@Bean
public AlwaysSampler defaultSampler() {
  return new AlwaysSampler();
}

添加完重新启动。输入 http://localhost:8080/callhome 你会发现日志的 export flag 从 false 变成了 true.

2016-06-20 09:03:44.939  INFO [slueth-sample,380c24fd1e5f89df,380c24fd1e5f89df,true] 19263 --- [nio-8080-exec-1] com.example.SleuthSampleApplication      : calling home
2016-06-20 09:03:44.966  INFO [slueth-sample,380c24fd1e5f89df,fc50a65582b7b845,true] 19263 --- [nio-8080-exec-2] com.example.SleuthSampleApplication      : you called home

这说明追踪信息发送到了 zipkin server。 打开 zipkin ui 页面 确保日期范围正确然后点击find taces 。你会看到 /callhome 的追踪信息 。点击会给你显示详细包含时间信息。

image.png
image.png

如果你想要了解更多,建议去了解官网文档。

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

推荐阅读更多精彩内容