Zuul简介
路由在微服务体系结构的一个组成部分。例如,/可以映射到您的Web应用程序,/api/users映射到用户服务,并将/api/shop映射到商店服务。Zuul是Netflix的基于JVM的路由器和服务器端负载均衡器。
Zuul有以下功能
- 认证(Authentication)
- 洞察(Insights)
- 压力测试(Stress Testing)
- 金丝雀测试(Canary Testing)
- 动态路由(Dynamic Routing)
- 服务迁移(Service Migration)
- 负载脱落(Load Shedding)
- 安全(Security)
- 静态响应处理(Static Response handling)
- 主动/主动流量管理(Active/Active traffic management)
创建zuul工程
创建service-zuul的Modules 依赖如前几篇一样:
<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>service-zuul</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>service-zuul</name>
<description>Demo project for Spring Boot</description>
<!-- 指定父pom -->
<parent>
<groupId>com.example</groupId>
<artifactId>springcloud</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<kotlin.version>1.2.20</kotlin.version>
<spring-cloud.version>Edgware.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-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>
<sourceDirectory>${project.basedir}/src/main/kotlin</sourceDirectory>
<testSourceDirectory>${project.basedir}/src/test/kotlin</testSourceDirectory>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>kotlin-maven-plugin</artifactId>
<groupId>org.jetbrains.kotlin</groupId>
<version>${kotlin.version}</version>
<configuration>
<args>
<arg>-Xjsr305=strict</arg>
</args>
<compilerPlugins>
<plugin>spring</plugin>
</compilerPlugins>
<jvmTarget>1.8</jvmTarget>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
<dependencies>
<dependency>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-allopen</artifactId>
<version>${kotlin.version}</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</build>
</project>
- 在入口类中增加
@EnableZuulProxy
,进行开启zuul功能
@EnableZuulProxy
@EnableEurekaClient
@SpringBootApplication
class ServiceZuulApplication
fun main(args: Array<String>) {
SpringApplication.run(ServiceZuulApplication::class.java, *args)
}
- 在配置文件中进行配置如下:
eureka.client.service-url.defaultZone= http://localhost:8761/eureka/
server.port=8770
spring.application.name=service-zuul
zuul.routes.api-a.path=/api-a/**
zuul.routes.api-a.serviceId=service-ribbon
zuul.routes.api-b.path=/api-b/**
zuul.routes.api-b.serviceId=service-feign
配置文件解析如下:
1. 首先指定服务注册中心 http://localhost:8761/eureka/
2. 服务端口号8770
3. 服务名为service-zuul
4. /api-a/ 开头的请求都转发给service-ribbon服务
5. /api-b/ 开头的请求都转发给service-feign服务
接下来 启动所有项目 :
- 可以使用http://localhost:8770/api-a/hi?name=houshuai 来访问service-ribbon服务
- 可以使用http://localhost:8770/api-b/hi?name=houshuai 来访问service-feign服务
服务过滤
zuul不仅仅只是路由,而且还能进行过滤,做一些安全验证。
@Component
class MyFilter: ZuulFilter() {
companion object {
private val log =LoggerFactory.getLogger(MyFilter::class.java)
}
override fun run(): Any? {
val currentContext = RequestContext.getCurrentContext()
val request = currentContext.request
log.info("${request.method} >>> ${request.requestURL}")
val accessToken = request.getParameter("token")
if (accessToken == null) {
log.warn("token is empty")
currentContext.setSendZuulResponse(false)
currentContext.responseStatusCode = 401
try {
currentContext.response.writer.write("token is empty")
} catch (e: Exception) {
}
return null
}
log.info("ok")
return null
}
override fun shouldFilter(): Boolean {
return true
}
override fun filterType(): String {
return "pre"
}
override fun filterOrder(): Int {
return 0
}
}
filterType:返回一个字符串代表过滤器的类型。因此不同类型的过滤器代表不同的生命周期的一环。
- pre: 路由之前
- routing:路由之时
- post: 路由之后
- error: 发送错误调用
filterOrder:过滤顺序
shouldFilter:这里可以写判断逻辑,是否过滤。为true代表永远过滤。
run: 过滤器的具体逻辑,可以很复杂的操作。
示例代码:
https://github.com/houshuai0816/SpringCloudDemo