Zuul(网关:路由和过滤)
ZUUL是Netflix开源的微服务网关,它可以和Eureka、Ribbon、Hystrix等组件配合使用,Zuul组件的核心是一系列的过滤器,这些过滤器可以完成以下功能:
- 动态路由:动态将请求路由到不同后端集群
- 压力测试:逐渐增加指向集群的流量,以了解性能
- 负载分配:为每一种负载类型分配对应容量,并弃用超出限定值的请
- 静态响应处理:边缘位置进行响应,避免转发到内部集群
- 身份认证和安全: 识别每一个资源的验证要求,并拒绝那些不符的请求。Spring Cloud对Zuul进行了整合和增强。
一、搭建Zuul网管服务
- 创建工程导入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>2.1.0.RELEASE</version>
</dependency>
- 编写ZuulServerApplication并开启Zuul的网关功能
@SpringBootApplication
@EnableZuulProxy // 开启Zuul的网关功能
public class ZuulServerApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulServerApplication.class, args);
}
}
- 配置application.yml
server:
port: 8080 #服务端口
spring:
application:
name: api-gateway #指定服务名
-
在application.yml进行Zuul中的路由配置
a. 基于指定路径url的配置
就是url是一个固定的ip和端口
zuul: routes: product-service: # 这里是路由id,随意写 path: /product-service/** # 这里是映射路径 url: http://127.0.0.1:9002 # 映射路径对应的实际url地址 # sensitiveHeaders: #默认zuul会屏蔽cookie,cookie不会传到下游服务,这里设置为空则取消默认的黑名单,如果设置了具体的头信息则不会传到下游服务
通过path和url进行匹配,但请求路径是path时,会转发到url
b. 面向服务的路由
1> 添加eureka依赖
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
2>开启eureka服务发现
@SpringBootApplication @EnableZuulProxy // 开启Zuul的网关功能 //EnableDiscoveryClient开启eureka @EnableDiscoveryClient public class ZuulServerApplication {...}
3> 在application.yml中添加eureka配置
eureka: client: serviceUrl: defaultZone: http://127.0.0.1:8761/eureka/ registry-fetch-interval-seconds: 5 #获取服务列表的周期:5s instance: preferIpAddress: true ip-address: 127.0.0.1
4>在application.yml中修改映射配置,通过服务名称获取
#配置路由规则 zuul: routes: product-service: # 这里是路由id,随意写 path: /product-service/** # 这里是映射路径 serviceId: service-product #配置转发的微服务名称 # 可以简化上面的配置 zuul: routes: #直接使 用serviceId: path service-product: /product-service/** #zuul也有默认的路由配置 #即 如果当前的微服务名称 service-product , 默认的请求映射路径 /service-product/** 这个无需自己配置,zuul默认
已经有了Eureka客户端,我们可以从Eureka获取服务的地址信息,因此映射时无需指定IP地址,而是通过服务名称来访问,而且Zuul已经集成了Ribbon的负载均衡功能。
Zuul加入后架构
ZuulFilter 过滤
Zuul 中的过滤器总共有 4 种类型:
- PRE:这种过滤器在请求被路由之前调用。我们可利用这种过滤器实现身份验证、在集群中选择请求的微服务、记录调试信息等。(转发之前执行)
- ROUTING:这种过滤器将请求路由到微服务。这种过滤器用于构建发送给微服务的请求,并使用Apache HttpClient或Netfilx Ribbon请求微服务。(路由请求时执行)
- POST:这种过滤器在路由到微服务以后执行。这种过滤器可用来为响应添加标准的HTTPHeader、收集统计信息和指标、将响应从微服务发送给客户端等。(执行微服务获取返回值之后执行)
- ERROR:在其他阶段发生错误时执行该过滤器。(在整个阶段抛出异常执行)
使用Zuul过滤器只需要自定义Zuul过滤器
* 自定义的zuul过滤器
* 继承抽象父类ZuulFilter
*/
@Component
public class LoginFilter extends ZuulFilter {
/**
* 定义过滤器类型
* pre
* routing
* post
* error
*/
public String filterType() {
return "pre";
}
/**
* 指定过滤器的执行顺序
* 返回值越小,执行顺序越高
*/
public int filterOrder() {
return 1;
}
/**
* 当前过滤器是否生效
* true : 使用此过滤器
* flase : 不使用此过滤器
*/
public boolean shouldFilter() {
return true;
}
/**
* 指定过滤器中的业务逻辑
* 身份认证:
* 1.所有的请求需要携带一个参数 : access-token
* 2.获取request请求
* 3.通过request获取参数access-token
* 4.判断token是否为空
* 4.1 token==null : 身份验证失败
* 4.2 token!=null : 执行后续操作
* 在zuul网关中,通过RequestContext的上下问对象,可以获取对象request对象
*/
public Object run() throws ZuulException {
//System.out.println("执行了过滤器");
//1.获取zuul提供的上下文对象RequestContext
RequestContext ctx = RequestContext.getCurrentContext();
//2.从RequestContext中获取request
HttpServletRequest request = ctx.getRequest();
//3.获取请求参数access-token
String token = request.getParameter("access-token");
//4.判断
if (token ==null) {
//4.1 如果token==null ,拦截请求,返回认证失败
ctx.setSendZuulResponse(false); // 拦截请求
ctx.setResponseStatusCode(HttpStatus.UNAUTHORIZED.value());
}
//4.2 如果token!=null ,继续后续操作
return null;
}
项目源码:https://gitee.com/hxmkd/spring-cloud/tree/master/study_springcloud7_zuul