在进行微服务调用的时候,为了系统的高可用性,不仅需要进行灰度发布验证服务的可用性。同时对于服务健康的监控也是很重要的一环。Nepxion Discovery 在这方面也有监控方面的集成,包含以下几个方面:

  • 蓝绿灰度埋点调用链监控
  • 全链路日志监控
  • 全链路指标监控

1、蓝绿灰度埋点调用链监控

1.1 蓝绿灰度埋点调用链监控

关于 蓝绿灰度埋点调用链监控 官网描述得很清楚,它内置蓝绿灰度埋点,包括如下:

1. n-d-service-group - 服务所属组或者应用
2. n-d-service-type - 服务类型,分为网关端 | 服务端 | 控制台端 | 测试端,使用者只需要关注前两个即可
3. n-d-service-id - 服务ID
4. n-d-service-address - 服务地址,包括Host和Port
5. n-d-service-version - 服务版本
6. n-d-service-region - 服务所属区域
7. n-d-service-env - 服务所属环境
8. n-d-version - 版本路由值
9. n-d-region - 区域路由值
10. n-d-env - 环境路由值
11. n-d-address - 地址路由值
12. n-d-version-weight - 版本权重路由值
13. n-d-region-weight - 区域权重路由值
14. n-d-id-blacklist - 全局唯一ID屏蔽值
15. n-d-address-blacklist - IP地址和端口屏蔽值
  • n-d-service 开头的埋点代表是服务自身的属性
  • n-d- 开头的埋点是蓝绿灰度传递的策略路由值

因为 Nepxion Discovery 集成了 opentracing 所以它还可以自定义外置埋点。它可以集成:

  • 集成OpenTracing + Jaeger蓝绿灰度全链路监控
  • 集成OpenTracing + SkyWalking蓝绿灰度全链路监控

它定义了 StrategyMonitor 接口用于集成 opentracing 监控,使用 StrategyTracer 接口用于 io.opentelemetry.api.trace.Span相关的操作。下面是StrategyTracer 接口的定义:

StrategyTracer.java

public interface StrategyTracer {void spanBuild();void spanOutput(Map<String, String> contextMap);void spanError(Throwable e);void spanFinish();String getTraceId();String getSpanId();
}

日志监控对于 Spring Cloud Gateway、Zuul 以及 微服务都是支持的,它们都会有具体的实现类去继承 StrategyMonitor

Spring Cloud Gateway

public class DefaultGatewayStrategyMonitor extends StrategyMonitor implements GatewayStrategyMonitor {@Overridepublic void monitor(ServerWebExchange exchange) {spanBuild();loggerOutput();loggerDebug();spanOutput(null);}@Overridepublic void release(ServerWebExchange exchange) {loggerClear();spanFinish();}
}

Zuul

public class DefaultZuulStrategyMonitor extends StrategyMonitor implements ZuulStrategyMonitor {@Overridepublic void monitor(RequestContext context) {spanBuild();loggerOutput();loggerDebug();spanOutput(null);}@Overridepublic void release(RequestContext context) {loggerClear();spanFinish();}
}

微服务 Service

public class DefaultServiceStrategyMonitor extends StrategyMonitor implements ServiceStrategyMonitor {@Value("${" + StrategyConstant.SPRING_APPLICATION_STRATEGY_TRACER_ENABLED + ":false}")protected Boolean tracerEnabled;@Value("${" + StrategyConstant.SPRING_APPLICATION_STRATEGY_TRACER_METHOD_CONTEXT_OUTPUT_ENABLED + ":false}")protected Boolean tracerMethodContextOutputEnabled;@Autowired(required = false)private List<ServiceStrategyMonitorAdapter> serviceStrategyMonitorAdapterList;@Overridepublic void monitor(ServiceStrategyMonitorInterceptor interceptor, MethodInvocation invocation) {spanBuild();loggerOutput();loggerDebug();}@Overridepublic void monitor(ServiceStrategyMonitorInterceptor interceptor, MethodInvocation invocation, Object returnValue) {spanOutput(createContextMap(interceptor, invocation, returnValue));}@Overridepublic void error(ServiceStrategyMonitorInterceptor interceptor, MethodInvocation invocation, Throwable e) {spanError(e);}@Overridepublic void release(ServiceStrategyMonitorInterceptor interceptor, MethodInvocation invocation) {loggerClear();spanFinish();}private Map<String, String> createContextMap(ServiceStrategyMonitorInterceptor interceptor, MethodInvocation invocation, Object returnValue) {if (!tracerEnabled) {return null;}Map<String, String> contextMap = new HashMap<String, String>();String className = interceptor.getMethod(invocation).getDeclaringClass().getName();String methodName = interceptor.getMethodName(invocation);contextMap.put("* " + DiscoveryConstant.CLASS, className);contextMap.put("* " + DiscoveryConstant.METHOD, methodName);if (tracerMethodContextOutputEnabled) {String[] methodParameterNames = interceptor.getMethodParameterNames(invocation);Object[] arguments = interceptor.getArguments(invocation);Map<String, Object> parameterMap = ClassUtil.getParameterMap(methodParameterNames, arguments);if (CollectionUtils.isNotEmpty(serviceStrategyMonitorAdapterList)) {for (ServiceStrategyMonitorAdapter serviceStrategyMonitorAdapter : serviceStrategyMonitorAdapterList) {Map<String, String> customizationMap = serviceStrategyMonitorAdapter.getCustomizationMap(interceptor, invocation, parameterMap, returnValue);for (Map.Entry<String, String> entry : customizationMap.entrySet()) {contextMap.put("* " + entry.getKey(), entry.getValue());}}}}return contextMap;}
}

1.2 蓝绿灰度埋点Debug辅助监控

Debug辅助监控只是通过普通的System.out.println方式输出,便于开发人员在IDE上调试,在生产环境下不建议开启

对于Debug辅助监控功能的开启和关闭,需要通过如下开关做控制

# 启动和关闭Header传递的Debug日志打印,注意:每调用一次都会打印一次,会对性能有所影响,建议压测环境和生产环境关闭。缺失则默认为false
spring.application.strategy.rest.intercept.debug.enabled=true
# 启动和关闭Debug日志打印,注意:每调用一次都会打印一次,会对性能有所影响,建议压测环境和生产环境关闭。缺失则默认为false
spring.application.strategy.logger.debug.enabled=true

① 网关端和服务端自身蓝绿灰度埋点Debug辅助监控

其实就是网关或者服务端调用 StrategyMonitor#loggerDebug 会进行下面日志的打印

------------------ Logger Debug ------------------
trace-id=dade3982ae65e9e1
span-id=997e31021e9fce20
n-d-service-group=discovery-guide-group
n-d-service-type=service
n-d-service-id=discovery-guide-service-a
n-d-service-address=172.27.208.1:3001
n-d-service-version=1.0
n-d-service-region=dev
n-d-service-env=env1
n-d-service-zone=zone1
n-d-version={"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.0"}
mobile=13812345678
user=
--------------------------------------------------

② 服务端Feign或者RestTemplate拦截输入的蓝绿灰度埋点Debug辅助监控

------- Feign Intercept Input Header Information -------
n-d-service-group=discovery-guide-group
n-d-version={"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.0"}
n-d-service-type=gateway
n-d-service-id=discovery-guide-zuul
n-d-service-env=default
mobile=13812345678
n-d-service-region=default
n-d-service-zone=default
n-d-service-address=172.27.208.1:5002
n-d-service-version=1.0
--------------------------------------------------

上面的实现方式是 FeignStrategyInterceptor 或者 RestTemplateStrategyInterceptor 的调用它们的父类方法FeignStrategyInterceptor#interceptInputHeader实现的

③ 服务端Feign或者RestTemplate拦截输出的蓝绿灰度埋点Debug辅助监控

------- Feign Intercept Output Header Information ------
mobile=[13812345678]
n-d-service-address=[172.27.208.1:3001]
n-d-service-env=[env1]
n-d-service-group=[discovery-guide-group]
n-d-service-id=[discovery-guide-service-a]
n-d-service-region=[dev]
n-d-service-type=[service]
n-d-service-version=[1.0]
n-d-service-zone=[zone1]
n-d-version=[{"discovery-guide-service-a":"1.0", "discovery-guide-service-b":"1.0"}]
--------------------------------------------------

上面的实现方式调用的是 FeignStrategyInterceptor#interceptOutputHeader 或者 RestTemplateStrategyInterceptor#interceptOutputHeader 实现的。

1.3 自定义埋点调用链监控

① 自定义调用链上下文参数的创建,继承 DefaultStrategyTracerAdapter

// 自定义调用链上下文参数的创建
// 对于getTraceId和getSpanId方法,在OpenTracing等调用链中间件引入的情况下,由调用链中间件决定,在这里定义不会起作用;在OpenTracing等调用链中间件未引入的情况下,在这里定义才有效,下面代码中表示从Http Header中获取,并全链路传递
// 对于getCustomizationMap方法,表示输出到调用链中的定制化业务参数,可以同时输出到日志和OpenTracing等调用链中间件,下面代码中表示从Http Header中获取,并全链路传递
public class MyStrategyTracerAdapter extends DefaultStrategyTracerAdapter {@Overridepublic String getTraceId() {return StringUtils.isNotEmpty(strategyContextHolder.getHeader(DiscoveryConstant.TRACE_ID)) ? strategyContextHolder.getHeader(DiscoveryConstant.TRACE_ID) : StringUtils.EMPTY;}@Overridepublic String getSpanId() {return StringUtils.isNotEmpty(strategyContextHolder.getHeader(DiscoveryConstant.SPAN_ID)) ? strategyContextHolder.getHeader(DiscoveryConstant.SPAN_ID) : StringUtils.EMPTY;}@Overridepublic Map<String, String> getCustomizationMap() {Map<String, String> customizationMap = new HashMap<String, String>();customizationMap.put("mobile", StringUtils.isNotEmpty(strategyContextHolder.getHeader("mobile")) ? strategyContextHolder.getHeader("mobile") : StringUtils.EMPTY);customizationMap.put("user", StringUtils.isNotEmpty(strategyContextHolder.getHeader("user")) ? strategyContextHolder.getHeader("user") : StringUtils.EMPTY);return customizationMap;}
}

在配置类里@Bean方式进行调用链类创建,覆盖框架内置的调用链适配器

@Bean
public StrategyTracerAdapter strategyTracerAdapter() {return new MyStrategyTracerAdapter();
}

② 自定义类方法上入参和出参输出到调用链,继承ServiceStrategyMonitorAdapter

// 自定义类方法上入参和出参输出到调用链
// parameterMap格式:
// key为入参名
// value为入参值
public class MyServiceStrategyMonitorAdapter implements ServiceStrategyMonitorAdapter {@Overridepublic Map<String, String> getCustomizationMap(ServiceStrategyMonitorInterceptor interceptor, MethodInvocation invocation, Map<String, Object> parameterMap, Object returnValue) {Map<String, String> customizationMap = new HashMap<String, String>();customizationMap.put(DiscoveryConstant.PARAMETER, parameterMap.toString());customizationMap.put(DiscoveryConstant.RETURN, returnValue != null ? returnValue.toString() : null);return customizationMap;}
}

在配置类里@Bean方式进行创建

@Bean
public ServiceStrategyMonitorAdapter serviceStrategyMonitorAdapter() {return new MyServiceStrategyMonitorAdapter();
}

③ 业务方法上获取TraceId和SpanId

public class MyClass {@Autowiredprivate StrategyMonitorContext strategyMonitorContext;public void doXXX() {String traceId = strategyMonitorContext.getTraceId();String spanId = strategyMonitorContext.getSpanId();...}
}

2、全链路日志监控

蓝绿灰度埋点日志输出,需要使用者配置logback.xml或者log4j.xml日志格式,参考如下

<!-- Logback configuration. See http://logback.qos.ch/manual/index.html -->
<configuration scan="true" scanPeriod="10 seconds"><!-- Simple file output --><appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- encoder defaults to ch.qos.logback.classic.encoder.PatternLayoutEncoder --><encoder><pattern>discovery %date %level [%thread] [%X{trace-id}] [%X{span-id}] [%X{n-d-service-group}] [%X{n-d-service-type}] [%X{n-d-service-app-id}] [%X{n-d-service-id}] [%X{n-d-service-address}] [%X{n-d-service-version}] [%X{n-d-service-region}] [%X{n-d-service-env}] [%X{n-d-service-zone}] [%X{mobile}] [%X{user}] %logger{10} [%file:%line] - %msg%n</pattern><charset>UTF-8</charset></encoder><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>log/discovery-%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>50MB</maxFileSize></rollingPolicy><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter><!-- Safely log to the same file from multiple JVMs. Degrades performance! --><prudent>true</prudent></appender><appender name="FILE_ASYNC" class="ch.qos.logback.classic.AsyncAppender"><discardingThreshold>0</discardingThreshold><queueSize>512</queueSize><appender-ref ref="FILE" /></appender><!-- Console output --><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><!-- encoder defaults to ch.qos.logback.classic.encoder.PatternLayoutEncoder --><encoder><pattern>discovery %date %level [%thread] [%X{trace-id}] [%X{span-id}] [%X{n-d-service-group}] [%X{n-d-service-type}] [%X{n-d-service-app-id}] [%X{n-d-service-id}] [%X{n-d-service-address}] [%X{n-d-service-version}] [%X{n-d-service-region}] [%X{n-d-service-env}] [%X{n-d-service-zone}] [%X{mobile}] [%X{user}] %logger{10} [%file:%line] - %msg%n</pattern><charset>UTF-8</charset></encoder><!-- Only log level WARN and above --><filter class="ch.qos.logback.classic.filter.ThresholdFilter"><level>INFO</level></filter></appender><!-- For loggers in the these namespaces, log at all levels. --><logger name="pedestal" level="ALL" /><logger name="hammock-cafe" level="ALL" /><logger name="user" level="ALL" /><root level="INFO"><!-- <appender-ref ref="FILE_ASYNC" /> --><appender-ref ref="STDOUT" /></root>
</configuration>

日志格式打印如下:

在这里插入代码片

3、全链路指标监控

3.1 Prometheus监控

3.2 Grafana监控

3.3 Spring-Boot-Admin监控

参考地址:

  • Nepxion Discovery 全链路监控

13、Nepxion Discovery 之 全链路调用链监控相关推荐

  1. 11、Nepxion Discovery 之全链路界面操作蓝绿灰度发布

    在之前的文章中讲过,用户可以通过 URL 请求以及配置中心进行灰度发布的操作,而且支持配置中心的灰度发布参数的动态变更.如果用户不希望使用上面的两种方式,Nepxion Discovery 框架还支持 ...

  2. 云原生分布式应用性能监控实践-天眼全流程调用链

    一.概述 天眼是中国联通IT生产运营支撑平台,对生产运营领域提供端到端.云化架构全层级的运维工具支撑,融合人工智能与大数据技术,实现传统运维向自动化生产.智慧化运营的转变,保障4亿级用户规模系统稳定运 ...

  3. 如何让控件span的id调用ajax_微服务架构之「 调用链监控 」

    「 调用链监控 」是在微服务兴起后才有的一种新流行的监控模式.因为在我们传统单体应用的项目中,不存在服务链/调用链的概念,所以也就根本没有调用链监控的需求了. 当我们开始微服务架构之后,我们的很多服务 ...

  4. 调用链监控 - Tracing - APM

    调用链监控 - Tracing - APM 调用链监控原理和相关概念 调用在分布式系统中的流程简述实例 相关概念 CAT vs Zipkin vs Skywalking 埋点方式简述 APM功能简述 ...

  5. 微服务架构之「 调用链监控 」

    「 调用链监控 」是在微服务兴起后才有的一种新流行的监控模式.因为在我们传统单体应用的项目中,不存在服务链/调用链的概念,所以也就根本没有调用链监控的需求了. 当我们开始微服务架构之后,我们的很多服务 ...

  6. 微服务调用链监控开源工具CAT

    1 监控在微服务架构的地位 2 为何需要调用链监控? 在初期的单体应用,应用都打在一个包中,无分布式概念,监控也只需对一些埋点监控. 但是微服务时代下,很多服务在各自的包,一旦出现问题,没有调用链监控 ...

  7. dubbo+zipkin调用链监控

    dubbo+zipkin调用链监控 原文地址:http://www.cnblogs.com/ASPNET2008/p/6709900.html 分布式环境下,对于线上出现问题往往比单体应用要复杂的多, ...

  8. 基于Spring Aop及log4j2的MDC实现全链路调用跟踪(traceid)

    环境: Springboot:2.2.3.RELEASE Spring-boot-starter-log4j2: 2.2.2.RELEASE jdk:1.8 目标: 实现Springboot框架下的全 ...

  9. 调用链监控:Dapper、Istio... etc.

    目录 Dapper,大规模分布式系统的跟踪系统by bigbully 2.5.1 带外数据跟踪收集 6.2 解决延迟的长尾效应 7. 其他收获 RPC服务追踪的原理与实践- SegmentFault ...

最新文章

  1. redis 缓存过期默认时间_缓存的必知必会:一文搞懂Redis持久化和过期机制
  2. 微信“红包封面”终于开放:这样免费定制!
  3. 【转载】基于AFNetWorking3.0的图片缓存分析
  4. 也谈大公司病1——正确是最大的错误
  5. CF1396B Stoned Game(博弈论)
  6. Python2.7-sqlite3
  7. 如何取得事件中鼠标坐标
  8. mysql openrowset_SQL的OPENROWSET开启和使用方法
  9. 骨骼动画编辑器Spine的纹理打包器(texture packer)
  10. 我的压缩软件选择:7zip软件+Zip格式
  11. ngrok 通过外网链接映射到本地机器,支持http,https
  12. 用php远程获取MySQL到本地,mysql本地从远程数据库导数据_MySQL
  13. NVelocity条件选择语法
  14. 解决卡米,安心卸载MIUI预装软件。
  15. 华为安装gsm框架_华为手机怎么安装 GMS 框架和谷歌应用?
  16. DAS,NAS,SAN 三种存储技术比较
  17. B站百万粉丝是如何做起来的?解密UP主成长之路
  18. docker下载gcr.io镜像
  19. 关于Office365邮箱附件大小限制问题
  20. 《Design of Computer Programs》学习笔记(2 - 1)Back of the Envelope - Lesson 2

热门文章

  1. 华为云云耀云服务器 中小企业的福音
  2. 在计算机上创建用户的密码要求,电脑设置密码在哪里设置
  3. Java - 为什麽 Iterator接口 不提供 add(E) 方法 ?
  4. 用Easy UI快速搭建一个后台
  5. 未来十年,都从今天开始 | 全球视角的心理AI产品应用与探索
  6. On ne change pas 做梦的fille
  7. Multi-Task Video Captioning with Video and Entailment Generation阅读笔记
  8. 网站提示DNS_PROBE_FINISHED_NXDOMAIN错误如何修复
  9. 机械键盘的“轴”有什么区别?
  10. DFRobot新推出一款适合短时间环境数据记录的Gravity: 串口数据记录器