一、Zuul 简介
Zuul 是 Netflix 开源的微服务网关,他可以和 Eureka,Ribbon,Hystrix 等组件配合使用。Zuul 组件的核心是一系列的过滤器,这些过滤器可以完成以下功能:
身份认证和安全:
识别每一个资源的验证要求,并拒绝那些不符的请求
审查与监控
动态路由:
动态将请求路由到不同后端集群
压力测试:
逐渐增加指向集群的流量,以了解性能
负载分配:
为每一种负载类型分配对应容量,并弃用超出限定值的请求
静态响应处理:
边缘位置进行响应,避免转发到内部集群
多区域弹性:
跨域 AWS Region 进行请求路由,旨在实现 ELB(ElasticLoad Balancing)使用多样化spring-cloud-starter-zuul 是 Spring Cloud 对 Zuul 功能的整合和增强
二、创建 Zuul 网关路由
1、创建 SpringBoot 项目,引入依赖:pring-cloud-starter-eureka 和 spring-cloud-starter-zuul
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
<version>2.2.5.RELEASE</version>
</dependency>
2、项目配置文件 application.yml 中配置注册中心地址
server:
port: 7600
spring:
application:
name: cloud-zuul7600
eureka:
client:
service-url:
defaultZone: http://localhost:7200/eureka
zuul:
routes:
#自定义
api-a: #唯一
path: /cloud-provider/** #服务通过cloud-provider进来时会自动转发到CLOUD-USER-PROVIDER7300服务端调用
service-id: CLOUD-USER-PROVIDER7300 #Eureka服务名
api-b:
path: /cloud-rest-consumer/**
service-id: CLOUD-REST-CONSUMER7400
api-c:
path: /cloud-feign-consumer/**
service-id: CLOUD-FEIGN-CONSUMER7500
3、在入口函数使用 @EnableZuulProxy 注解启用 Zuul 网关路由
三、创建 Zuul 网关过滤器
1、网关过滤器实现步骤
在 springcloud-zuul 项目的 Spring 容器中加入网关过滤器 com.netflix.zuul.ZuulFilter 抽象类的子实现类,在此实现微服务集群权限控制功能:如下
package com.lsj.filter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Component
public class ZuulTokenFilter 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 {
//获取HttpServletRequest对象
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
HttpServletResponse response = ctx.getResponse();
response.setCharacterEncoding("UTF-8");
//获取headers传来的数据
String token = request.getHeader("token");
if(token != null){
return null;//放行
}
ctx.setSendZuulResponse(false);//拦截
try {
ctx.getResponse().getWriter().write("token过期");
} catch (IOException e) {
e.printStackTrace();
}
return null;//放行
}
}