- 背景描述
- 问题描述
- 解决思路
- 思路一
- 思路二
- 解决方案(思路二)
系统采用了前后端分离的架构搭建:
- 前端是采用Vue 2.X+elementUI开发,构建的安装包部署到Nginx服务上。
- 后端业务采用Java+spring cloud微服务架构,前置spring cloud gateway网关接入,后置各种业务微服务应用构成,通过alibaba Nacos做服务发现和应用配置。
需求是想把系统从Vue前端到Java后端的每一次访问日志通过唯一ID全链路跟踪起来。在Java后端微服务的全链路跟踪直接引入Spring Cloud Sleuth方案解决,但如何把Vue前端的Nginx访问日志与Java后端日志里由Sleuth生成的traceid关联起来呢?
解决思路 思路一在前端Nginx生成访问唯一ID,覆盖后端Sleuth方案产生的TraceID。
【nginx的request_id就是一个随机唯一ID,通过nginx配置可传递到upstream网关层,但是没有找到好办法去覆盖Sleuth方案产生TraceID,最终放弃此思路 】
利用后端Sleuth方案产生的TraceID,并在响应的时候把它返回Nginx层,并记录于nginx日志中。【最终选择方案】
解决方案(思路二)1、在spring cloud gateway微服务中需要实现GlobalFilter并在filter方法中给ServerHttpResponse添加新响应头存TraceID。具体代码片段如下:
@Component
public class MyGlobalFilter implements GlobalFilter, Ordered {
@Autowired
private Tracer tracer; // SLeuth方案的tracer对象(import brave.Tracer;),可以获取到traceID
@Override
@SuppressWarnings({"unchecked", "static-access"})
public Mono filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
// 记录sleuth产生的trace id到响应头里
response.getHeaders().set("traceid", tracer.currentSpan().context().traceIdString());
}
}
2、在前端Nginx日志配置$sent_http_traceid获取到TraceID。
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"
"$request_time" "$upstream_response_time" "$sent_http_traceid"';



