前言
凡是文中需要注册到nacos的都需要这个jar包
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
凡是使用config jar包的都需要写bootstrap.properties
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
-
在注册中心注册
spring.cloud.nacos.discovery.server-addr=192.168.14.58:8848
-
配置注册中心的地址
spring.cloud.nacos.config.server-addr=192.168.14.58:8848
文章目录
Spring Cloud Alibaba Gateway 全链路跟踪TraceId日志
1.filter包中直接编码
方式和token类似
@Component
@Slf4j
public class TraceFilter implements GlobalFilter, Ordered {
private static final String TRACEID = "traceid";
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
List<String> traceIds = request.getHeaders().get(TRACEID);
String traceid = "";
if(ObjectUtil.isEmpty(traceIds)){
traceid = IdUtil.fastSimpleUUID();
log.debug("没有traceId,生成一个{}",traceid);
ServerHttpRequest traceid1 = request.mutate().header(TRACEID, traceid).build();
ServerWebExchange exchange1 = exchange.mutate().request(traceid1).build();
chain.filter(exchange1);
return chain.filter(exchange1);
}
log.debug("traceId,已经存在{}",traceIds.get(0));
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 2;
}
}
配置文件这里配置了多个路由 ,测试用的是 route[2]可以只写一个
但是一定要加入
token.key=by123
spring.application.name=gateway-app
spring.cloud.nacos.discovery.ip=192.168.14.53
logging.level.com.hb=debug
logging.level.root=error
# 配置路由
spring.cloud.gateway.routes[0].id = test
#这是显示请求详情的网址,同时也是本次被路由到的url
spring.cloud.gateway.routes[0].uri = http://httpbin.org
#配置断言 也就是本次可以被路由出的地址必须在test域名下
spring.cloud.gateway.routes[0].predicates[0] = Path=/test/**
# 配置截取二级目录 也就是 截取 http://httpbin.org/test/** 截取成为 http://httpbin.org/**
spring.cloud.gateway.routes[0].filters[0] = StripPrefix=1
#添加过滤请求时 请求头中添加一个参数
spring.cloud.gateway.routes[0].filters[1] = AddRequestParameter=aa,blue
#请求头中添加参数
spring.cloud.gateway.routes[0].filters[2] = AddRequestHeader=lianxu,shuai
#添加一个返回头
spring.cloud.gateway.routes[0].filters[3] = AddResponseHeader=kuailong,shuaidaile
spring.cloud.gateway.routes[0].filters[4] = LogTime=50
spring.cloud.gateway.routes[0].filters[5] = LogTime2=ms,50
#配置中心注册服务
spring.cloud.nacos.discovery.server-addr=192.168.14.58:8848
spring.cloud.gateway.routes[1].id = nacos-a
#这是显示请求详情的网址,同时也是本次被路由到的url
spring.cloud.gateway.routes[1].uri = lb://nacos-a
#配置断言 也就是本次可以被路由出的地址必须在test域名下
spring.cloud.gateway.routes[1].predicates[0] = Path=/nacosa/**
# 配置截取二级目录 也就是 截取 http://httpbin.org/test/** 截取成为 http://httpbin.org/**
spring.cloud.gateway.routes[1].filters[0] = StripPrefix=1
spring.cloud.gateway.routes[1].filters[1] = LogTime=50
spring.cloud.nacos.discovery.register-enabled=true
#路由
spring.cloud.gateway.routes[2].id=openfeign-app
spring.cloud.gateway.routes[2].uri = lb://openfeign-app
spring.cloud.gateway.routes[2].predicates[0] = Path=/openfeign/**
spring.cloud.gateway.routes[2].filters[0] = StripPrefix=1
spring.cloud.gateway.routes[2].filters[1] = LogTime=50
结果
2.使用openFeign转发
2.1 配置TraceId 过滤器
依赖
需要将服务注册道nacos中
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.18</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
过滤器
@WebFilter
@Slf4j
public class TraceFilter implements Filter {
public static String TRACEID = "traceId";
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String traceId = httpServletRequest.getHeader(TRACEID);
if(ObjectUtil.isNotEmpty(traceId)){
MDC.put(TRACEID,traceId);
}
log.info("岁在甲子,天下大吉{}",traceId);
filterChain.doFilter(servletRequest, servletResponse);
}
}
主类配置
配置文件
#配置name
spring.application.name=openfeign-app
server.port = 3030
#Nacos服务发现注册中心
spring.cloud.nacos.discovery.server-addr=192.168.14.58:8848
spring.cloud.nacos.discovery.register-enabled=true
logging.level.com.hb = debug
##日志输出格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%-5level) %clr([%X{traceId}]) %clr(${PID:-}) --- %clr(%logger{50}) - %m%n
配置这个才能看到追踪的id
##日志输出格式
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(%-5level) %clr([%X{traceId}]) %clr(${PID:-}) — %clr(%logger{50}) - %m%n
接口
@RestController
public class TestController {
@Autowired
OrderClients orderClients;
@GetMapping("/port")
public String feignAClient(){
String port = orderClients.port();
return port;
}
@GetMapping("/sleep")
public String sleep(@RequestParam("s") Integer s){
String order = orderClients.sleep(s);
return order;
}
}
调用服务为nacos-a的方法
@FeignClient("nacos-a")
public interface OrderClients {
@GetMapping("/port")
String port();
@GetMapping("/sleep")
String sleep(@RequestParam("second") Integer second);
}
3.调用nacos中的接口
有必要说明一下这里只是接口刚好在当初配置的nacos里面,所以这里调用(我理解还不够深刻,先记着)
配置一定要加上
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
//注意:如果使用服务注册中心,需要添加@LoadBalanced注解
//加上该注解之后,RestTemplate会把请求的一级目录改为服务名,去服务注册中心抓取对应的ip,然后再去调用对应的接口数据
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
nacos-a 也需要将服务注册在其中(因为到这里线程就换啦,所以存储在threadlocal(MDC)线程中的traceId也就不存在)需要重新放入
@WebFilter
@Slf4j
public class TraceFilter implements Filter {
public static String TRACEID = "traceId";
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String traceId = httpServletRequest.getHeader(TRACEID);
if(ObjectUtil.isNotEmpty(traceId)){
MDC.put(TRACEID,traceId);
}
log.info("岁在甲子,天下大吉{}",traceId);
filterChain.doFilter(servletRequest, servletResponse);
}
}
controller
@GetMapping("/port")
public String port(){
log.info("gagaga");
return port + "aaa";
}
运行结果