Spring Cloud Zuul的URL转发和路由规则

文章目录
  1. 1. Spring Cloud Zuul
  2. 2. 快速搭建SC Zuul
    1. 2.1. Spring Cloud Zuul原始的URL转发功能
      1. 2.1.1. URL路由转发功能
      2. 2.1.2. URL路由转发功能测试
  3. 3. Spring Cloud Zuul功能
    1. 3.1. Spring Cloud Zuul功能案例
    2. 3.2. Spring Cloud Zuul功能演示
  4. 4. Spring Cloud Zuul路由规则
    1. 4.1. 指定服务路由对外访问路径

摘要:最近开了《跟我学Spring Cloud》系列教程,由于最近比较忙,因此更新较慢。由于自己最近在研究基于Netty名为Janus的网关中间件分为janus-Server端和janus-console管控端,纳管Spring Cloud实现市面上网关85%以上的功能,将在2017年5月6号Spring Cloud中国社区北京技术沙龙分享。顺便抽时间把Spring Cloud Zuul相关的东西整理比较。在本篇文章中Spring Cloud的版本更换为Dalston.RELEASE,Spring Boot的版本为1.5.2.RELEASE。

Spring Cloud Zuul

Spring Cloud Zuul 通过与 Spring Cloud Eureka 进行整合,将自身注册到 Eureka Server中,与Eureka,Ribbon,Hystrix等整合,同时从 Eureka 中获得了所有其它微服务的实例信息。这样的设计通过把网关和服务治理整合到一起,Spring Cloud Zuul可以获取到服务注册信息,结合Ribbon,Hystrix等更好的实现路由转发,负载均衡等功能。想了解更多的内容,可以参考下面的中英文对照翻译文档。或者查看官网文档。
Spring Cloud Zuul中英文对照翻译① Spring Cloud Zuul中英文对照翻译② Spring Cloud Zuul中英文对照翻译③

Janus网关

快速搭建SC Zuul

工程目录如下图所示:

工程目录

Code地址:https://github.com/SoftwareKing/spring-cloud-study/tree/master/sc-zuul-first

Spring Cloud Zuul原始的URL转发功能

由于sc-zuul-first-provider1的代码极其简单就是一个简单的服务提供者,因此不做过多介绍。下面主要介绍sc-zuul-first-zuul-no-eureka这个工程,

URL路由转发功能

  1. 创建名为sc-zuul-first-zuul-no-eureka的maven工程,添加依赖,但注意的是该工程只有Zuul的依赖。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    <?xml version="1.0"?>
    <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.xujin.sc</groupId>
    <artifactId>sc-zuul-first-zuul-no-eureka</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sc-zuul-first-zuul-no-eureka</name>
    <url>http://maven.apache.org</url>
    <!-- 引入spring boot的依赖 -->
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.2.RELEASE</version>
    </parent>
    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <java.version>1.8</java.version>
    </properties>
    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zuul</artifactId>
    </dependency>
    </dependencies>
    <!-- 引入spring cloud的依赖 -->
    <dependencyManagement>
    <dependencies>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-dependencies</artifactId>
    <version>Dalston.RELEASE</version>
    <type>pom</type>
    <scope>import</scope>
    </dependency>
    </dependencies>
    </dependencyManagement>
    <!-- 添加spring-boot的maven插件 -->
    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>
    </project>

    说明: 对于 spring-cloud-starter-zuul 依赖,我们可以通过查看它的依赖内容了解 到:该模块中不仅包含了 Netflix Zuul 的核心依赖 zuul-core,它还包含了下面这 些网关服务需要的重要依赖。
    spring-cloud-starter-hystrix:该依赖用来在网关服务中实现对微服务 转发时候的保护机制,通过线程隔离和断路器,防止微服务的故障引发 API 网关 资源无法释放,从而影响其他应用的对外服务。
    spring-cloud-starter-ribbon:该依赖用来实现在网关服务进行路由转发 时候的客户端负载均衡以及请求重试。
    spring-boot-starter-actuator :该依赖用来提供常规的微服务管理端点。另外,在Spring Cloud Zuul中还特别提供了/routes 端点来返回当前的所有路由规则。

2.主入口程序代码如下,使用@EnableZuulProxy注解

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package org.xujin.sc.zuul.first.zuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulServer;
@SpringBootApplication
@EnableZuulProxy
public class SpringCloudZuulApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudZuulApplication.class, args);
}
}

3.application.yml配置文件信息如下

1
2
3
4
5
server.port=8041
spring.application.name=sc-zuul-first-zuul-no-eureka
zuul.routes.api-url.path=/api-url/**
zuul.routes.api-url.url=http://localhost:8000/

该配置定义了发往 API 网关服务的请求中,所有符合/api-url/**规则的访问都 将 被 路 由 转 发 到 http://localhost:8000/ 地 址 上 , 也 就 是 说 当 我 们 访 问 http://localhost:8041/api-url/sc/order/1 可以正常的把请求的url转发到http://localhost:8000/sc/order/2 。其 中 , 配 置 属 性 zuul.routes.api-url.path 中的 api-url 部分为路由的名字,可以任意定义, 但是一组 path 和 url 映射关系的路由名要相同。

zuul.routes.api-url.url=http://localhost:8000/ 这个配置了服务提供者sc-zuul-first-provider1的URL

4.测试依次按如下顺序,把各个服务启动。
注册中心为:sc-zuul-first-eureka-server 服务提供者为:sc-zuul-first-provider1,sc-zuul-first-provider2
启动sc-zuul-first-zuul-no-eureka 上述Server启动之后,测试Case:

URL路由转发功能测试

1.当注解为@EnableZuulProxy时,测试转发。通过访问网关的URL: http://localhost:8041/api-url/sc/order/1 可以正常的把请求的url转发到http://localhost:8000/sc/order/2

网关URL转发Debug

Tips:断点跳过之后,返回结果如下,说明当使用@EnableZuulProxy注解的时候,Zuul具有URL转发调用的功能。

网关URL转发

2.关闭sc-zuul-first-zuul-no-eureka对应的服务,把主应用程序中的注解@EnableZuulProxy变为@EnableZuulServer,按第1步启动sc-zuul-first-zuul-no-eureka服务,测试。

换为@EnableZuulServer注解变为普通的Zuul Server

Tips: 可以看到上图返回结果为200,但是空白。那为什么会这样呢?后面专门对Zuul的源码分析,请读者忽略或自行查看源码。

Spring Cloud Zuul功能

大家知道Spring Cloud的服务治理的粒度是服务应用名,而如下的配置规则硬编码配置主机名和端口,由于Spring Cloud Zuul整合了Ribbon负载均衡器等因此,下面的配置方式不推荐使用比较low。

1
2
3
4
5
server.port=8041
spring.application.name=sc-zuul-first-zuul-no-eureka
zuul.routes.api-url.path=/api-url/**
zuul.routes.api-url.url=http://localhost:8000/

Spring Cloud Zuul功能案例

1.为了演示面向服务名为粒度的路由规则,新建了一个名为sc-zuul-first-zuul的工程,该工程与sc-zuul-first-zuul-no-eureka的最大的区别就是在pom.xml文件中,加入spring-cloud-starter-eureka依赖,如下注释所示。

1
2
3
4
5
6
7
8
9
10
11
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<!-- 多了eureka starter -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>

2.application.yml

1
2
3
4
5
6
7
8
9
10
11
server:
port: 8040
spring:
application:
name: sc-zuul-first-zuul
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
instance:
prefer-ip-address: true

3.主应用程序代码SpringCloudZuulApplication.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package org.xujin.sc.zuul.first.zuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
*
* @author xujin
* @EnableZuulProxy 声明一个Zuul 代理,该代理使用Ribbon软负载均衡,还整合Hystrix实现熔断
*/
@SpringBootApplication
@EnableZuulProxy
public class SpringCloudZuulApplication {
public static void main(String[] args) {
SpringApplication.run(SpringCloudZuulApplication.class, args);
}
}

4.分别依次把sc-zuul-first-eureka-server,sc-zuul-first-zuul,sc-zuul-first-provider1,
sc-zuul-first-provider2,sc-zuul-first-consumer,sc-zuul-first-hystrix-dashboard启动。
Eureka Server

Spring Cloud Zuul功能演示

1.网关的默认路由规则
说明默认情况下,Zuul会代理所有注册到Eureka Server的微服务,并且Zuul的路由规则如下:
http://ZUUL_HOST:ZUUL_PORT/微服务在Eureka上的serviceId/** 会被转发到serviceId对应的微服务。
http://localhost:8040/sc-zuul-first-provider/sc/order/2
默认路由规则
2.网关的负载均衡
http://localhost:8040/sc-zuul-first-provider/sc/order/2
通过网关访问服务提供者,负载均衡打出对应的日志

1
2
3
2017-04-30 18:35:37.502  INFO 3443 --- [nio-8000-exec-3] o.x.s.e.f.o.controller.OrderController  : Zuul路由到服务提供者①
2017-04-30 18:34:06.764  INFO 3444 --- [nio-8001-exec-4] o.x.s.e.f.o.controller.OrderController  : Zuul路由到服务提供者②
2017-04-30 18:35:37.251  INFO 3444 --- [trap-executor-0] c.n.d.s.r.aws.ConfigClusterResolver  : Resolving eureka endpoints via configuration

3.集成Hystrix
http://localhost:8040/hystrix.stream

Spring Cloud Zuul路由规则

指定服务路由对外访问路径

1
2
3
zuul:
routes:
sc-zuul-first-provider: /order/**

相当于把sc-zuul-first-provider映射为/order/**,访问http://localhost:8040/sc-zuul-first-provider/sc/order/2
可以等价于:http://localhost:8040/order/sc/order/2,其它路由规则,可以从官网文档中阅读尝试。

如果您觉得文章不错,可以打赏我喝一杯咖啡!