零侵入式分布式链路日志minbox-logging使用文档v1.0

MinBox Logging

MinBox Logging 是一款分布式、零侵入式的链路日志分析框架,支持 SpringCloud 微服务架构下配置使用,内部封装了 RestTemplate 、 OpenFeign 两种方式透传链路信息。

零侵入式

MinBox Logging 无需使用注解配置采集链路日志,只需要添加 依赖 后简单配置 Minbox Loggin Admin 的相关 地址 或 服务名称 即可,每次在收到请求时就会把请求对应的链路日志详细信息自动上报到 MinBox Logging Admin 进行后续分析、告警通知等。

源码地址

https://gitee.com/minbox-projects/minbox-logging

I. 概念

1. 链路架构图

零侵入式分布式链路日志minbox-logging使用文档v1.0

 

在一次请求中,经过的每一个 服务(MicroService) 的 链路编号(TraceId) 保持一致,通过 SpanID 、 ParentSpanID 进行链路上下级关系衔接。

2. 提交使用中遇到的问题

遇到你在集成使用过程中遇到了问题,请提交 issues ,提交地址: 创建Issues

3. ApiBoot集成实践示例

ApiBoot 作为 MinBox 开源组织的组件最佳集成方案,在第一时间会进行整合 minbox-projects 开源组织内新发布的组件, MinBox Logging 整合实践请访问 ApiBoot 源码 ,整合源码详见 org.minbox.framework.api.boot.autoconfigure.logging 。

II. 配置客户端

4. 启用客户端

在 minbox-logging-spring-context 依赖内提供了 @EnableLoggingClient 注解来启用客户端,配置使用该注解后通过 @Import 自动注册 Logging Client 运行时所需要的 Bean 。

@EnableLoggingClient使用示例如下所示:

@SpringBootApplication
@EnableLoggingClientpublic class ApiBootLoggingApplication { /** * logger instance */ static Logger logger = LoggerFactory.getLogger(ApiBootLoggingApplication.class); public static void main(String[] args) { SpringApplication.run(ApiBootLoggingApplication.class, args); logger.info("{}服务启动成功.", "ApiBoot Logging Client"); }}

5. 透传链路信息

每发送一个请求时就会产生一条链路信息,而链路单元(Span)之前的相互访问目前则以 http 、 rpc 等方式作为主要占比。

链路信息(Trace)的传递, Logging Client 内部提供了提取请求 header 内的链路信息编号(TraceID)、上级单元编号(Parent SpanID),整条链路都通过这种方式来进行上下级单元关系、链路关系绑定。

5.1. RestTemplate透传链路信息

RestTemplate 是 Spring Web 组件提供的请求封装对象,可用于发送指定方式的请求到目标地址,可携带 header 信息进行传递身份认证信息、请求、响应等信息。

Logging Client 则是利用 RestTemplate 的拦截器将链路(Trace)信息写入请求的 header进行传递到下一个单元(Span)。

Logging Client 已经提供了 RestTemplate 拦截器实现类 LoggingRestTemplateInterceptor,在 LoggingFactoryBean#afterPropertiesSet 方法内进行实例化并且已经设置了拦截器,在 Logging Client 上报请求日志信息时,都是通过 LoggingFactoryBean#restTemplate 来执行发送请求到 Admin ,因此只需要实例化 LoggingFactoryBean 即可。

5.2. OpenFeign透传链路信息

OpenFeign 是 SpringCloud 为服务之间方法相互调用的实现方式,根据接口配置信息来发送请求并获取响应内容。

Logging Client 同样是利用 OpenFeign 提供的拦截器将链路(Trace)信息写入服务相互调用的请求 header ,进行传递到下一个服务。

Logging Client 内部提供了 RequestInterceptor 接口实现类 LoggingOpenFeignInterceptor来完成链路信息透传, OpenFeign 会自动检索 Spring IOC 容器内 RequestInterceptor 接口的实现类实例,每次通过 OpenFeign 发起请求时会调用 RequestInterceptor 实现类的 apply 方法来完成拦截业务处理。

6. 发现Admin并上报日志

Logging Client 默认本地不进行持久化存储 请求日志 信息,而是将本地生成的 请求日志 详细信息上报到 Logging Admin ,由 Admin 进行存储、分析等。

Logging Client 内部提供 LoggingAdminDiscovery#lookup 接口方法来进行 发现Admin地址 。

6.1. 指定地址发现Admin

Logging Client 获取指定 Admin 地址是通过 LoggingAdminDiscovery 其中一个实现类 LoggingAppointAdminDiscovery 来进行获取。

下面是 ApiBoot 配置使用 LoggingAppointAdminDiscovery 实践示例,

详见源码, ApiBootLoggingAdminAppointAutoConfiguration 

/**
* ApiBoot Logging Admin Config Discovery* Multiple Use "," Separation** @return LoggingAdminDiscovery*/@Bean@ConditionalOnMissingBeanpublic LoggingAppointAdminDiscovery loggingConfigAdminDiscovery() { String[] adminAddressArray = apiBootLoggingProperties.getAdmin().getServerAddress().split(","); LoggingAppointAdminDiscovery appointAdminDiscovery = new LoggingAppointAdminDiscovery(adminAddressArray); return appointAdminDiscovery;}

LoggingAppointAdminDiscovery 构造函数需提供 Logging Admin 地址数组,格式为: ip(IP地址):port(端口号) ,并不需要添加任何 http 、 https 前缀。

6.1.1. 多Admin地址负载均衡配置

如果我们在创建 LoggingAppointAdminDiscovery 对象时传递了多个 Logging Admin 地址,比如:

@Bean
@ConditionalOnMissingBeanpublic LoggingAppointAdminDiscovery loggingConfigAdminDiscovery() { // 初始化Logging Admin地址列表 String[] adminAddressArray = {"127.0.0.1:8080,127.0.0.1:9090"}; LoggingAppointAdminDiscovery appointAdminDiscovery = new LoggingAppointAdminDiscovery(adminAddressArray); return appointAdmi
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
其中arrb[i]表示第i个盒子中是否已经放入小球(1表示已经放入,0表示未放入)。现在需要找到一个未被检查过的盒子,将小球放入其中,使得放入小球后,所有盒子中放入小球的数量都不相同。若存在多个未被检查过的盒子都可以满足要求,则选择编号最小的盒子放入小球。 解决思路: 1.遍历数组arrb,将所有已经放入小球的盒子对应的位置在数组arra中标记为1; 2.遍历数组arra,找到第一个未被检查过的盒子,标记为当前最小盒子; 3.从最小盒子开始,向后遍历数组arra,找到第一个未被检查过的盒子,将其标记为当前比当前最小盒子放入小球后,放入小球的数量最少的盒子; 4.继续遍历数组arra,找到所有未被检查过的盒子中,放入小球后,放入小球的数量最少的盒子; 5.将小球放入最终找到的盒子中,更新数组arrb中对应位置的值为1,表示该盒子已经放入小球; 6.返回最终找到的盒子编号。 代码实现: int findBox(int n, int a, int* arra, int* arrb) { int minBox = -1; //当前最小盒子 int minNum = INT_MAX; //放入小球后,放入小球的数量最少的盒子的小球数量 int numCount[n + 1]; //用于记录每个盒子中放入小球的数量 memset(numCount, 0, sizeof(numCount)); //初始化为0 for(int i = 1; i <= n; i++) { if(arrb[i] == 1) { arra[i - 1] = 1; //标记为已经检查过 numCount[i]++; //更新放入小球的数量 } } for(int i = 0; i < n; i++) { if(arra[i] == 0) { //找到第一个未被检查过的盒子 minBox = i + 1; break; } } for(int i = minBox + 1; i <= n; i++) { //从最小盒子开始遍历 if(arra[i - 1] == 0) { //找到未被检查过的盒子 int ballNum = numCount[i]; //放入小球后,放入小球的数量 if(ballNum < minNum) { //更新放入小球后,放入小球的数量最少的盒子 minBox = i; minNum = ballNum; } } } for(int i = minBox + 1; i <= n; i++) { //继续遍历数组arra,找到所有未被检查过的盒子中,放入小球后,放入小球的数量最少的盒子 if(arra[i - 1] == 0) { int ballNum = numCount[i]; if(ballNum == minNum) { minBox = i; } } } arrb[minBox] = 1; //将小球放入最终找到的盒子中 return minBox; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值