gateway链路监控
现状:目前查找一个交易的详情,须要通过portainer进入申请所在的容器查找流水号对应的日志。因为申请很多,同一申请的日志可能不在一起,并且同一申请中有的日志无奈增加流水号。
目标:通过流水号对网关日志进行查问,可失去同一申请的所有日志。
原理图:
办法:
将gateway的同一申请的日志增加流水号:
- 申请进入时日志增加流水号
- 响应回来时日志增加流水号,因为申请和响应不是同一个线程解决
- 发送响应时删除日志流水号
- 异步操作传递流水号
通过ELK对网关日志进行收集,以gateway-{date}归集一个index,做为根底的服务日志。
Filebeat:换行的日志当作一条发送到kafka
Logstash:解析orderNo当作es的一个字段
查问:
配置后端服务的日志收集地址,在查问交易日志时可通过api查到关联的上游日志
以api-invoke-his做为交易流水库,依据流水号,网关类型和日期到gateway-{date}(昨今今天)查问具体gateway日志,依据apiName查到关联的上游日志index,综合失去整条链路的日志
毛病:
- 代码侵入性比拟强,须要改变到处中央
- 被动配置的中央较多,须要配置交易的日志收集index,即交易的链路。须要提前晓得交易的链路。比照skywalking,引入agent即可打印链路的信息,然而无奈打印日志。
- 如果想监控mysql、es,须要本人开发agent
系统日志监控:
背景:
微服务中系统日志散落在各个机器中,无奈集中查看,目前通过elk可收集各个系统的日志在kibana查看。然而日志构造比拟涣散,出了问题排查艰难,须要当时找到机器。此外如果日志量大,难以查看报错日志的上下文。因而须要疾速找到一次申请链上的所有日志。因而须要一种疾速晓得哪里报错以及找到报错上下文日志的计划。
计划简述:
将同一申请/解决逻辑的日志增加雷同流水号,不便零碎异样时查到关联日志。其中所有服务的异样日志放入同一个es的index,不便间接展现谬误日志。如果该日常蕴含流水号,可去相干服务查问具体日志。如果晓得申请通过的服务,能够查问链路的相干日志。谬误日志也放入kafka的topic中,便于监控零碎对接告警。
目标:
- 疾速找到报错的日志及流水号,便于查看系统启动时是否胜利
- 通过流水号找到对立申请的日志。(须要手动关联同一流水号的多个服务,无奈做到api级别的动静关联,如果查找所有index比拟消耗性能)
原理图:
流程:
- Filebeat监听服务日志,定义logtopic放入kafka的openapi_{logtopic}中
- Logstash监听openapi_{logtopic}的topic,将数据格式化后输入至三个方向:
- 全量输入至{logtopic}_{date},即在es中按logtopic和日期为index进行保留
- 级别为error的日志一方面输入至openapi_error_{date},即以error和日期为index进行保留,另一方面输入至topic为openapi-error的kafka中,供监控告警应用。
- 这些输入是并行的。
- Monitor以error_{date}为根底数据源进行查看,如果异样日志蕴含流水号,则可跳转至{logtopic}-{date}进行查看服务的日志。如果查看相干链路日志,须要联结index进行查问。
须要解决的问题:
- 流水号在服务外部传递
- 流水号在服务间传递
- 流水号在异步线程传递
- 服务在某个办法中传递
服务日志增加流水号的形式:
- request filter:web申请到来时,如果此时线程中曾经设置过流水号,不必再设置。如果没有设置且header中蕴含orderNo,则将其作为以后线程的order,否则新生成orderNo并设置。确保filter是申请第一个进入的,防止一些log记录不到流水号。
- Feign intercepter:服务通过feign调用其余服务时,将以后线程的orderNo放入header中,保障上游服务能够取得orderNo。如果有应用hystrix,须要在hystrix线程池中传递mdc
- 异步线程池:异步执行时,无奈传递流水号,因而须要应用特定的线程池,能够传递流水号
- 独自执行的办法:redis,mq的监听,执行定时工作,由特定事件执行,而非web申请触发,通过aop在办法执行前设置MDC,实现后革除
革新的中央:
- 异步执行应用特定线程池
- 独自执行的办法增加注解
- Filebeat减少换行的配置,只传输*All的日志
- Logstash减少orderNo的解析,log_level为error的传入es及kafka中
问题:
如果不是logger.info或logger.error的日志,如果出现异常如NullPointerException,尽管是同一个线程解决,但流水号无奈继承。须要有GlobalExceptionAspect捕捉全局异样
Async-threadpool:
- 提供一个能够间接应用的线程池,@Async间接应用。使用方便,不必什么配置
- 提供获取线程池的静态方法,能够通过办法获取,通过@Bean注入,便于设置线程池参数。场景:有多个参数不同的线程池需要
- 提供线程池装璜器,自定义的线程池加上装璜器即可增加mdc
Method-aspect:
有些代码的执行并不禁web申请触发,而是由定时工作,mq的监听触发,执行某个办法。因而须要对办法进行AOP拦挡,执行前增加MDC,执行完后删除。此外留神产生异样时也须要拦挡并删除MDC。
异样如果不必logger.error/info记录,则无奈打印MDC,主动抛出的异样(如除数为0)尽管在一个线程解决但mdc为空。因而AOP须要拦挡异样并用logger.error进行记录。
此外,@PostConstruct执行的办法无奈增加MDC。
Feign-interceptor:
如果以后线程蕴含MDC,则在header中设置,否则不做解决。因为有可能应用到hystrix进行限流熔断,须要对hystrix进行配置
Request-interceptor:
如果以后线程蕴含MDC,不做解决;如果不蕴含,查看header是否含有orderNo,如果蕴含,将orderNo作为流水号设为MDC,否则生成新orderNo作为MDC。
留神的几个点:
- Filebeat同步的是**All.log日志,防止error呈现两次
- MDC put后再put,会革除
- Request filter的order; filter在interceptor前,因而须要用filter且优先级最高,保障申请到来第一个进入
- Gateway无奈应用skywalking,因为是nio,申请和响应是不同线程解决,响应无奈与申请的mdc保持一致
- 第三方jar包的类名最好加上服务名称,防止反复