SpringCloud Zuul基于Consul配置及详解
本文内容纲要:
一.构建工程
**1.引入依赖**
<!--SpringBoot2.0以上版本需引入该依赖-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
2.创建主类
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
@RestController
publicclassApplication{
publicstaticvoidmain(String[]args){
SpringApplication.run(Application.class,args);
}
}
3.配置application.properties
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.service-id=api-a
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.service-id=api-b
这里存在api-a和api-b两个微服务应用,当请求http://localhost:port/api-a/helloWorld,会被路由转发至api-a服务的/helloWorld接口,当请求http://localhost:port/api-b/helloWorld,会被路由转发至api-b服务的/helloWorld接口.当请求URL符合配置规则时,就会被转发至service-id对应的微服务应用接口.
4.配置请求过滤
SpringCloudZuul还有另一个和核心功能:请求过滤.Zuul允许开发者在API网关上通过定义过滤器来实现对请求的拦截与过滤,实现方法非常简单,只需继承ZuulFilter抽象类并实现它定义的4个抽象函数就可以完成对请求的拦截和过滤.
publicclassMyGatewayFilterextendsZuulFilter{
/*4种过滤器类型,
pre:可以在请求被路由之前调用,
route:在路由请求时候被调用,
post:在route和error过滤器之后被调用,
error:处理请求时发生错误时被调用*/
@Override
publicStringfilterType(){
return"pre";
}
@Override
publicintfilterOrder(){
return0;//优先级为0,数字越大,优先级越低
}
@Override
publicbooleanshouldFilter(){
returntrue;//是否执行该过滤器,此处为true,说明需要过滤
}
@Override
publicObjectrun(){
RequestContextctx=RequestContext.getCurrentContext();
HttpServletRequestrequest=ctx.getRequest();
log.info(String.format("%srequestto%s",request.getMethod(),request.getRequestURL().toString()));
ObjectaccessToken=request.getParameter("token");//获取token参数
if(accessToken==null){
log.warn("tokenisempty");
ctx.setSendZuulResponse(false);//过滤该请求,不对其进行路由
ctx.setResponseStatusCode(401);//返回错误码
ctx.setResponseBody("tokenisnull!");//返回错误内容
returnnull;//Zuul还未对返回数据做处理
}
returnnull;
}
}
创建过滤器后,它并不会直接生效,我们还需为其创建具体的Bean才能启动该过滤器.
@SpringBootApplication
@EnableDiscoveryClient
@EnableZuulProxy
@RestController
publicclassLixjApplication{
publicstaticvoidmain(String[]args){
SpringApplication.run(LixjApplication.class,args);
}
@Bean
publicMyGatewayFiltermyGatewayFilter(){
returnnewMyGatewayFilter();
}
}
二.路由详解
1.路径匹配规则******
/api-a/?可以匹配/api-a/之后拼接一个任务字符的路径,比如/api-a/a,/api-a/b,/api-a/c
/api-a/*可以匹配/api-a/之后拼接任意字符的路径,比如/api-a/a,/api-a/aaa,/api-a/bbb.但它无法匹配/api-a/a/b这种多级目录路径
/api-a/**可以匹配/api-a/*包含的内容之外,还可以匹配形如/api-a/a/b的多级目录路径
2.路由匹配顺序
随着版本的迭代,我们需要对一个服务做一些功能拆分,将原属于api-a服务的某些功能拆分到另一个全新的服务api-a-part中,而这些拆分的外部调用URL路径希望能够符合规则/api-a/part/**.
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.service-id=api-a
zuul.routes.api-a-part.path=/api-a/part/**
zuul.routes.api-a-part.service-id=api-a-part
在源码中,路由规则是通过LinkedHashMap保存的,也就是说,路由规则的保存时有序的,而内容的加载是通过遍历配置文件中路由规则依次加入的,所以导致问题的根本原因是对配置文件中内容的读取,但上述properties配置无法保证路由规则加载顺序,我们需要使用YML文件来配置,以实现有序的路由规则.
zuul:
routes:
api-a-part:
path=/api-a/part/**
service-id=api-a-part
api-a:
path=/api-a/**
service-id=api-a
3.本地跳转******
zuul.routes.api-c.path=/api-c/**
zuul.routes.api-c.url=forward:/api-c
以上配置使用了本地跳转,当url符合/api-c/**规则时,会被网关转发到自己本身服务的对应接口.
本文内容总结:
原文链接:https://www.cnblogs.com/xiaoshouxing/p/9502469.html