范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

Jaeger开发入门(java版)

  欢迎访问我的GitHub这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos本篇概览前文《分布式调用链跟踪工具Jaeger?两分钟极速体验》咱们体验了Jaeger的基本能力,今天就来编码实践,了解如何将让自己的应用集成Jaeger;本文的目标:今天咱们要在一个分布式系统中部署和使用jaeger,使用方式包括两种:首先是SDK内置的span,例如web请求、mysql或redis的操作等,这些会自动上报,第二种就是自定义span;总的来说,今天的实战步骤如下:今天咱们要从零开发一个迷你的分布式系统,该系统架构如下图所示,可见有两个web应用:服务提供方jaeger-service-provider 和服务调用方jaeger-service-consumer ,再加一个redis:
  jaeger-service-consumer收到用户通过浏览器发来的http请求时,会调用jaeger-service-provider 提供的web服务,而jaeger-service-provider 又会操作一次redis,整个流程与典型的分布式系统类似jaeger-service-consumer 和jaeger-service-provider 在响应服务的过程中,都会将本次服务相关的数据上报到jaeger,这样咱们在jaeger的web页面就能观察到客户的一次请求会经过那些应用,关键位置耗时多少,关键参数是哪些等等;将所有应用制作成镜像,再编写docker-compose.yml文件集成它们运行,验证参考文章本文中会将springboot应用制作成docker镜像,如果您想了解详细的制作过程,可以参考以下两篇文章: 《体验SpringBoot(2.3)应用制作Docker镜像(官方方案)》 《详解SpringBoot(2.3)应用制作Docker镜像(官方方案)》 jaeger接入套路先提前总结Spring Cloud应用接入jaeger的套路,以方便您的使用:添加依赖库opentracing-spring-jaeger-cloud-starter,我这里是3.3.1版本配置jaeger远程端口创建配置类,向spring环境注册TracerBuilderCustomizer实例在需要使用自定义span的代码中,用@Autowired注解引入Trace,使用它的API定制span可以创建span,还可以基于已有span创建子span除了指定span的名字,还能借助Trace的API给span增加标签(tag)和日志(log),这些都会在jaeger的web页面展示出来以上六步就是常规接入套路,接下来的实战就是按照此套路进行的源码下载本篇实战中的完整源码可在GitHub下载到,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
  这个git项目中有多个文件夹,本篇的源码在 spring-cloud-tutorials 文件夹下,如下图红框所示:
  spring-cloud-tutorials 文件夹下有多个子工程,本篇的代码是 jaeger-service-consumer 和 jaeger-service-provider ,如下图红框所示:
  创建web工程之一:jaeger-service-provider为了方便管理依赖库版本, jaeger-service-provider 工程是作为spring-cloud-tutorials的子工程创建的,其pom.xml如下:<?xml version="1.0" encoding="UTF-8"?>               spring-cloud-tutorials         com.bolingcavalry         1.0-SNAPSHOT          4.0.0      jaeger-service-provider                             com.bolingcavalry             common             ${project.version}                                org.springframework.boot             spring-boot-starter-web                                io.opentracing.contrib             opentracing-spring-jaeger-cloud-starter                                org.springframework.boot             spring-boot-starter-data-redis                                                          org.springframework.boot                 spring-boot-maven-plugin                                                               true                                                                  配置文件application.yml,注意由于后面会用到docker-compose,因此redis和jaeger的地址都无需填写具体的IP,只要填写它们的容器名即可: spring:   application:     name: jaeger-service-provider   redis:     database: 0     # Redis服务器地址 写你的ip     host: redis     # Redis服务器连接端口     port: 6379     # Redis服务器连接密码(默认为空)     password:     # 连接池最大连接数(使用负值表示没有限制  类似于mysql的连接池     jedis:       pool:         max-active: 10         # 连接池最大阻塞等待时间(使用负值表示没有限制) 表示连接池的链接拿完了 现在去申请需要等待的时间         max-wait: -1         # 连接池中的最大空闲连接         max-idle: 10         # 连接池中的最小空闲连接         min-idle: 0     # 连接超时时间(毫秒) 去链接redis服务端     timeout: 6000  opentracing:   jaeger:     enabled: true     udp-sender:       host: jaeger       port: 6831配置类: package com.bolingcavalry.jaeger.provider.config;  import io.jaegertracing.internal.MDCScopeManager; import io.opentracing.contrib.java.spring.jaeger.starter.TracerBuilderCustomizer; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration;  @Configuration public class JaegerConfig {     @Bean     public TracerBuilderCustomizer mdcBuilderCustomizer() {         // 1.8新特性,函数式接口         return builder -> builder.withScopeManager(new MDCScopeManager.Builder().build());     } }另外,由于本篇的重点是jaeger,因此redis相关代码就不贴出来了,有需要的读者请在此查看:RedisConfig.java、RedisUtils.java接下来看看如何使用Trace的实例来定制span,下面是定了span及其子span的web接口类,请注意trace的API的使用,代码中已有详细注释,就不多赘述了:package com.bolingcavalry.jaeger.provider.controller;  import com.bolingcavalry.common.Constants; import com.bolingcavalry.jaeger.provider.util.RedisUtils; import io.opentracing.Span; import io.opentracing.Tracer; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.text.SimpleDateFormat; import java.util.Date;  @RestController @Slf4j public class HelloController {      @Autowired     private Tracer tracer;      @Autowired     private RedisUtils redisUtils;      private String dateStr(){         return new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(new Date());     }      /**      * 模拟业务执行,耗时100毫秒      * @param parentSpan      */     private void mockBiz(Span parentSpan) {         // 基于指定span,创建其子span         Span span = tracer.buildSpan("mockBizChild").asChildOf(parentSpan).start();          log.info("hello");         try {             Thread.sleep(100);         } catch (InterruptedException e) {             e.printStackTrace();         }          span.finish();     }      /**      * 返回字符串类型      * @return      */     @GetMapping("/hello")     public String hello() {         long startTime = System.currentTimeMillis();          // 生成当前时间         String timeStr = dateStr();          // 创建一个span,在创建的时候就添加一个tag         Span span = tracer.buildSpan("mockBiz")                     .withTag("time-str", timeStr)                     .start();          // span日志         span.log("normal span log");          // 模拟一个耗时100毫秒的业务         mockBiz(span);          // 增加一个tag         span.setTag("tiem-used", System.currentTimeMillis()-startTime);          // span结束         span.finish();          // 写入redis         redisUtils.set("Hello",  timeStr);         // 返回         return Constants.HELLO_PREFIX + ", " + timeStr;     } }编码已经结束,接下来要将此工程制作成docker镜像了,新建Dockerfile文件,和pom.xml在同一个目录下: # 指定基础镜像,这是分阶段构建的前期阶段 FROM openjdk:8-jdk-alpine as builder  # 设置时区 RUN ln -sf /usr/share/zoneinfo/Asia/Shanghai /etc/localtime RUN echo "Asia/Shanghai" >/etc/timezone  # 执行工作目录 WORKDIR application # 配置参数 ARG JAR_FILE=target/*.jar # 将编译构建得到的jar文件复制到镜像空间中 COPY ${JAR_FILE} application.jar # 通过工具spring-boot-jarmode-layertools从application.jar中提取拆分后的构建结果 RUN java -Djarmode=layertools -jar application.jar extract  # 正式构建镜像 FROM openjdk:8-jdk-alpine WORKDIR application # 前一阶段从jar中提取除了多个文件,这里分别执行COPY命令复制到镜像空间中,每次COPY都是一个layer COPY --from=builder application/dependencies/ ./ COPY --from=builder application/spring-boot-loader/ ./ COPY --from=builder application/snapshot-dependencies/ ./ COPY --from=builder application/application/ ./ ENTRYPOINT ["java", "org.springframework.boot.loader.JarLauncher"] 先在父工程 spring-cloud-tutorials 的pom.xml所在目录执行以下命令完成编译构建:mvn clean package -U -DskipTests再在Dockerfile所在目录执行以下命令制作docker镜像: docker build -t bolingcavalry/jaeger-service-provider:0.0.1 .至此, jaeger-service-provider 相关开发已经完成创建web工程之二:jaeger-service-consumerjaeger-service-consumer工程的创建过程和jaeger-service-provider如出一辙,甚至还要更简单一些(不操作redis),所以描述其开发过程的内容尽量简化,以节省篇幅pom.xml相比jaeger-service-provider的,少了redis依赖,其他可以照抄application.yml也少了redis:spring:   application:     name: jaeger-service-consumer opentracing:   jaeger:     enabled: true     udp-sender:       host: jaeger       port: 6831配置类JaegerConfig.java可以照抄jaeger-service-provider的 由于要远程调用jaeger-service-provider的web接口,因此新增restTemplate的配置类: package com.bolingcavalry.jaeger.consumer.config;  import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.web.client.RestTemplate;  @Configuration public class RestTemplateConfig {     @Bean     public RestTemplate restTemplate(ClientHttpRequestFactory factory) {         RestTemplate restTemplate = new RestTemplate(factory);         return restTemplate;     }      @Bean     public ClientHttpRequestFactory simpleClientHttpRequestFactory() {         SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();         factory.setReadTimeout(5000);         factory.setConnectTimeout(15000);         return factory;     } }关键代码是web接口的实现,会通过restTemplate调用jaeger-service-provider的接口: package com.bolingcavalry.jaeger.consumer.controller;  import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate;  @RestController @Slf4j public class HelloConsumerController {      @Autowired     RestTemplate restTemplate;      /**      * 返回字符串类型      * @return      */     @GetMapping("/hello")     public String hello() {         String url = "http://jaeger-service-provider:8080/hello";         ResponseEntity responseEntity = restTemplate.getForEntity(url, String.class);         StringBuffer sb = new StringBuffer();         HttpStatus statusCode = responseEntity.getStatusCode();         String body = responseEntity.getBody();          // 返回         return "response from jaeger-service-provider  status : " + statusCode + " body : " + body;     } }接下来是编译构建制作docker镜像,和前面的jaeger-service-provider一样;docker-compose.yml文件编写现在咱们要将所有服务都运行起来了,先盘点一共有哪些服务要在docker-compose中启动的,如下所示,共计四个:jaegerredisjaeger-service-providerjaeger-service-consumer完整的docker-compose.yml内容如下:version: "3.0"  networks:   jaeger-tutorials-net:     driver: bridge     ipam:       config:         - subnet: 192.168.1.0/24           gateway: 192.168.1.1  services:   jaeger:     image: jaegertracing/all-in-one:1.26     container_name: jaeger     # 处理时钟漂移带来的计算出负数的问题     command: ["--query.max-clock-skew-adjustment=100ms"]     #选择网络     networks:       - jaeger-tutorials-net     #选择端口     ports:       - 16686:16686/tcp     restart: always   redis:     image: redis:6.2.5     container_name: redis     #选择网络     networks:       - jaeger-tutorials-net     restart: always   jaeger-service-provider:     image: bolingcavalry/jaeger-service-provider:0.0.1     container_name: jaeger-service-provider     #选择网络     networks:       - jaeger-tutorials-net     restart: always   jaeger-service-consumer:     image: bolingcavalry/jaeger-service-consumer:0.0.1     container_name: jaeger-consumer-provider     #选择端口     ports:       - 18080:8080/tcp     #选择网络     networks:       - jaeger-tutorials-net     restart: always至此,开发工作已全部完成,开始验证 验证在docker-compose.yml所在目录执行命令 docker-compose up -d ,即可启动所有容器:will$ docker-compose up -d Creating network "jaeger-service-provider_jaeger-tutorials-net" with driver "bridge" Creating jaeger-service-provider  ... done Creating jaeger                   ... done Creating redis                    ... done Creating jaeger-consumer-provider ... done浏览器打开 http://localhost:16686/search ,熟悉的jaeger页面:
  调用 jaeger-service-consumer 的web服务,浏览器访问 http://localhost:18080/hello :
  再去jaeger上可以看到上述访问的追踪详情:
  点击上图红框3,可以展开此trace的所有span详情,如下图,红框中是咱们程序中自定义的span,绿框中的全是SDK自带的span,而蓝框中是redis的span的tag,该tag的值就是本次写redis操作的key,借助tag可以在定位问题的时候提供关键线索:
  点开上图红框中的自定义span,如下图所示,tag和log都和代码对应上了:
  至此,Spring Cloud应用接入和使用Jaeger的基本操作就全部完成了,希望如果您正在接入Jaeger,希望本文能给您一些参考,接下来的文章,咱们会继续深入学习Jaeger,了解它的更多特性; 欢迎关注头条号:程序员欣宸学习路上,你不孤单,欣宸原创一路相伴...

十日谈春日随想春暖花开的季节,一听到外面人声鸟鸣,心就跟着飞了出去,要一起走进这春天里,亲自去感受惠风和畅天朗气清。一年四季都有好日子,唯独春天最为特别。灰暗了整个冬天后,目光所及的生命又忽然苍2023智能手表盘点(1)知名或小众,哪些更值得入手?智能手表这个概念,在这几年大火了起来,尤其是疫情之下,人们对自己或者家人的健康更为重视,从2021年的数据来看,国内智能手表的出货量为1。15亿,这是个多么庞大的数字!未来,智能手遮星板像花瓣,主镜像蜂巢,天文望远镜为何有如此匠心独具的设计?科技日报记者魏依晨据媒体此前报道,中国计划于2023年底发射一颗新的X射线天文卫星爱因斯坦探针,有望捕捉超新星爆发时发出的第一缕光,帮助搜寻和精确定位引力波源,发现宇宙中更遥远更暗华为预览手表佩戴效果专利公布天眼查App显示,3月17日,华为技术有限公司申请的一种预览方法电子设备及系统专利公布。摘要显示,第一设备可以开启拍摄预览功能,采集并识别第二设备的轮廓(或屏幕的轮廓)或佩戴第二设只用黑白两色,就能穿出耐看穿搭,越简单越高级是时尚至理名言头条创作挑战赛周末值得放松心情,所以穿衣也不必太费劲,简单地黑与白两个色系,就能穿出很高级的风格,这些穿搭可以成为爱美又想穿出好品味女生的必选。同样的小香风西装外套搭T恤,上衣可以心态是最好的风水云衡微语修得平常心,做个自在人。不以物喜,不以己悲。心态是最好的风水,生活简单让人轻松快乐,想法简单让人平和宁静。(摘自老甄絮语)能够在没有鸟语花香里,能够在风吹雨打里,依然保持坚浅论古巴比伦国王的宗教职能文豆子编辑木易历史简介古巴比伦是古代世界著名的文明中心之一,其国王在当时不仅仅是政治领袖,更是宗教领袖。古巴比伦国王在宗教方面扮演着非常重要的角色,掌握着巨大的神权力量。在古巴比伦哈利波特男星在国王十字车站晕倒后猝逝,享年56岁3月21日,据外媒报道,电影哈利波特扮演古灵阁妖精的男星保罗格兰特(PaulGrant)意外去世,享年56岁。图据保罗格兰特IG根据外媒报道,保罗格兰特于上周四在伦敦国王十字车站昏慢性子宫内膜炎这么治妊娠率大大提高,九成姐妹可能想不到!头条创作挑战赛慢性子宫内膜炎就像一个神出鬼没的小妖精,平时对你生活可能根本没有任何影响,但是一涉及到生育,它就可能让你不孕胎停不着床。其实它的治疗方法也不难,就是抗生素,这个没什么国王V爵士的球赛这场比赛是国王vs爵士,这也是一场东西部之间的较量,看完这场比赛我已经迫不及待的想去现场看球了。我和朋友商量了一下就决定去了现场,因为我们都很期待这场比赛。到了现场之后,我们就直奔几大原因分析,国王大概率一轮游!上限虽然不高,但季后赛走不远几大原因分析,国王大概率一轮游!上限虽然不高,但季后赛走不远科尔和布朗作为波波维奇的弟子,无论是王朝勇士还是今年的国王,和14年马刺进攻走的其实还是一个核心,强调无球跑动掩护无球高
20,C罗大发雷霆点射破球荒,倒数第二掀翻领头羊,曼联首胜赛前在E组排名倒数第二的曼联队迎来了欧联杯小组赛第二轮的较量,他们此役做客PK赛前在该组排名榜首的摩尔多联赛冠军谢里夫队。曼联首轮在自己的主场射门数控球率等各项数据都占优的情况下爆奥巴梅扬带伤作战并不容易,希望我能尽快恢复到100直播吧9月15日讯在今日凌晨进行的一场欧冠小组赛中,切尔西11战平萨尔茨堡红牛。赛后在接受采访时,蓝军前锋奥巴梅扬谈到了自己和球队目前的状态。现在感觉如何?奥巴梅扬我感觉还好,我对乾隆皇帝与文人的交往(一)乾隆帝和民间文人的交往(一)乾隆帝是一位什么样的君主我们姑且不去探讨,但他的文学造诣的确很高,当皇子时,曾刊诗集乐善堂集。该诗集录诗1034首。即位后又写了42550首,共计写诗4怒火迷失地图开放顺序大家好,我是传奇游戏怒火迷失游戏的小编小鹿。今天由我给大家讲解一下怒火迷失地图开放顺序,怒火迷失是一款三端互通折扣手游,我们的新游也是刚开服的福利也是多多的,上线送满赞哦1520天两大萍乡中单太猛了!网友质疑小虎到底怎么从别人手里偷来的?当前的季后赛,已经来到了最后的阶段了,仅剩下三场比赛,就将决出最终的LPL夏季赛冠军,在9。1号的时候,LPL就要开启最终的决赛。目前TES战队已经成功拿下了一张全球总决赛的名额,散文今天就是生命里最美的一天作者晴空飘雨今天就是生命里最美的一天!每一个今天都是新生的,充满着蓬勃向上的希望。每一个今天都是美好的,金色的阳光把大地亲吻题记让我们热爱今天吧每一个今天都是含金的,每一个人都在今女人频繁说这些话,其实是在暗示你她喜欢上别人了图源自网络侵权请联系删除社会学家李银河说爱情是流动着的,如今他爱你,以后也有可能爱别人。每每看到这句话,很多人就会觉得很没有安全感,不确定此时此刻陪在身边的爱人,是不是那个能陪自己常吃鸡蛋易导致高胆固醇血症?提醒关于鸡蛋的这些谣言你可别信鸡蛋是我们日常生活中最受欢迎的食材之一,很多人认为鸡蛋受欢迎是其廉价的原因。但事实却并非如此,在临床看来鸡蛋本质就是一种高营养类的食物,它含有人体必需的8种氨基酸各种矿物质蛋白质维医生公认最健康的作息时间表,多少人没有做到?时间都是固定的,只要掌握好规律顺序,人的身体就能朝好,方向发展,否则就会影响身体健康。但现如今很多人的生活作息是非常紊乱的,没有规律可言,毕竟在现在社会下,人们的生活压力生活节奏都防癌又治心脏病,这个东西要多吃亚太日报欣卓西红柿是一种原产于南美洲的茄科植物。虽然在植物学上番茄是一种水果,但它通常被人们当作蔬菜食用。西红柿成熟时通常是红色的,但其实还包括橙色绿色和紫色,也存在许多不同形状和太阳为202223赛季带回经典的太阳爆发制服菲尼克斯太阳队正在更新他们的耐克复古经典版队服。为了庆祝该队服亮相30周年,太阳队推出了经典的阳光爆发队服。太阳队表示,他们将在202223赛季穿着制服,并将举办沉浸式90年代之夜