Zuul是Netflix OSS中的一员,是个基于 JVM 路由和服务端的负载均衡器。提供路由、监控、弹性、安全等方面的服务框架。Zuul能够与Eureka、Ribbon、Hystrix等组件配合使用。
Zuul的核心是过滤器,通过这些过滤器我们可以扩展出很多功能,比如:
主要在父工程的pom.xml中确定整个微服务spring boot和spring cloud的版本
<dependencyManagement>
<dependencies>
<!--spring boot 2.2.2-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.2.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--spring cloud Hoxton.SR1-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
pom.xml文件的主要依赖
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<!-- SpringCloud Hystrix 微服务容错监控组件:断路器,依赖隔离,服务降级,服务监控 依赖 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.yml
spring:
application:
name: eurekaServer
server:
port: 8761
eureka:
server:
# 关闭自我保护机制,防止失效的服务也被一直访问 (Spring Cloud默认该配置是 true)
enable-self-preservation: true
# 每隔10s扫描服务列表,该配置可以修改检查失效服务的时间,每隔10s检查失效服务,并移除列表 (Spring Cloud默认该配置是 60s)
eviction-interval-timer-in-ms: 10000
instance:
hostname: ${spring.cloud.client.ip-address}
#该实例,相较于hostname是否优先使用IP
prefer-ip-address: true
#该实例注册到服务中心的唯一ID
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
client:
#关闭eureka的客户端行为:注册服务
registerWithEureka: false
#关闭eureka的客户端行为:订阅服务
fetchRegistry: false
#与Eureka注册服务中心的通信zone和url地址
instance-info-replication-interval-seconds: 30 #间隔多长时间再次复制实例信息到eureka服务器,默认为30秒
serviceUrl:
#eureka注册中心地址
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
创建启动类
@SpringBootApplication
@EnableEurekaServer
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class,args);
}
}
pom.xml文件主要如下:
<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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
application.yml
server:
port: 8010
servlet:
context-path: /provide
spring:
application:
name: provideServer
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true
instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
创建启动类
@SpringBootApplication
@EnableEurekaClient
public class ProvideApplicaiton {
public static void main(String[] args) {
SpringApplication.run(ProvideApplicaiton.class,args);
}
}
pom.xml文件的主要依赖
<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>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<scope>true</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
当以/provideServer开头的路径访问网关时,会自动转发到服务Id为provideServer的服务上
实现相同的功能可以简化配置如下
进一步简化如下
1、在默认情况,给服务提供者开启多个实例,zuul会使用eureka集成的负载均衡功能。已循环的方式转到每个实例
2、使用Ribbon的负载均衡功能
使用Ribbon的负载均衡功能需要指定一个serviceId,此操作需要禁止Ribbon使用Eureka。ribbon有多种负载均衡策略可以选择。以下选择了随机选择Server策略。
ribbon有七种负载均衡策略如下图所示
访问http://localhost:8040/forwardTest/hello,匹配到routeC路由,截取到orwardTest后,将后面的hello拼接到forward:/test后,生成访问url:http://localhost:8040/test/hello,跳转访问本地资源。单实例url跳转同理。
如下,有相同的映射路径指定转发到不同的url,经过测试,总会路由到yml配置文件后面的那个url,如下图访问http://localhost:8040/forwardTest/hello可以返回hello forward。而将routeC和routeD对调下,则返回404。
在yml解释器工作的时候,如果同一个映射路径对应多个服务,按照加载顺序,最末加载的映射规则会把之前的映射规则覆盖掉
在配置路由规则的时候,我们可以配置可以统一的代理前缀
访问http://localhost:8040/prefix/forwardTest/hello,当stripPrefix为false,此时转发的地址为http://localhost:8040/test/forwardTest/hello
访问http://localhost:8040/prefix/forwardTest/hello,当stripPrefix为true,此时转发的地址为http://localhost:8040/test/hello
1、服务屏蔽
在使用zuul进行路由配置时,经常会添加或修改路由。通过zuul的两个智能端点routes、filters可以对路由和过滤信息进行查看,还可以更新路由。
zuul默认路由根据服务名加路由API,不需配置zuul路由即可访问到接口,这样会将所有的接口都暴露出来。虽然方便性较高但安全性低。zuul.ignoredServices=* 表示禁用默认路由,只认我们自己配置的路由.
禁用指定服务
2、路径屏蔽
屏蔽掉包含provideServer的路径
屏蔽以/prefix/provideServer开头的路径
sensitiveHeaders:会过滤客户端请求中的和该配置项匹配的headers,如果客户端在发请求是带了x-myHeader,那么x-myHeader不会传递给下游服务
ignoredHeaders:会过滤服务之间通信附带的headers,如果客户端在发请求是带了x-myHeader,那么x-myHeader依然会传递给下游服务。但是如果下游服务再转发就会被过滤,比如feign