# log-parent **Repository Path**: JKcoding/log-parent ## Basic Information - **Project Name**: log-parent - **Description**: 基于Java日志平台的访问链路追踪 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2020-05-17 - **Last Updated**: 2022-05-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # log-parent ### 1、介绍 基于Java日志平台的访问链路追踪(ELK搭建参考中间件.pdf) ### 2、项目搭建 #### 2.1 项目描述 搭建⼀套微服务环境,实现多点⽇志采集,⽤于web请求的访问链路跟踪,包含以下跟踪点: - 请求的前台⻚⾯ - 请求到达nginx的转发记录 - 请求的后台⽅法 - 请求的业务输出标记 - 远程的⽅法调⽤(如有涉及) #### 2.2 设计⽬标 ##### 2.2.1 检索维度 可以按常⽤维度做到快速检索: - 某次请求 - 某个⽤户 - 某个终端 ##### 2.2.2 分布式环境 - 机器以集群形式部署多台 - 微服务存在docker等容器化部署场景 - 不同机器的同⼀服务⽇志要做到集中展示 ##### 2.2.3 低⼊侵 在保障⽇志内容详尽的前提下,尽量做到业务代码⽆感知 ##### 2.2.4 低耦合 ⽇志服务不要影响主业务的进⾏,⽇志down机不能阻断业务执⾏ ##### 2.2.5 时效性 ⽇志在分布式环境中⽆法做到完全实时,但要尽量避免过⻓的时间差 ##### 2.2.6 缓冲与防丢失 在⽇志服务不可⽤时,对应⽤的⽇志产出要做到暂存,缓冲,防⽌丢失 #### 2.3 设计 ##### 2.3.1 基本概念 本项⽬中,与请求链路相关的概念约定如下: - rid(requestId):⼀次请求的唯⼀标示,⽣成后⼀直传递到调⽤结束 - sid(sessionId):⽤户会话相关,涉及登陆时存在,不登陆的操作为空 - tid(terminalId):同⼀个终端的请求标示,可以理解为同⼀个设备。可能对应多个⽤户的多次请求 ##### 2.3.2 前台⻚⾯ - ⻚⾯⾸次加载时⽣成tid,写⼊当前浏览器的cookie,后续请求都会携带 - ⻚⾯请求时,⽣成唯⼀性的rid作为⼀次请求的发起 - 如果⽤户session作为sid,⽤于识别同⼀⽤户的⾏为 ##### 2.3.3 nginx - ⽅案⼀:通过accesslog可以打印,fifilebeat采集本地⽂件⽅式可以送⼊kafka通道 - ⽅案⼆:lua脚本可以直接送⼊kafka - logstash获取kafka⽇志数据,进⼊es ##### 2.3.4 java服务端 - gateway作为统⼀⽹关,处理三个维度变量的⽣成与下发 - 各个微服务集成kafka,将⾃⼰需要的⽇志送⼊kafka ##### 2.3.5 ⽅法调⽤ - Aop切⾯,拦截器等系统组件可以以插件形式介⼊⽇志采集,缺点是⽆法灵活做到个性化定制 - 注解操作灵活,可以⾃由定制输出内容,缺点是对代码存在轻微⼊侵 ##### 2.3.6 远程调⽤ - 远程⽅法之间的调⽤,三个id通过显式参数形式进⾏传递,由当前服务到下⼀个服务 ##### 2.3.8 系统拓扑 ![1589684268143](C:\Users\ADMINI~1\AppData\Local\Temp\1589684268143.png) #### 2.4 框架搭建 搭建⼀个微服务项⽬,集成⽇志平台的对接。 ##### 2.4.1 模块划分 - ⽗pom:maven项⽬的⽗pom,⽤于整个项⽬的依赖继承,版本传递和约束 - nacos:springcloud的注册中⼼和配置中⼼ - gateway:微服务⽹关,请求链路进⼊后台的第⼀道关⼝ - web:springboot集成web组件,⽤于模拟我们的上层web项⽬ - user:基于springcloud微服务模块,⽤于模拟实际项⽬中的⼀个⽤户微服务 - utils:存放⽇常使⽤的⼀些⼯具类 ##### 2.4.2 nacos  Nacos ⽀持基于 DNS 和基于 RPC 的服务发现(可以作为springcloud的注册中⼼)、动态配置服务(可以做配置中⼼)、动态 DNS 服务。 1)快速启动参考:https://nacos.io/zh-cn/docs/quick-start.html 2)下载解压,可以修改conf/application.properties,配置端⼝信息 (可到**springcloud alibaba**仓库中查找,之前上传了) 3)启动: sh /opt/app/nacos/bin/startup.sh -m standalone ##### 2.4.3 ⽗pom以及子模块(详情参考源码) 1)访问 http://start.spring.io 2)选择版本并填写相关坐标 ,根据实际选择 3)创建web、user、utils模块 ### 3、项⽬实施 #### 3.1基本思路 从访问源头开始,按链路逐个写⼊⽇志,使⽤不同的⼿段,实现⽤户请求的各个点的⽇志收集 #### 3.2 前端请求 ##### 3.2.1 概述 ⽬前项⽬多采⽤动静分离⽅式,静态⻚由nginx处理。那么nginx上的请求⽇志如何收集处理呢? - 第⼀可以采⽤输出到log⽂件,fifilebeat采集,送⼊kafka。 - 第⼆可以采⽤lua脚本⽅式,直接输出到kafka 采⽤第⼆种⽅式,完成静态⽂件部分的请求⽇志追踪。 ##### 3.2.2 openresty  下载解压,修改nginx.conf文件的kafka地址为自己的,所有配置都搞定了,直接使用即可 #### 3.3 微服务层 ##### 3.3.1 概述 后台服务同样需要⽣成上⾯的rid,tid,sid和基本的ip与url,这些在java端被封装在了HttpServletRequest中。通过request对象,获取相应的信息后,可以将访问信息送⼊⽇志平台。 ##### 3.3.2 代理转发 修改nginx.conf文件的转发地址为自己的 ##### 3.3.3 fifilter第⼀关 请求进⼊后台后,第⼀道关卡可以通过fifilter或者interceptor拿到相关信息,记录其调⽤⽇志。 参考在utils项⽬下的filter过滤器 ##### 3.3.4 id的⽣成 ⽇志可以正常进⼊采集通道,但是各个id采⽤的是字符串,怎么取得真实的场景数据呢?参考utils项目的CommonUtils 类 ##### 3.3.5 切⾯aop 参考LogAspect 和注解LogInfo ##### 3.3.6 重写RestTemplate 的execute⽅法 参考MyRestTemplate #### 3.4 总结 1. 前端链路收集:lua+kafka 2. 微服务fifilter,第⼀道关卡 3. threadlocal服务内上下⽂传递 4. 切⾯和注解配合完成⽇志的⾃动打印 5. 乱序问题 (增加字段time解决) 6. 跨服务的传递(重写RestTemplate的execute⽅法 ) 7. ⽤户登陆的sid