Zuul网关入门实战

一、入门项目搭建

eureka-server 的搭建参考我的笔记: Eureka 高可用服务集群搭建

1. zuul-server 搭建

  • 引入 spring-cloud-starter-netflix-zuul
java 复制代码
<?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.10.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>zuul-server</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>

    <dependencies>

        <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>

    </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>
  • 配置 application.properties
java 复制代码
server.port=9091
# 注册中心地址
eureka.client.service-url.defaultZone=http://admin:123@ek1.com:7901/eureka/,http://admin:123@ek2.com:7902/eureka/
#
# 客户端在注册中心中的名称
eureka.instance.instance-id=zuul-server-9091
#
# 当前服务对外暴露的名称
spring.application.name=zuul-server
#
  • 添加 @EnableZuulProxy 注解
java 复制代码
@SpringBootApplication
@EnableZuulProxy
public class ZuulTestApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulTestApplication.class, args);
    }
}

2. zuul-provider 搭建

  • pom.xml 添加
java 复制代码
<?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.10.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>zuul-provider</artifactId>
    <version>0.0.1-SNAPSHOT</version>


    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>

    <dependencies>

        <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>

    <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>
  • application.properties 设置
java 复制代码
server.port=9191
#
# ????
eureka.client.service-url.defaultZone=http://admin:123@ek1.com:7901/eureka/,http://admin:123@ek2.com:7902/eureka/
#
# 客户端在注册中心中的名称
eureka.instance.instance-id=zuul-provider-9191
#
# 设置当前 client 每5秒向 server 发送一次心跳,默认 30s
eureka.instance.lease-renewal-interval-in-seconds=5
#
# 表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance,默认为90秒
eureka.instance.lease-expiration-duration-in-seconds=90
#
# 当前服务名称
spring.application.name=zuul-provider
#
# 表示将自己的ip注册到Eureka Server上。不配置,表示将操作系统的 hostname 注册到server
eureka.instance.prefer-ip-address=true
#
#
# 对外开放所有监控端点
management.endpoints.web.exposure.include=*
#
# 是否将自己注册到其他Eureka Server,默认为true
eureka.client.register-with-eureka=true
#
# 是否从eureka server获取注册信息, 需要
eureka.client.fetch-registry=true
  • 添加服务接口
java 复制代码
@RestController
@RequestMapping("/zuul-pro")
public class ZuulProviderController {

    private final static Logger log = LoggerFactory.getLogger(ZuulProviderController.class);

    @Value("${server.port}")
    private String serverPort;

    @GetMapping("/get-port-01")
    public String getUserList() {
        return "zuul-provider:" + serverPort;
    }
}
  • 添加启动类
java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class ZuulProviderApplication {

    public static void main(String[] args) {
        SpringApplication.run(ZuulProviderApplication.class, args);
    }
}

3. zuul-consumer 搭建

  • pom.xml引入
java 复制代码
<?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.10.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>zuul-consumer-01</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>

    <dependencies>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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-openfeign</artifactId>
        </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>
  • application.properties 配置
java 复制代码
server.port=9291
# 注册中心地址
eureka.client.service-url.defaultZone=http://admin:123@ek1.com:7901/eureka/,http://admin:123@ek2.com:7902/eureka/
#
# 客户端在注册中心中的名称
eureka.instance.instance-id=zuul-consumer-9291
#
# 设置当前 client 每5秒向 server 发送一次心跳,默认 30s
eureka.instance.lease-renewal-interval-in-seconds=5
#
# 表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance,默认为90秒
eureka.instance.lease-expiration-duration-in-seconds=90
#
# 当前服务对外暴露的名称
spring.application.name=zuul-consumer
#
# 表示将自己的ip注册到Eureka Server上。不配置,表示将操作系统的 hostname 注册到 server
eureka.instance.prefer-ip-address=true
#
# 是否将自己注册到其他Eureka Server
eureka.client.register-with-eureka=true
#
# 是否从eureka server获取注册信息
eureka.client.fetch-registry=true
#
# 表示eureka client间隔多久去拉取服务注册信息,默认为30秒,如果要迅速获取服务注册状态,可以缩小该值,比如5秒
eureka.client.registry-fetch-interval-seconds=5
#
# 设置 ribbon 和服务注册中心Eureka一起工作,ribbon 可以从服务注册中心获取服务端的地址信息
ribbon.eureka.enabled=true
#
# 配置负载均衡策略,这里配置了随机访问
zuul-provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
  • 服务接口
java 复制代码
@RestController
@RequestMapping("/zuul-con")
public class ZuulConsumerController01 {

    @Value("${server.port}")
    private String serverPort;

    @Resource
    private ZuulConsumerService01 zuulConsumerService01;

    @GetMapping("/ajax-get-port-01")
    public String ajaxGetPort() {
        String resServerPort = zuulConsumerService01.getServerPort();
        return "zuul-consumer-01:" + serverPort + "---->>" + resServerPort;
    }
}

// 调用 zuul-provider 服务接口
@FeignClient(value = "zuul-provider/zuul-pro")
public interface ZuulConsumerService01 {

    @GetMapping("/get-port-01")
    String getServerPort();
}
  • 启动类配置
java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
// 开启 Feign 客户端,指定service接口所在的包
@EnableFeignClients(basePackages = "com.example.zuul.consumer01.service")
public class ZuulConsumer01Application {

    public static void main(String[] args) {
        SpringApplication.run(ZuulConsumer01Application.class, args);
    }
}

4. 测试

依次启动 EurekaServerZuulProviderApplicationZuulConsumer01ApplicationZuulTestApplication 应用

  • 访问消费者接口

http://localhost:9291/zuul-con/ajax-get-port-01

4.1 通过zuul网关访问

  • 网关的访问方式

通过zuul访问服务的,URL默认格式为:http://zuulHostIp:port/要访问的服务名称/服务中的URL

服务名称:properties配置文件中的spring.application.name

服务的URL:就是对应的服务对外提供的URL路径监听

在本文的案例中的URL路径就是:http://localhost:9091/zuul-consumer/zuul-con/ajax-get-port-01

二、负载均衡

Zuul 网关通过统一请求路径:http://localhost:9091/zuul-consumer/zuul-con/ajax-get-port-01 访问服务,服务配置负载均衡访问服务提供者,新增两个应用

1. zuul-provider-02

  • pom.xml 配置
java 复制代码
<?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.10.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>zuul-provider-02</artifactId>
    <version>0.0.1-SNAPSHOT</version>


    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>

    <dependencies>

        <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>

    <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>
  • application.properties 配置
java 复制代码
server.port=9192
#
# ????
eureka.client.service-url.defaultZone=http://admin:123@ek1.com:7901/eureka/,http://admin:123@ek2.com:7902/eureka/
#
# 客户端在注册中心中的名称
eureka.instance.instance-id=zuul-provider-9192
#
# 设置当前 client 每5秒向 server 发送一次心跳,默认 30s
eureka.instance.lease-renewal-interval-in-seconds=5
#
# 表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance,默认为90秒
eureka.instance.lease-expiration-duration-in-seconds=90
#
# 当前服务名称
spring.application.name=zuul-provider
#
# 表示将自己的ip注册到Eureka Server上。不配置,表示将操作系统的 hostname 注册到server
eureka.instance.prefer-ip-address=true
#
#
# 对外开放所有监控端点
management.endpoints.web.exposure.include=*
#
# 是否将自己注册到其他Eureka Server,默认为true
eureka.client.register-with-eureka=true
#
# 是否从eureka server获取注册信息, 需要
eureka.client.fetch-registry=true
  • 提供接口
java 复制代码
@RestController
@RequestMapping("/zuul-pro")
public class ZuulProviderController02 {

    private final static Logger log = LoggerFactory.getLogger(ZuulProviderController02.class);

    @Value("${server.port}")
    private String serverPort;

    @GetMapping("/get-port-01")
    public String getUserList() {
        return "zuul-provider-02:" + serverPort;
    }

}
  • 启动类
java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
public class ZuulProvider02Application {

    public static void main(String[] args) {
        SpringApplication.run(ZuulProvider02Application.class, args);
    }
}

2. zuul-consumer-02

  • pom.xml引入
java 复制代码
<?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.10.RELEASE</version>
        <relativePath/>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>zuul-consumer-02</artifactId>
    <version>0.0.1-SNAPSHOT</version>

    <properties>
        <java.version>8</java.version>
        <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
    </properties>

    <dependencies>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</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-openfeign</artifactId>
        </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>
  • application.properties配置
java 复制代码
server.port=9292
# 注册中心地址
eureka.client.service-url.defaultZone=http://admin:123@ek1.com:7901/eureka/,http://admin:123@ek2.com:7902/eureka/
#
# 客户端在注册中心中的名称
eureka.instance.instance-id=zuul-consumer-9292
#
# 设置当前 client 每5秒向 server 发送一次心跳,默认 30s
eureka.instance.lease-renewal-interval-in-seconds=5
#
# 表示eureka server至上一次收到client的心跳之后,等待下一次心跳的超时时间,在这个时间内若没收到下一次心跳,则将移除该instance,默认为90秒
eureka.instance.lease-expiration-duration-in-seconds=90
#
# 当前服务对外暴露的名称
spring.application.name=zuul-consumer
#
# 表示将自己的ip注册到Eureka Server上。不配置,表示将操作系统的 hostname 注册到 server
eureka.instance.prefer-ip-address=true
#
# 是否将自己注册到其他Eureka Server
eureka.client.register-with-eureka=true
#
# 是否从eureka server获取注册信息
eureka.client.fetch-registry=true
#
# 表示eureka client间隔多久去拉取服务注册信息,默认为30秒,如果要迅速获取服务注册状态,可以缩小该值,比如5秒
eureka.client.registry-fetch-interval-seconds=5
#
# 设置 ribbon 和服务注册中心Eureka一起工作,ribbon 可以从服务注册中心获取服务端的地址信息
ribbon.eureka.enabled=true
#
# 配置负载均衡策略,这里配置了随机访问
zuul-provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
  • 服务接口
java 复制代码
@RestController
@RequestMapping("/zuul-con")
public class ZuulConsumerController02 {

    @Value("${server.port}")
    private String serverPort;

    @Resource
    private ZuulConsumerService02 zuulConsumerService02;

    @GetMapping("/ajax-get-port-01")
    public String ajaxGetPort() {
        String resServerPort = zuulConsumerService02.getServerPort();
        return "zuul-consumer-02:" + serverPort + "---->>" + resServerPort;
    }
}


@FeignClient(value = "zuul-provider/zuul-pro")
public interface ZuulConsumerService02 {

    @GetMapping("/get-port-01")
    String getServerPort();
}
  • 启动类
java 复制代码
@SpringBootApplication
@EnableDiscoveryClient
// 开启 Feign 客户端,指定service接口所在的包
@EnableFeignClients(basePackages = "com.example.zuul.consumer02.service")
public class ZuulConsumer02Application {

    public static void main(String[] args) {
        SpringApplication.run(ZuulConsumer02Application.class, args);
    }
}

3. 测试

依次启动 EurekaServerZuulProviderApplication ZuulProvider02ApplicationZuulConsumer01ApplicationZuulConsumer02ApplicationZuulTestApplication 应用

  • 第一次请求网关

  • 第二次请求网关

  • 第三次请求网关

三、配置服务访问路径

通过 Zuul 网关访问服务时,URL默认格式为:***http://zuulHostIp:port/要访问的服务名称/服务中的URL***, 这个访问路径中直接就把咱们访问的服务名称暴露出去了,为了避免这个问题,我们可以在 zuul-server 服务中进行配置

  • application.properties 中新增配置
java 复制代码
#
# 指定网关访问的服务的路径,zuul-consumer 是访问的服务名称
zuul.routes.zuul-consumer=/test/**

此时访问 http://localhost:9091/zuul-consumer/zuul-con/ajax-get-port-01 的效果等同于 http://localhost:9091/test/zuul-con/ajax-get-port-01

1. 如何禁止通过服务名称访问

http://localhost:9091/zuul-consumer/zuul-con/ajax-get-port-01 如何禁止这个路径的访问呢?此时应该在 application.properties文件中新增如下配置

java 复制代码
#
# 禁止通过服务名称访问
zuul.ignored-services=zuul-consumer

2. 如何访问路径增加统一访问前缀

application.properties文件中新增如下配置

java 复制代码
#
# 网关统一前缀
zuul.prefix=/api/v1
#
# 网关统一前缀是否生效;true - 是 false - 否
zuul.strip-prefix=true

此时再通过 http://localhost:9091/test/zuul-con/ajax-get-port-01 访问失败

相关推荐
2401_895521346 小时前
SpringBoot Maven快速上手
spring boot·后端·maven
disgare6 小时前
关于 spring 工程中添加 traceID 实践
java·后端·spring
ictI CABL6 小时前
Spring Boot与MyBatis
spring boot·后端·mybatis
小江的记录本8 小时前
【Linux】《Linux常用命令汇总表》
linux·运维·服务器·前端·windows·后端·macos
yhole11 小时前
springboot三层架构详细讲解
spring boot·后端·架构
香香甜甜的辣椒炒肉11 小时前
Spring(1)基本概念+开发的基本步骤
java·后端·spring
白毛大侠12 小时前
Go Goroutine 与用户态是进程级
开发语言·后端·golang
ForteScarlet12 小时前
从 Kotlin 编译器 API 的变化开始: 2.3.20
android·开发语言·后端·ios·开源·kotlin
橘子编程12 小时前
OpenClaw(小龙虾)完整知识汇总
java·前端·spring boot·spring·spring cloud·html5
大阿明12 小时前
SpringBoot - Cookie & Session 用户登录及登录状态保持功能实现
java·spring boot·后端