Spring Cloud Zuul 服务网关(路由)
前置说明:本文内容基于相关文章整理,具体内容请参考原文
Spring Cloud 微服务架构:服务网关(基础)
Spring Cloud 微服务架构:服务网关(路由配置)
Spring Cloud 微服务架构(五):服务网关
1. 微服务架构中的对外服务权限控制
在微服务架构中,存在需要对外开放的服务接口。为了保障对外服务的安全性,我们需要实现访问权限的控制。如果在每个对外服务上直接添加权限控制逻辑,将面临以下问题:
- 服务权限控制会贯穿整个对外服务的业务逻辑,破坏REST API无状态的特点。同时,服务开发和测试过程中需要额外处理接口访问控制逻辑。
- 已有接口无法直接复用。当需要将现有微服务接口对外开放时,必须在原有接口上增加权限控制功能。
如何解决这一问题?服务网关
2. 服务网关 & Spring Cloud Netflix Zuul
在微服务架构中,我们可以将权限控制等非业务逻辑从服务单元中分离,集中部署在对外访问的最前端,即服务网关。服务网关在微服务架构中扮演着重要角色,具备服务路由、负载均衡、权限控制等功能,统一为外部系统提供REST API接口。
Spring Cloud Netflix中的Zuul组件正是承担了服务网关的角色,为微服务架构提供前端保护,同时将权限控制等非业务逻辑迁移到服务路由层面,提高了服务集群的可复用性和可测试性。
3. 使用Spring Cloud Zuul实现服务网关及验证服务路由功能
步骤1:准备服务注册中心eureka-server,以及网关内部的微服务eureka-client和eureka-consumer。具体实现可参考Spring Cloud Eureka服务治理相关文档。
步骤2:构建服务网关。创建一个基础的Spring Boot项目api-gateway。添加以下起步依赖:
- spring-cloud-starter-netflix-zuul
- spring-cloud-starter-netflix-eureka-server
注意:如果使用指定serviceId的方式,则eureka依赖可选。
步骤3:在配置类中添加@EnableZuulProxy注解以开启Zuul功能,并添加@SpringCloudApplication注解标注这是一个Spring Cloud项目。
步骤4:在application.properties文件中添加以下配置:
# 服务名称及端口配置
spring.application.name: api-gateway
server.port: 1101
# 指定服务注册中心地址
eureka.client.serviceUrl.defaultZone=http://localhost:1001/eureka/
这样,一个基于Spring Cloud Zuul的服务网关就创建完成了。
步骤5:启动eureka-server、eureka-client和eureka-consumer服务,并启动api-gateway。通过访问http://localhost:1101/eureka-client/discoveryClient,该请求将被路由到eureka-client的/discoveryClient接口。
4. Spring Cloud Netflix Zuul服务路由实现机制
通过以上示例,可以看到api-gateway服务网关已经具备了服务路由功能。Zuul是如何实现这一功能的?
a. Zuul通过整合Spring Cloud Eureka,实现对服务实例的自动维护。API网关作为一个普通微服务应用,具备以下功能:
- 自己注册到Eureka服务注册中心
- 从注册中心获取所有服务及其实例清单
因此,API网关能够维护服务ID与实例地址的映射关系。
b. 当服务有多个实例时,Zuul通过Ribbon的负载均衡策略选择一个具体实例。外部请求到达API网关后,根据URL路径找到匹配的路由规则,确定需要路由的服务ID。通过Ribbon负载均衡策略,在对应服务实例清单中选择一个实例进行转发,完成路由过程。
c. 在当前示例中,api-gateway启动并注册到eureka后,会发现eureka-client和eureka-consumer两个服务。Zuul会创建以下两个路由规则:
- 路由规则1:/eureka-client/** 转发到eureka-client服务
- 路由规则2:/eureka-consumer/** 转发到eureka-consumer服务
通过访问http://localhost:1101/eureka-client/discoveryClient,请求将被路由到eureka-client的/discoveryClient接口。
5. Spring Cloud Netflix Zuul服务路由映射机制
5.1 默认情况下无需手动配置
5.2 在application.properties中配置zuul.routes.<route>.path和zuul.routes.<route>.serviceId参数
# 匹配/eureka-client-zuul/**路径的请求转发到eureka-client服务
zuul.routes.eureka-client.path=/eureka-client-zuul/**
zuul.routes.eureka-client.serviceId=eureka-client
重启api-gateway服务后,访问http://localhost:1101/eureka-client-zuul/discoveryClient和http://localhost:1101/eureka-client/discoveryClient将得到相同结果。
5.3 在application.properties中配置zuul.routes.<serviceId>=<path>格式
<serviceId>指定目标服务名称<path>指定请求路径表达式
# 匹配/user-service/**路径的请求转发到eureka-client服务
zuul.routes.eureka-client=/user-service/**
重启服务后,访问http://localhost:1101/user-service/discoveryClient和http://localhost:1101/eureka-client/discoveryClient将得到相同结果。
注意:对于同一服务,不能同时使用两种配置方式,否则zuul.routes.<serviceId>=<path>格式的配置将优先生效。