在上一篇文章【apiboot logging使用springcloud openfeign透传链路信息】中我们详细的讲解了apiboot logging整合springcloud通过openfeign进行透传链路信息,包括traceid(链路编号)、parentspanid(上级单元编号)等信息。
apiboot logging不仅仅可以使用openfeign传递链路信息,还支持resttemplate方式,本篇文章来详细的讲解下具体的使用方式。
搭建logging admin 我们需要搭建logging admin服务,用于接收业务服务上报的请求日志信息,请参考【将apiboot logging采集的日志上报到admin】文章内容.
添加apiboot统一版本 由于本章采用是maven 多模块的方式构建源码,所以我们只需要将apiboot统一版本的依赖配置在root项目的pom.xml内,如下所示:
1.82.1.5.releaseorg.minbox.frameworkapi-boot-dependencies${api.boot.version}pomimport 接下来我们营造本篇文章的模拟场景,查询用户基本信息时一并查询出用户的账号余额。
创建账户服务 创建一个名为account-service的springboot项目。
添加相关依赖 在项目pom.xml配置文件内添加相关依赖,如下所示:
org.springframework.bootspring-boot-starter-weborg.minbox.frameworkapi-boot-starter-logging 配置上报的logging admin 在application.yml配置文件内添加请求日志上报的logging admin地址,如下所示:
spring: application: name: account-serviceserver: port: 9090api: boot: logging: # 控制台打印请求日志 show-console-log: true # 美化请求日志 format-console-log-json: true # logging admin地址 admin: server-address: 127.0.0.1:8081 注意:server-address配置参数不需要添加http://前缀 启用logging client 添加完成依赖后我们通过@enableloggingclient注解来启用apiboot logging,在accountserviceapplication类上添加如下所示:
/** * 账户服务 * * @author 恒宇少年 */@springbootapplication@enableloggingclientpublic class accountserviceapplication { /** * logger instance */ static logger logger = loggerfactory.getlogger(accountserviceapplication.class); public static void main(string[] args) { springapplication.run(accountserviceapplication.class, args); logger.info({}服务启动成功., 账户); }} @enableloggingclient注解就实例化部分apiboot logging内部所需要的类,将实例放置到spring ioc容器内。 查询账户余额代码实现 我们创建一个名为accountcontroller的控制器来提供查询账户的余额信息,代码实现如下所示:
/** * 账户服务实现 * * @author 恒宇少年 */@restcontroller@requestmapping(value = /account)public class accountcontroller { /** * 示例,内存账户列表 */ static final hashmap accounts = new hashmap() {{ put(1, 1233.22); put(2, 69269.22); }}; /** * 获取指定账户的余额 * * @param accountid * @return */ @getmapping(value = /{accountid}) public double getbalance(@pathvariable(accountid) integer accountid) { return accounts.get(accountid); }},> 至此我们的账户服务已经编写完成,下面我们来编写用户服务。 创建用户服务 我们来创建一个名为user-service的springboot项目。
添加相关依赖 在项目pom.xml配置文件内添加相关依赖,如下所示:
org.springframework.bootspring-boot-starter-weborg.minbox.frameworkapi-boot-starter-logging 配置上报的logging admin 本章我们使用指定logging admin地址的方式配置,修改application.yml配置文件如下所示:
spring: application: name: user-serviceserver: port: 9091api: boot: logging: # 控制台打印请求日志 show-console-log: true # 美化请求日志 format-console-log-json: true # logging admin地址 admin: server-address: 127.0.0.1:8081 启用logging client 添加完依赖后我们需要在xxxapplication入口类上添加@enableloggingclient注解来启用apiboot logging,如下所示:
/** * 用户服务 * * @author 恒宇少年 */@springbootapplication@enableloggingclientpublic class userserviceapplication { /** * logger instance */ static logger logger = loggerfactory.getlogger(userserviceapplication.class); public static void main(string[] args) { springapplication.run(userserviceapplication.class, args); logger.info({}服务启动成功., 用户); }} 实例化resttemplate对象 在user-service需要访问账户服务获取当前用户的余额,所以我们需要在user-service内实例化resttemplate,这样我们才可以通过resttemplate访问获取用户账户余额信息,我们直接在userserviceapplication类内添加实例,如下所示:
/** * 实例化resttemplate * * @return {@link resttemplate} */ @bean @conditionalonmissingbean public resttemplate resttemplate() { return new resttemplate(); } 注解解释:
@conditionalonmissingbean:这是springboot条件注入其中的一个注解,表示当ioc容器内不存在resttemplate类型的实例时才会去执行resttemplate()方法创建对象。 查询用户信息代码实现 /** * 用户基本信息控制器 * * @author 恒宇少年 */@restcontroller@requestmapping(value = /user)public class usercontroller { /** * 示例,用户列表 */ static final hashmap users = new hashmap() {{ put(1, new user(1, 恒宇少年)); put(2, new user(2, 于起宇)); }}; /** * 注入resttemplate */ @autowired private resttemplate resttemplate; /** * 获取用户基本信息 * * @param userid 用户编号 * @return */ @getmapping(value = /{userid}) public user getuserinfo(@pathvariable(userid) integer userid) { responseentity responseentity = resttemplate.getforentity(http://localhost:9090/account/{accountid}, double.class, userid); double balance = responseentity.getbody(); user user = users.get(userid); if (objectutils.isempty(user)) { throw new runtimeexception(用户: + userid + ,不存在.); } user.setbalance(balance); return user; } @data public static class user { private integer id; private string name; private double balance; public user(integer id, string name) { this.id = id; this.name = name; } }},> 我们所需要的两个服务都已经编写完成,下面我们来测试resttemplate是可以透传apiboot logging的链路信息?
运行测试 依次启动logging-admin > user-service > account-service。
测试点:透传链路信息 我们使用curl命令访问user-service提供的地址/user,如下所示:
➜ ~ curl http://localhost:9091/user/1{id:1,name:恒宇少年,balance:1233.22} 下面我看来看下logging-admin控制台接收到的请求日志。
接收user-service请求日志
receiving service: 【user-service -> 127.0.0.1】, request log report,logging content:[ { endtime:1573032865311, httpstatus:200, requestbody:, requestheaders:{ host:localhost:9091, user-agent:curl/7.64.1, accept:*/* }, requestip:0:0:0:0:0:0:0:1, requestmethod:get, requestparam:{}, requesturi:/user/1, responsebody:{/id/:1,/name/:/恒宇少年/,/balance/:1233.22}, responseheaders:{}, serviceid:user-service, serviceip:127.0.0.1, serviceport:9091, spanid:f8cff018-42d5-481f-98df-c19b7196b3c3, starttime:1573032865130, timeconsuming:181, traceid:16ad1dd4-beaa-4110-b4b7-fc7d952d9a57 }] 接收account-service请求日志
receiving service: 【account-service -> 127.0.0.1】, request log report,logging content:[ { endtime:1573032865309, httpstatus:200, parentspanid:f8cff018-42d5-481f-98df-c19b7196b3c3, requestbody:, requestheaders:{ minbox-logging-x-parent-span-id:f8cff018-42d5-481f-98df-c19b7196b3c3, minbox-logging-x-trace-id:16ad1dd4-beaa-4110-b4b7-fc7d952d9a57, host:localhost:9090, connection:keep-alive, accept:application/json, application/*+json, user-agent:java/1.8.0_211 }, requestip:127.0.0.1, requestmethod:get, requestparam:{}, requesturi:/account/1, responsebody:1233.22, responseheaders:{}, serviceid:account-service, serviceip:127.0.0.1, serviceport:9090, spanid:63b18b40-5718-431c-972f-78956ce78380, starttime:1573032865307, timeconsuming:2, traceid:16ad1dd4-beaa-4110-b4b7-fc7d952d9a57 }] 当我们访问user-service服务内的/user路径时,因为是第一次访问apiboot logging会主动创建traceid(链路编号)、spanid(单元编号),因为没有上级单元所以parentspanid为null. 而通过查看account-service服务上报的请求日志时,可以看到apiboot logging相关的链路信息是通过httpheader的方式进行传递的
minbox-logging-x-trace-id -> 链路编号 minbox-logging-x-parent-span-id -> 上级单元编号 敲黑板,划重点 apiboot logging在内部自动化实现了resttemplate的拦截器配置,所以我们只需要创建实例就可以,而不需要主动去配置拦截器信息,具体源码请访问org.minbox.framework.logging.client.http.rest.loggingresttemplateinterceptor查看。
不管你一次请求跨度几个服务,都可以将请求入口生成的链路信息进行依次传递,而上下级关系则是根据parentspanid、spanid进行绑定的。
区块链独立基础生态系统Remiit介绍
基于定时器的PLC交通灯控制系统研究
越南将启动大规模5G服务测试 诺基亚为科尼部署5G SA专网
51单片机p0口上拉电阻的选择,应该遵循哪些设计原则?
移动商务神器 年货节选三星Galaxy Tab S7就对了!
ApiBoot Logging使用Rest Template透传链路信息
耐高压透明液压节流阀的原理及设计
高低温湿热试验箱的简单故障分析
新型EPWM斩波器式交流稳压电源的原理分析
康佳T953S彩电开关电源的改进
单片机闪烁灯汇编语言源代码大全(四款闪烁灯的汇编语言源代码)
Leap Motion的模拟技术能解决VR的硬件问题吗
康宁 Gorilla(R) 玻璃被应用于 LG 电子新款超薄
TRMK213 | 带你感受物联网时代的红利
新能源汽车电池包的构成_新能源汽车电池组装全过程
比特币上涨18个月新高 4万美元在望
人工智能技术在安防行业的实际落地应用 可以从以下几个方面来看
海尔李华刚:创物联网时代全球引领的生态品牌
荣耀9评测:荣耀9与小米6对比评测,作为小米6的劲敌,荣耀9到底哪里比不上对手?
为迎小米6上市米5大降价,拥有十大黑科技的米5是否值得购买?