6. Zuul网关
6.1 简介
-
Zuul就是我们服务的统一入口
-
不管是来自于客户端(PC或移动端)的请求,还是服务内部调用。
-
一切对服务的请求都会经过Zuul这个网关,然后再由网关来实现 鉴权、动态路由等等操作。
6.2 Zuul入门
实际路径 : http://localhost:8081/test
期望路径 : http://localhost:10010/api/service/test
http://localhost:10010/路有前缀/服务名/controller访问路径
-
步骤一 : 导入pom依赖
<dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> </dependencies>
-
步骤二 : 开启zuul服务
@SpringBootApplication @EnableZuulProxy public class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class,args); } }
-
步骤三 : 修改yml文件
server: port: 10010 spring: application: name: zuul_demo zuul: prefix: /api #路由前缀 routes: service: /service/** path: /service/** url: http://localhost:8081
6.2 面向路由
-
上面的yml文件写法把访问路径写死了,修改为服务名访问
-
步骤一 : 修改pom依赖
<!--添加eureka客户端--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
-
步骤二 : 开启eureka客户端
@SpringBootApplication @EnableZuulProxy @EnableEurekaClient public class ZuulApplication { public static void main(String[] args) { SpringApplication.run(ZuulApplication.class,args); } }
-
步骤二 : 修改yml文件,注册自己到注册中心,并通过服务名访问
- 注册到注册中心后,会自动通过Ribbon进行服务名访问,访问路径可以省略不写
server: port: 10010 spring: application: name: zuul eureka: client: service-url: defaultZone: http://localhost:10087/eureka/ instance: instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${server.port} prefer-ip-address: true zuul: prefix: /api #路由前缀
6.3 过滤器
- Zuul作为网关的其中一个重要功能,就是实现请求的鉴权。
- 而这个功能我们往往是通过Zuul提供的过滤器来实现的
6.3.1 ZuulFilter
-
ZuulFilter 是过滤器的顶级父类,其中有四个方法
public abstract ZuulFilter implements IZuulFilter{ abstract public String filterType(); //过滤器类型 abstract public int filterOrder(); //执行顺序 boolean shouldFilter(); //是否需要执行 Object run() throws ZuulException; //具体业务逻辑 }
- shouldFilter:返回一个Boolean值,判断该过滤器是否需要执行。返回true执行,返回false不执行
- filterType:返回字符串,代表过滤器的类型。包含以下4种:
- pre:请求在被路由之前执行
- routing:在路由请求时调用
- post:在routing和errror过滤器之后调用
- error:处理请求时发生错误调用
- filterOrder:通过返回的int值来定义过滤器的执行顺序,数字越小优先级越高。
- run:过滤器的具体业务逻辑。
6.3.1 过滤器入门案例
-
创建一个测试类并继承ZuulFilter
package com.czxy.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; @Component public class LoginFilter extends ZuulFilter { @Override public String filterType() {// 设置类型 return "pre"; } @Override public int filterOrder() {// 设置排序 return 1; } @Override public boolean shouldFilter() {// 是否执行 return true; } @Override public Object run() throws ZuulException { //1, 获取上下文对象 RequestContext requestContext = RequestContext.getCurrentContext(); //2, 获取request对象 HttpServletRequest request = requestContext.getRequest(); //3, 获取校验请求头 String token = request.getHeader("Authorization"); //4, 判断是否存在 if (token == null){ //4.1 关闭响应 requestContext.setSendZuulResponse(false); //4.2 返回状态码 requestContext.setResponseStatusCode(401); } //5, 放行 return null; } }
6.4 负载均衡和熔断
-
Zuul中默认就已经集成了Ribbon负载均衡和Hystix熔断机制。
#网关配置 zuul: retryable: true #开启重试(注意:检查之前是否配置zuul,如果配置需要合并配置项) #全局负载均衡配置 ribbon: ConnectTimeout: 250 # 连接超时时间(ms) ReadTimeout: 2000 # 通信超时时间(ms) OkToRetryOnAllOperations: true # 是否对所有操作重试 MaxAutoRetriesNextServer: 2 # 同一服务不同实例的重试次数 MaxAutoRetries: 1 # 同一实例的重试次数 #熔断 hystrix: command: default: execution: isolation: thread: timeoutInMillisecond: 6000 # 熔断超时时长:6000ms