目录
一、zuul(同步)
1.快速入门
1.1配置pom.xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-zuul -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
1.2配置application.properties
server.port=8769
spring.application.name=zuul
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
zuul.routes.provider.path=/provider/**
zuul.routes.provider.serviceId=provider
zuul.routes.consumer=/consumer/**
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=28000
ribbon.ConnectionTimeout=500
ribbon.ReadTimeout=6000
zuul.retryable= true
#在rest请求重试3次且都没有连接成功,就会触发熔断机制(熔断器开关打开)
ribbon.MaxAutoRetries= 3
#切换实例的重试次数
ribbon.MaxAutoRetriesNextServer=0
1.3启动类添加@EnableZuulProxy注解
@SpringBootApplication
@EnableZuulProxy
@EnableEurekaClient
@EnableDiscoveryClient
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
至此,该网关应用已经能根据路由配置实现路由功能了,接下来是配置过滤器
1.4过滤器实现类
public class AccessFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext=RequestContext.getCurrentContext();
HttpServletRequest request=requestContext.getRequest();
Object token=request.getParameter("token");
if(token==null){
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(401);
return null;
}
return null;
}
}
接下来需要配置一个过滤器的bean这个过滤器才能生效。
1.5配置bean
@Configuration
public class AccessFilterConf {
@Bean
public AccessFilter filter(){
return new AccessFilter();
}
}
上面就实现了一个简单的zuul网关配置。
2.深入理解zuul
2.1什么是zuul?
zuul 是netflix开源的一个API ,它包含了对请求的路由和过滤两个功能。其中路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础;过滤功能则负责对请求的处理过程进行干预,是实现请求校验、服务聚合等功能的基础。
2.2 路由
- 服务路由配置(两种方式)
#方式一:serviceId方式
zuul.routes.provider.path=/provider/**
zuul.routes.provider.serviceId=provider
#方式二:无serviceId方式
zuul.routes.consumer=/consumer/**
- 请求映射
直接请求provider服务地址:http://localhost:8764/add
通过网关请求provider服务地址:http://localhost:8769/provider/add
直接请求consumer服务地址:http://localhost:8762/select
通过网关请求provider服务地址:http://localhost:8769/consumer/select
2.3过滤器
zuul除了有强大的路由功能外,还提供了强大的过滤功能。
2.3.1过滤器详解
public class AccessFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() throws ZuulException {
RequestContext requestContext=RequestContext.getCurrentContext();
HttpServletRequest request=requestContext.getRequest();
Object token=request.getParameter("token");
if(token==null){
requestContext.setSendZuulResponse(false);
requestContext.setResponseStatusCode(401);
return null;
}
return null;
}
}
当我们需要使用过滤器时需要继承ZuulFilter 抽象类,并实现其中的4个抽象方法。
- filterType:该函数通过返回一个字符串来代表该过滤器的类型,这个类型就是在HTTP请求过程中定义的各个阶段,在Zuul中默认定义了4种不同的生命周期的过滤器类型,如下
pre:可以在请求被路由之前调用
routing:在路由请求是被调用
post:在routing和error过滤器之后被调用
error :处理请求时发生错误时被调用
- filterOrder:通过int值来定义过滤器的执行顺序数值越小优先级越高
- shouldFilter:返回boolean值来判断该过滤器是否执行,相当于一个开关
- run:过滤器的具体实现逻辑,在该函数中我们可以实现自定义的过滤器逻辑,来确定是否要拦截当前请求,不对其进行后续的路由,或者是在请求路由返回结果之后,对处理结果做一些加工。
2.3.2 zuul过滤器过滤过程解析
如图,当外部HTTO请求到达API网关服务的时候,首先它会进入第一个阶段pre,在这里他会被pre类型的过滤器进行处理,该类型过滤器的主要目的是在进行请求路由之前做一些前置加工,如请求校验等。
在完成pre类型的过滤器处理之后进入第二阶段routing,也就是将路由转发阶段,请求会被routing类型过滤器处理。这里的具体处理内容就是将外部请求转发到具体服务实例上去的过程。
当服务实例将请求结果都返回之后,ruoting阶段完成,请求进入第三阶段post。此时请求将会被post类型的过滤器处理,这些过滤器在处理的时候不仅可以获取到请求信息,还能获取到服务实例的返回相信,所以在post类型过滤器中,我们可以处理结果进行一些加工或者转换等。
另外,还有一个特殊的阶段error,该阶段只有在上面三个阶段中发生异常的时候才会被触发,但是他的最后流向还是post类型过滤器,最后返回给客户端。