SpringCloud 整合 Zuul 实现服务网关路由,实战讲解!
一、背景介绍
在之前的文章中,我们陆续介绍了 Spring Cloud 技术体系中的 Eureka、Ribbon、Fegin、Hystrix、Config 等核心组件的作用和使用方式。
通过这些组件,基本可以构建一个简易版的微服务框架了,其交互流程可以用如下图来简要概括。

这种架构模式,初看好像没啥问题,但是当微服务越来越多的时候,会带来新的挑战。
例如需要配置的反向代理服务越来越多,这显然不符合微服务的归一理念;其次,接口权限管理难以维护,如果需要对某些微服务的接口做权限控制,只能一个一个的去迭代修改,开发和维护起来都很繁琐。
在这样的背景下,服务网关应运而生。
今天通过这篇文章,我们一起来了解一下 Spring Cloud 技术体系中一个重要的服务网关组件 Zuul。
二、Zuul 简介
Zuul 是 Netflix 开源的一个API Gateway 服务组件,也是 Spring Cloud Netflix 子项目的核心组件之一。它的主要职责就是作为接受外部请求的统一入口,并将收到的请求转发到具体的业务微服务上,为微服务框架提供了前门保护。
Zuul 除了提供服务路由、均衡负载等基础功能之外,开发者还可以利用它来实现权限控制、接口限流等功能。
引入 Zuul 之后,微服务框架的前置交互流程可以用如下图来简要概括。

下面我们通过具体的例子,看看如何使用 Zuul 来实现将服务请求进行转发的效果。
三、方案实践
3.1、构建服务网关
使用 Spring Cloud Zuul 来构建服务网关非常的简单,通过以下三步骤即可完成。
3.1.1、创建服务网关
首先创建一个 Spring Boot 工程,命名为eureka-zuul
,并在pom.xml
中引入 Zuul 依赖包,示例如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Edgware.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.1.2、开启服务网关功能
然后,创建一个服务启动类并添加@EnableZuulProxy
,表示开启 Spring Cloud Zuul 网关功能。
@EnableZuulProxy
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
3.1.3、配置服务注册中心
最后,在application.properties
中服务注册中心,示例如下:
spring.application.name=eureka-zuul
server.port=9030
# 设置与Eureka Server交互的地址,多个地址可使用【,】分隔
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
3.2、构建业务微服务
构建业务微服务同样简单,其本质就是一个 Eureka 客户端,通过以下三步骤即可完成。
3.2.1、创建业务微服务
创建一个 Spring Boot 工程,命名为eureka-consumer-order
,并在pom.xml
中引入相关的依赖内容,示例如下:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</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>Edgware.SR3</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
3.2.2、编写 web 接口
接着,创建一个服务启动类并添加@EnableDiscoveryClient
注解,表示当前是一个 Eureka 客户端服务。
@EnableEurekaServer
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
然后,创建一个 web 接口,以便等会测试请求转发的效果。
@RestController
public class HelloController {
@GetMapping("/hello")
public String index() {
return "hello,这是一个订单微服务";
}
}
3.2.3、配置服务注册中心
与上文一样,在application.properties
配置文件中,添加服务注册中心地址,示例如下:
spring.application.name=eureka-consumer-order
server.port=9022
# 设置与Eureka Server交互的地址,多个地址可使用【,】分隔
eureka.client.serviceUrl.defaultZone=http://localhost:8001/eureka/
3.3、服务测试
最后,将服务注册中心、服务网关、订单微服务依次启动起来,然后访问http://localhost:9030/eureka-consumer-order/hello
,可以得到类似于如下内容。
hello,这是一个订单微服务
可以清晰的看到,请求 Zuul 服务,接口被顺利的转发到eureka-consumer-order
服务上去了。
Zuul 会自动代理所有注册到 Eureka Server 的微服务接口地址,默认的路由规则如下。
http://zuul_host:zuul_port/serviceId/**
其中serviceId
指的的是微服务在 Eureka 注册的 serviceId,其值通常指的是spring.application.name
配置的参数。
因此,当请求http://localhost:9030/eureka-consumer-order/hello
时,会自动转发到http://localhost:9022/hello
,如果有多个目标服务地址,会自动进行负载均衡。
如果不想在请求路径上暴露服务实例 serviceId,也可以在 Zuul 服务的配置文件中自定义路由规则。
例如,通过请求http://localhost:9030/order/hello
时进行服务路由,示例如下:
# 自定义服务路由前缀,如果不指定,默认路由地址就是服务实例名称
zuul.routes.api-order.path=/order/**
zuul.routes.api-order.serviceId=eureka-consumer-order
四、小结
最后总结一下,Zuul 是一个强大的服务网关组件,除了提供服务路由、均衡负载等基础功能之外,还可以利用它来实现权限控制、接口限流等功能,这一重要特性,我们在下篇文章中会再次介绍。
五、参考
作者:潘志的技术笔记
出处:https://pzblog.cn/
版权归作者所有,转载请注明出处
