一、入门项目搭建
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. 测试
依次启动 EurekaServer
、ZuulProviderApplication
、ZuulConsumer01Application
和ZuulTestApplication
应用
- 访问消费者接口
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. 测试
依次启动 EurekaServer
、ZuulProviderApplication
、 ZuulProvider02Application
、ZuulConsumer01Application
、ZuulConsumer02Application
和ZuulTestApplication
应用
-
第一次请求网关
-
第二次请求网关
-
第三次请求网关
三、配置服务访问路径
通过 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 访问失败