1. 路由知识
有关网关的很多知识我们都在04.gateway讲解了,有关网关的详细知识可以到上节详细了解。本节我们主要来讲解下另一个网关zuul
。本节结合之前的章节网关搭建的项目案例上实现zuul的搭建,侧重于实战。
2. Zuul现状
zuul官方文档
zuul截止cloud的 H.SR12 版本之后就彻底从官网移除了,假如你这时候还想使用zuul,需要注意cloud版本,springboot版本也需要注意,不可以高于2.3.12.RELEASE。
3. 入门实战
网关有一个功能是负载均衡,要实现负载均衡功能就需要先进行服务注册中心的搭建,多个服务实例注册到服务注册中心才能形成服务注册列表,负载均衡才有意义。但服务注册中心并不是必须的,毕竟网关的作用并不止负载均衡。注册中心有:nacos、eureka。案例中使用eureka进行,eureka比较方便,并不需要进行客户端下载,使用nacos之前需要先下载对应的nacos客户端。
1)创建eureka注册中心
在我之前的博客中已经详细介绍了搭建的过程,原文链接:https://blog.csdn.net/m0_53951384/article/details/135473214
网关跟注册中心没有直接关联,可以只配置网关,不配置注册中心。本节课程是基于链接实现的注册中心案例继续的,所以先实现注册中心的搭建再往下进行。
eureka注册中心搭建和网关搭建很简单,但是需要有服务注册和服务提供才能看出网关和注册中心的作用,这些一起写了就显得比较繁琐。
2)创建SpringBoot项目
注意选择Cloud Bootstrap
,该项目才会引入SpringCloud相关依赖。
创建名为【zuul-server】的服务。
3) 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 https://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.3.12.RELEASE</version><relativePath/> <!-- lookup parent from repository --></parent><groupId>com.lzk</groupId><artifactId>zuul-server</artifactId><version>0.0.1-SNAPSHOT</version><name>zuul-server</name><description>zuul-server</description><properties><java.version>8</java.version><spring-cloud.version>Hoxton.SR1</spring-cloud.version></properties><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><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></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build></project>
4)配置文件
spring:application:name: zuul-gateway
eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka
server:port: 9527
5)启动类
在启动类上添加以下两个注解
@EnableEurekaClient
:将zuul注册到注册中心上@EnableZuulProxy
:开启网关代理
6)访问
没有添加网关的时候访问订单服务接口:
添加网关后,可以通过网关访问订单服务接口:相当于在用户访问订单服务前增加了一层,但是这一层目前什么事情都没有做。
由于Zuul自动集成了Ribbon,所以Zuul天生就有负载均衡,我们刷新一次就会发现8080-> 8081
4. zuul配置
1) 路由配置
zuul在不添加配置的情况下,默认就是允许通过服务名称来调用其他服务的,就像我们上面访问http://localhost:9527/orderservice/order/info
一样,zuul也可以指定url来访问。
zuul:routes:orders: # orders是自己定义的路由名称,可以配置多个path: /order/**url: orderservice #注册进eureka服务器的服务名称,也可写成http://127.0.0.1:8083,不过这种写法请求就只发向一8081端口
2) 关闭服务名称访问
既然我已经自定义了路由地址,那么我不希望再通过服务名称来访问,可以通过下面的配置关闭服务名称访问:
zuul:ignored-services: orderservice #关闭服务名称查询
可以指定关闭具体的服务名称访问,也可以用 *
代表全部。
zuul:ignored-services: "*"
3) 统一公共前缀
zuul:prefix: /lzk
添加完统一公共前缀后请求必须加上前缀,否则请求会报404
未添加公共前缀前,下面请求可以访问到,现在报404
加上前缀访问:
需要注意:假如设置为zuul的时候,添加zuul前缀访问也会404
zuul:prefix: /zuul
分析:
- 配置完zuul网关,默认的
context-path
是/zuul。 - 在默认的情况下我们不加/zuul也可以请求成功是因为它帮我们做了url的裁剪。
简单点说在不加zuul.prefix=/zuul
配置的情况下,以下两个url都可以请求成功
- http://localhost:9527/order/order/info
- http://localhost:9527/zuul/order/order/info
解决:
- 将默认
context-path
设置为空:zuul.servlet-path=/
- 配置网关zuul的统一前缀:
zuul.prefix=/zuul
zuul:prefix: /zuulservlet-path: /
设置完之后就必须通过前缀/zuul可以访问,不加前缀就访问不了
4)指定路由不设置前缀
zuul:ignored-services: orderserviceprefix: /lzkroutes:orders:path: /order/**url: orderservicestrip-prefix: falseservlet-path: /
prefix是设置全局的前缀,stripPrefix是针对单个路由是否要用前缀访问的设置,默认是true,这个是官网也有说明,但是问题是当设置为false的时候不管设置不设置前缀访问都是404,我认为是版本bug。开始测完访问不到我认为可能是servlet-path
默认为zuul有问题,但即使设置为/还是不行,但区别就是设置为/
后页面不报404,但后台还是显示路由不了。
5)超时时间设置
如果您使用@EnableZuulProxy,则可以使用代理路径上传文件,只要文件很小,它应该可以工作。对于大文件接口访问慢,这时候需要设置超时时间,如下:
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
ribbon:ConnectTimeout: 3000ReadTimeout: 60000
如果你想通过 Zuul 代理的请求,配置套接字超时和读取超时,有下面选项:
zuul:host:connect-timeout-millis: 40000socket-timeout-millis: 40000connection-request-timeout-millis: 40000
一些常用配置:
zuul.host.connect-timeout-millis=40000
zuul.host.socket-timeout-millis=40000
zuul.host.connection-request-timeout-millis=40000
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=40000
ribbon.ReadTimeout=10000
ribbon.ConnectTimeout=10000
5. zuul过滤器
过滤器可以对请求进行额外的处理,在gateway中也介绍过过滤器,还有自定义过滤器。
1) 自定义 Zuul 过滤器
过滤类型:
- pre: 在请求被路由到目标服务前执行,比如权限校验、打印日志等功能;
- routing: 在请求被路由到目标服务时执行
- post: 在请求被路由到自标服务后执行,比如给目标服务的响应添加头信息,收集统计数据等功能;
- error: 请求在其他阶段发生错误时执行。
@Component
@Slf4j
public class PreLogFilter extends ZuulFilter {// 请求类型@Overridepublic String filterType() {return "pre";}// 假如多个过滤器,会根据这个数字来进行排序执行@Overridepublic int filterOrder() {return 1;}// 过滤器是否开启@Overridepublic boolean shouldFilter() {return true;}// 执行自己的业务逻辑@Overridepublic Object run() {RequestContext requestContext = RequestContext.getCurrentContext();HttpServletRequest request = requestContext.getRequest();String host = request.getRemoteHost();String method = request.getMethod();String uri = request.getRequestURI();log.info("=====> Remote host:{},method:{},uri:{}", host, method, uri);System.out.println("********" + System.currentTimeMillis());return null;}
}
请求发起的时候控制台会打印对应的日志详情。
通过配置文件当中,可以关闭过滤器,过滤器的名字PreLogFilter
就是我们上面自定义的。
zuul:PreLogFilter:pre:disable: true # 关闭前置过滤器
关闭后控制台不会打印对应的日志信息。
ZuulFilter中还有很多子类供我们进行过滤处理
文章参考:https://blog.csdn.net/weixin_43888891/article/details/126445571