分布式系统中日志的串联

        分布式系统中,一个业务任务请求会被多个系统串联或者并行的去执行,最后返回结果,这已经很常见。

为了在日志中能很快的在各个系统中对应的属于同一业务任务的日志,我们可以在最初时,产生一个 SN 唯一编码,然后在各个系统之间的调用参数中,必须统一规范的传递这个SN 。于是每个系统都能知道SN.

        系统知道了SN 之后,怎么方便的应用起来?不能每次log的时候都硬编码这个SN输出(Log.info("{},abcdef", SN)这样无法避免有小弟弟会糊弄,于是可以再logger 的配置文件里进行配置:

<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <File>${log.base}configuration.log</File>
        	<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId}] %logger{0} - %msg%n</pattern>
        </encoder>
</appender>

 红色部分就是一个 SN 值得代号,可以通过很多形式比如在filter中:

MDC.put("traceId", newTraceId);

 这个MDC 是logback的类。里面的实现就是涉及到上一篇文章中的 InheritableThreadLocal .

而从MDC中读取put的值就是 %x{keyName} 的方式。

这里用InheritableThreadLocal 而不同 ThreadLocal 的原因就是,在系统中,如果启动了别的子线程去处理任务,那么也可以从 InheritableThreadLocal  中获取刚进入系统时设置的 MDC里的值。

       在各系统间传递 SN 的值,就各有各的规范了,比如必须在header中出现,或者在请求报文中必须以什么样固定方式出现等。

猜你喜欢

转载自kangzye.iteye.com/blog/2358680