从15开始搭建一个微服务框架链路追

白癜风诚信医院 http://m.39.net/disease/a_6169057.html

前言

最近在搭一个基础版的项目框架,基于SpringCloud微服务框架。

如果把SpringCloud这个框架当做1,那么现在已经有的基础组件比如swaggr/logback等等就是0.5,然后我在这1.5基础上进行组装,完成一个微服务项目框架。

为什么要造二代轮子呢?市面上现成的项目框架不香吗?

因为项目组不允许用外部的现成框架,比如Ruoyi。另外因为我们的项目需求具有自身的特色,技术选型也会选择我们自己熟悉的框架,所以自己来造二代轮子也是一个不错的选择。

核心功能

需要包含以下核心功能:

多个微服务模块拆分,抽取出一个dmo微服务模块供扩展,已完成

提取核心框架模块,已完成

注册中心Eurka,已完成

远程调用OpnFign,已完成

日志logback,包含tracId跟踪,已完成

SwaggrAPI文档,已完成

配置文件共享,已完成

日志检索,ELKStack,已完成

自定义Startr,待定

整合缓存Rdis,Rdis哨兵高可用,已完成

整合数据库MySQL,MySQL高可用,已完成

整合MyBatis-Plus,已完成

链路追踪组件,待定

监控,待定

工具类,待开发

网关,技术选型待定

审计日志进入ES,待定

分布式文件系统,待定

定时任务,待定

等等

本篇要介绍的内容是关于日志链路追踪的。

一、痛点

痛点一:进程内的多条日志无法追踪

一个请求调用,假设会调用后端十几个方法,打印十几次日志,无法将这些日志串联起来。

如下图所示:客户端调用订单服务,订单服务中方法A调用方法B,方法B调用方法C。

方法A打印第一条日志和第五条日志,方法B打印第二条日志,方法C打印第三条日志和第四条日志,但是这5条日志并没有任何联系,唯一的联系就是时间是按照时间循序打印的,但是如果有其他并发的请求调用,则会干扰日志的连续性。

痛点二:跨服务的日志如何进行关联

每个微服务都会记录自己这个进程的日志,跨进程的日志如何进行关联?

如下图所示:订单服务和优惠券服务属于两个微服务,部署在两台机器上,订单服务的A方法远程调用优惠券服务的D方法。

方法A将日志打印到日志文件1中,记录了5条日志,方法D将日志打印到日志文件2中,记录了5条日志。但是这10条日志是无法关联起来的。

痛点三:跨线程的日志如何关联

主线程和子线程的日志如何关联?

如下图所示:主线程的方法A启动了一个子线程,子线程执行方法E。

方法A打印了第一条日志,子线程E打印了第二条日志和第三条日志。

痛点四:第三方调用我们的服务,如何追踪?

本篇要解决的核心问题是第一个和第二个问题,多线程目前还未引入,目前也没有第三方来调用,后期再来优化第三个和第四个问题。

二、方案

1.1解决方案

①使用SkywalkingtracId进行链路追踪

②使用ElasticAPM的tracId进行链路追踪

③MDC方案:自己生成tracId并put到MDC里面。

项目初期,先不引入过多的中间件,用简单可行的方案先尝试,所以这里用第三种方案MDC。

1.2MDC方案

MDC(MappdDiagnosticContxt)用于存储运行上下文的特定线程的上下文数据。因此,如果使用log4j进行日志记录,则每个线程都可以拥有自己的MDC,该MDC对整个线程是全局的。属于该线程的任何代码都可以轻松访问线程的MDC中存在的值。

三、原理和实战

2.1追踪一个请求的多条日志

我们先来看第一个痛点,如何在一个请求中,将多条日志串联起来。

该方案的原理如下图所示:

(1)在logback日志配置文件中的日志格式中添加%X{tracId}配置。

pattrn%d{yyyy-MM-ddHH:mm:ss.SSS}[%thrad]%X{tracId}%-5lvl%loggr-%msg%n/pattrn

(2)自定一个拦截器,从请求的hadr中获取tracId,如果存在则放到MDC中,否则直接用UUID当做tracId,然后放到MDC中。

()配置拦截器。

当我们打印日志的时候,会自动打印tracId,如下所示,多条日志的tracId相同。

示例代码

拦截器代码:

/***

author


转载请注明:http://www.aierlanlan.com/cyrz/3542.html

  • 上一篇文章:
  •   
  • 下一篇文章: