一、简介

Zuul:springcloud提供请求过滤转发、负载均衡,的组件。

如果Consumer是集群状态默认进行负载均衡。

可以对请求进行过滤。

二、依赖

1、父项目 pom.xml

<properties>
        <maven.compiler.source>8</maven.compiler.source>
        <maven.compiler.target>8</maven.compiler.target>
        <java.version>1.8</java.version>
        <!-- springboot的版本 -->
        <spring-boot.version>2.3.2.RELEASE</spring-boot.version>
        <!-- springcloud的版本 -->
        <spring-cloud.version>Hoxton.SR9</spring-cloud.version>
        <!-- alibaba推出springcloud的对应版本 -->
        <spring-cloud-alibaba.version>2.2.6.RELEASE</spring-cloud-alibaba.version>
    </properties>
    <!-- 项目打包方式 -->
    <packaging>pom</packaging>
​
    <dependencyManagement>
        <dependencies>
            <!-- spring boot依赖 -->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring-boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- spring-cloud依赖 -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- alibaba推出的spring-cloud依赖的父依赖 -->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

2、zuul网关项目 pom.xml文件

<dependencies>
        <!-- springboot core -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <!-- springboot web -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- nacos客户端 -->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
            <version>2.2.6.RELEASE</version>
        </dependency>
        <!-- 网关zuul组件 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
        </dependency>
</dependencies>

三、zuul网关项目的配置文件(application.yml)

spring:
  application:
    name: test-provider
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
        username: nacos
        password: nacos
        # 所属的命名空间:填写的是命名空间id
        namespace: asidhasudh-2sada-8hjbahas
        # 所属命名空间的组名称
        group: user
# 数据源配置
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    url: jdbc:mysql://localhost:3306/market?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8&useSSL=false
    username: root
    password: root
    druid:
      driver-class-name: com.mysql.jdbc.Driver
​
# 配置zuul网关
zuul:
  routes:
    test-consumer: # consumer工程名(注册进注册中心的名字)
            # 匹配的路径(前缀和它相同的路径才会进行转发。**表示任意路径都可以)
            path: /test-consumer/** 
            strip-prefix: true # 转发时是否去掉匹配的前缀

四、zuul网关项目的启动类

@SpringBootApplication
// 启用注册中心客户端
@EnableDiscoveryClient
// 开启Zuul网关
@EnableZuulProxy
public class Gateapplication {
    public static void main(String[] args) {
        SpringApplication.run(Gateapplication.class,args);
    }
}

五、通过网关项目访问Consumer

比如:上面配置文件写的路径这样就可以把我们的请求转发到对应的服务器上了。

http://localhost:8080/test-consumer/hello

http://localhost:8080/test-consumer/order

......

六、网关过滤器(可以对请求进行过滤和拦截)

  1. 编写的过滤器类继承ZuulFilter类,添加@Component注解

  2. 过滤器类型:

    // 所有请求进来都会过滤执行的方法(预过滤方法)
    FilterConstants.PRE_TYPE;
    // 将要转发之前执行的过滤操作(完成匹配路由之后要进行转发时执行)
    FilterConstants.ROUTE_TYPE/FilterConstants.ROUTING_DEBUG_KEY;
    // 业务方法执行完之后要执行的方法
    FilterConstants.POST_TYPE;
    // 方法报错时要执行的方法执行完之后会跳到POST方法(注意POST方法不能报错否则会造成死循环)
    FilterConstants.ERROR_TYPE;
    ​
    // 执行顺序
    PRE → ROUTE     →  POST
              ↓    ↑    ↑
              target   error
  3. 同类型的过滤器,数越大级别越低

  4. 过滤器是否需要继续往下执行(是否执行后续的过滤方法)

1、一个完整的过滤器

/**
 * @Name 周稚林
 * @Data 2022-05-23-15:55
 **/
@Component
public class orderfilter extends ZuulFilter {
    // 设置过滤器类型
    @Override
    public String filterType() {
        return FilterConstants.ERROR_TYPE;
    }
​
    // 设置同类型过滤器的执行顺序(数越大级别越低)
    @Override
    public int filterOrder() {
        return 0;
    }
​
    // 获取是否能继续执行。
    @Override
    public boolean shouldFilter() {
        RequestContext ctx = RequestContext.getCurrentContext();
        return ctx.sendZuulResponse();
    }
​
    // 过滤器的执行内容
    @Override
    public Object run() throws ZuulException {
        // 获取请求的上下文
        RequestContext ctx = RequestContext.getCurrentContext();
        // 获取具体的请求
        HttpServletRequest request = ctx.getRequest();
        // 设置下个网关过滤器是否执行
        ctx.setSendZuulResponse(false);
        // 操作过滤器上下文属性
        ctx.set("username",false);
        ctx.get("username");
        
        // 设置过滤器返回的数据
        ctx.setResponseStatusCode(201); // 状态码
        // 返回的数据
        ctx.setResponseBody("{\"msg\": sdsdsdsfsdddddd}");
        return null;
    }
}