1,zuul 简介
1.1,zuul 是什么
zuul 是 netflix 开源的一个 API Gateway 服务器, 本质上是一个 web servlet 应用.
Zuul 在云平台上提供动态路由, 监控, 弹性, 安全等边缘服务的框架. Zuul 相当于是设备和 Netflix 流应用的 Web 网站后端所有请求的前门.
Zuul 的主要功能是路由转发和过滤器. 路由功能是微服务的一部分, 比如 / api/user 转发到到 user 服务,/api/shop 转发到到 shop 服务. zuul 默认和 Ribbon 结合实现了负载均衡的功能.
1.2,zuul 能做什么
zuul 的核心是一系列的 filters, 其作用可以类比 Servlet 框架的 Filter, 或者 AOP.
Zuul 可以通过加载动态过滤机制, 从而实现以下各项功能:
验证与安全保障: 识别面向各类资源的验证要求并拒绝那些与要求不符的请求.
审查与监控: 在边缘位置追踪有意义数据及统计结果, 从而为我们带来准确的生产状态结论.
动态路由: 以动态方式根据需要将请求路由至不同后端集群处.
压力测试: 逐渐增加指向集群的负载流量, 从而计算性能水平.
负载分配: 为每一种负载类型分配对应容量, 并弃用超出限定值的请求.
静态响应处理: 在边缘位置直接建立部分响应, 从而避免其流入内部集群.
多区域弹性: 跨越 AWS 区域进行请求路由, 旨在实现 ELB 使用多样化并保证边缘位置与使用者尽可能接近.
2, 创建 service-zuul 工程
2.1, 创建 service-zuul 工程, pom.xml 文件如下
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <groupId>com.lishun</groupId>
- <artifactId>service-zuul</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
- <name>service-zuul</name>
- <description>Demo project for Spring Boot</description>
- <parent>
- <groupId>com.lishun</groupId>
- <artifactId>cloud</artifactId>
- <version>1.0-SNAPSHOT</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
- <dependencies>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- </dependencies>
- </project>
2.2, 在其入口 applicaton 类加上注解 @EnableZuulProxy, 开启 zuul 的功能:
- @EnableZuulProxy
- @EnableEurekaClient
- @SpringBootApplication
- public class ServiceZuulApplication {
- public static void main(String[] args) {
- SpringApplication.run(ServiceZuulApplication.class, args);
- }
- }
2.3, 加上配置文件 application.yml 加上以下的配置代码:
- eureka:
- client:
- serviceUrl:
- defaultZone: http://localhost:8761/eureka/
- server:
- port: 8769
- spring:
- application:
- name: service-zuul
- zuul:
- routes:
- api-a:
- path: /api-a/**
- serviceId: service-ribbon
- api-b:
- path: /api-b/**
- serviceId: service-feign
首先指定服务注册中心的地址为 http://localhost:8761/eureka/ , 服务的端口为 8769, 服务名为 service-zuul;
以 / api-a/ 开头的请求都转发给 service-ribbon 服务; 以 / api-b / 开头的请求都转发给 service-feign 服务;
2.4, 启动 5 个服务, 浏览器访问 http://localhost:8769/api-a/hi?name=lis 页面显示
hi lis ,i am from port:8762
浏览器访问 http://localhost:8769/api-b/hi?name=lis 页面显示
hi lis ,i am from port:8762
这说明 zuul 起到了路由的作用
3, 服务过滤
前面提到, Zuul 通过加载动态过滤机制, 不仅可以实现路由功能, 还能实现验证, 检查, 监控等功能.
下面使用 zuul 来实现安全验证功能
- @Component
- public class MyFilter extends ZuulFilter {
- private static Logger log = LoggerFactory.getLogger(MyFilter.class);
- @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 ctx = RequestContext.getCurrentContext();
- HttpServletRequest request = ctx.getRequest();
- log.info(String.format("%s>>> %s", request.getMethod(), request.getRequestURL().toString()));
- Object accessToken = request.getParameter("token");
- if(accessToken == null) {
- log.warn("token is empty");
- ctx.setSendZuulResponse(false);
- ctx.setResponseStatusCode(401);
- try {
- ctx.getResponse().getWriter().write("token is empty");
- }catch (Exception e){}
- return null;
- }
- log.info("ok");
- return null;
- }
- }
filterType: 返回一个字符串代表过滤器的类型, 在 zuul 中定义了四种不同生命周期的过滤器类型, 具体如下:
pre: 路由之前
routing: 路由之时
post: 路由之后
error: 发送错误调用
filterOrder: 过滤的顺序
shouldFilter: 这里可以写逻辑判断, 是否要过滤, 本文 true, 永远过滤.
run: 过滤器的具体逻辑. 可用很复杂, 包括查 sql,nosql 去判断该请求到底有没有权限访问.
这时访问: http://localhost:8769/api-a/hi?name=forezp lis ; 网页显示:
token is empty
访问 http://localhost:8769/api-a/hi?name=lis&token=22 http://localhost:8769/api-a/hi?name=forezp&token=22 ; 网页显示:
hi lis ,i am from port:8762
来源: http://www.bubuko.com/infodetail-2697638.html