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 访问失败

相关推荐
Estar.Lee3 小时前
查手机号归属地免费API接口教程
android·网络·后端·网络协议·tcp/ip·oneapi
2401_857610035 小时前
SpringBoot社团管理:安全与维护
spring boot·后端·安全
凌冰_5 小时前
IDEA2023 SpringBoot整合MyBatis(三)
spring boot·后端·mybatis
码农飞飞5 小时前
深入理解Rust的模式匹配
开发语言·后端·rust·模式匹配·解构·结构体和枚举
一个小坑货5 小时前
Rust 的简介
开发语言·后端·rust
monkey_meng6 小时前
【遵守孤儿规则的External trait pattern】
开发语言·后端·rust
Estar.Lee6 小时前
时间操作[计算时间差]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Grey_fantasy7 小时前
高级编程之结构化代码
java·spring boot·spring cloud
新知图书7 小时前
Rust编程与项目实战-模块std::thread(之一)
开发语言·后端·rust
盛夏绽放7 小时前
Node.js 和 Socket.IO 实现实时通信
前端·后端·websocket·node.js