0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

ApiBoot Logging使用Rest Template透传链路信息

电子设计 来源:电子设计 作者:电子设计 2020-12-10 22:03 次阅读

在上一篇文章【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-serviceSpringBoot项目。

添加相关依赖

在项目pom.xml配置文件内添加相关依赖,如下所示:

org.springframework.bootspring-boot-starter-weborg.minbox.frameworkapi-boot-starter-logging

配置上报的Logging Admin

application.yml配置文件内添加请求日志上报的Logging Admin地址,如下所示:

spring:
  application:
    name: account-service
server:
  port: 9090

api:
  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
@EnableLoggingClient
public 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-serviceSpringBoot项目。

添加相关依赖

在项目pom.xml配置文件内添加相关依赖,如下所示:

org.springframework.bootspring-boot-starter-weborg.minbox.frameworkapi-boot-starter-logging

配置上报的Logging Admin

本章我们使用指定Logging Admin地址的方式配置,修改application.yml配置文件如下所示:

spring:
  application:
    name: user-service
server:
  port: 9091

api:
  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
@EnableLoggingClient
public 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(单元编号),因为没有上级单元所以parentSpanIdnull.
  • 而通过查看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查看。

不管你一次请求跨度几个服务,都可以将请求入口生成的链路信息进行依次传递,而上下级关系则是根据parentSpanIdspanId进行绑定的。

审核编辑 黄昊宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • JAVA
    +关注

    关注

    19

    文章

    2954

    浏览量

    104510
  • MySQL
    +关注

    关注

    1

    文章

    799

    浏览量

    26413
  • 人脸识别
    +关注

    关注

    76

    文章

    4004

    浏览量

    81715
  • Template
    +关注

    关注

    0

    文章

    8

    浏览量

    9459
收藏 人收藏

    评论

    相关推荐

    请问AT支持UDP吗?

    做了测试,SDK V1.00 AT文件烧写后,设定为TCP时,是可以了, 但是设定为UDP后,传出现发送不成功,但是接收是可以的,是不是AT不支持UDP
    发表于 07-17 08:28

    最新推出低功耗蓝牙模块

    注意啦!最新推出蓝牙模块,模块可以省去蓝牙底层的软硬件的时间投入及成本投入,以最短的开发周期整合现有的方案基于NRF51822的
    发表于 11-05 13:47

    物联网中的数据

    摘要:在农业工业等场景应用中,存在很多场景是有线网络无法达到的,借助物联网技术使用无线数据采集与传输能很好的解决这一个问题,在这个数据传输过程中为了保证数据的可靠性和准确性,通常会涉及到“数据
    发表于 08-29 19:27

    物联网中的数据

    摘要:在农业工业等场景应用中,存在很多场景是有线网络无法达到的,借助物联网技术使用无线数据采集与传输能很好的解决这一个问题,在这个数据传输过程中为了保证数据的可靠性和准确性,通常会涉及到“数据
    发表于 09-03 14:17

    什么是

    的概念概念具体到此次实践
    发表于 12-24 07:13

    什么是蓝牙

    一.什么是蓝牙是最简单也是最常见的通讯方式(如下图所示),也叫串口
    发表于 12-06 06:15

    ApiBoot Logging Admin可视化界面管理日志教程

    ApiBoot Logging Admin支持界面可视化查看请求日志信息,初期版本支持查看上报日志的服务列表、最新的日志等功能,还可以整
    的头像 发表于 12-10 22:03 475次阅读

    ApiBoot Logging使用Spring Cloud Openfeign信息

    ApiBoot Logging可以无缝整合SpringCloud来采集请求日志,目前支持RestTemplate、Openfeign两种方式,我们本章来讲解下在使用Openfeign...
    的头像 发表于 12-10 22:05 512次阅读

    ApiBoot Logging整合Spring Cloud Eureka负载均衡上报日志

    ApiBoot Logging支持整合服务注册中心(Eureka、Consul、Nacos Discovery、Zookeeper...)进行上报请求日志,Logging Client会从服务注...
    的头像 发表于 12-10 22:08 397次阅读

    ApiBoot Logging忽略路径不进行采集日志的教程

    ApiBoot Logging支持排除指定路径不参与日志的采集,当我们的服务集成actuator时,会不断的重复调用内置的路径导致大量采集到一些无关业...
    的头像 发表于 12-10 22:18 376次阅读

    修改ApiBoot Logging日志采集前缀的教程

    ApiBoot Logging支持指定单个或者多个路径的前缀进行采集,也就是我们可以指定/user/**或者/order/**下的单个或者同时指定多个路径进行...
    的头像 发表于 12-10 22:20 420次阅读

    minbox-logging日志分析框架

    gitee-minbox-logging.zip
    发表于 04-27 10:07 1次下载
    minbox-<b class='flag-5'>logging</b><b class='flag-5'>链</b><b class='flag-5'>路</b>日志分析框架

    NuMicro M031BT-利用蓝牙实现个人健康信息应用的好帮手

    NuMicro M031BT-利用蓝牙实现个人健康信息应用的好帮手
    的头像 发表于 08-10 11:31 542次阅读
    NuMicro M031BT-利用蓝牙<b class='flag-5'>透</b><b class='flag-5'>传</b>实现个人健康<b class='flag-5'>信息</b>应用的好帮手

    轻松搞懂和非的区别

    和非是数据通信中的两种不同模式,各自有其适用场景和优势。模式简单、高效,适用于数据完
    的头像 发表于 06-05 12:03 8660次阅读
    轻松搞懂<b class='flag-5'>透</b><b class='flag-5'>传</b>和非<b class='flag-5'>透</b><b class='flag-5'>传</b>的区别

    网络和非是什么区别是什么

    :适用简易、立即的数据传输,留意数据的完整性和低延迟。非:适用必须进行数据解决优化的状况,提供良好的可靠性和效果。 在挑选传输技术时,务必根据实际的业务需求、数据种类、安全规
    的头像 发表于 08-07 16:19 635次阅读