前言
本小节学习一下Zuul Gateway。
-
为什么需要API Gateway
-
简化客户端调用复杂度
在微服务架构模式下后端服务的实例数一般是动态的,对于客户端而言很难发现动态改变的服务实例的访问地址信息。因此在基于微服务的项目中为了简化前端的调用逻辑,通常会引入API Gateway作为轻量级网关,同时API Gateway中也会实现相关的认证逻辑从而简化内部服务之间相互调用的复杂度。
-
数据裁剪以及聚合
通常而言不同的客户端对于显示时对于数据的需求是不一致的,比如手机端或者Web端又或者在低延迟的网络环境或者高延迟的网络环境。
因此为了优化客户端的使用体验,API Gateway可以对通用性的响应数据进行裁剪以适应不同客户端的使用需求。同时还可以将多个API调用逻辑进行聚合,从而减少客户端的请求数,优化客户端用户体验。 -
多渠道支持
当然我们还可以针对不同的渠道和客户端提供不同的API Gateway,对于该模式的使用由另外一个大家熟知的方式叫Backend for front-end, 在Backend for front-end模式当中,我们可以针对不同的客户端分别创建其BFF -
遗留系统的微服务化改造
对于系统系统而言进行微服务改造通常是由于原有的系统存在或多或少的问题,比如技术债务,代码质量,可维护性,可扩展性等等。API Gateway的模式同样适用于这一类遗留系统的改造,通过微服务化的改造逐步实现对原有系统中的问题的修复,从而提升对于原有业务响应力的提升。通过引入抽象层,逐步使用新的实现替换旧的实现。
-
-
什么是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):跨域AWS Region进行请求路由
案例
-
Eureka Server端编写(参考前例)。
-
Eureka Client端服务提供方编写。
-
项目结构
-
CoreCode
<?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> <artifactId>microservice-deal-gateway-zuul</artifactId> <packaging>jar</packaging> <name>microservice-deal-gateway-zuul</name> <description>Demo project for Spring Boot</description> <parent> <groupId>com.example</groupId> <artifactId>microservice-deal-parent</artifactId> <version>0.0.1-SNAPSHOT</version> </parent> <dependencies> <!-- Zuul --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-zuul</artifactId> </dependency> </dependencies> </project>
server: port: 8040 spring: application: name: microservice-deal-gateway-zuul eureka: client: service-url: #defaultZone: http://localhost:8080/eureka/ defaultZone: http://Dustyone:bai5331359@localhost:8080/eureka/ instance: prefer-ip-address: true zuul: routes: user-route: path: /deal/** service-id: microservice-deal-cloud ribbon: eureka: enabled: true # 禁用掉ribbon的eureka使用。详见:http://cloud.spring.io/spring-cloud-static/Camden.SR3/#_example_disable_eureka_use_in_ribbon microservice-deal-cloud: ribbon: listOfServers: localhost:8081 management: security: enabled: false
package com.exmaple.deal; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication @EnableZuulProxy public class MicroserviceDealGatewayZuulApplication { public static void main(String[] args) { SpringApplication.run(MicroserviceDealGatewayZuulApplication.class, args); } }
-
-
Eureka Client端服务提消费编写(单实例) (参考前例)。
-
Zuul API Gateway的一些常用配置:
-
本地转发
zuul: routes: route-name: path: /path-a/** url: forward:/path-b
-
忽略指定的微服务节点即对指定的微服务节点不做转发:
zuul: ignored-services:microservice-deal-broker-cloud-ribbon-customized-properties,microservice-deal-broker-cloud-feign-cusomized-external
-
忽略所有微服务节点只转发指定的微服务节点:
zuul: ignored-services: '*' # 使用'*'可忽略所有微服务 routes: microservice-deal-cloud: /deal/**
-
指定路由节点和微服务节点:
zuul: routes: deal-route: # 该配置方式中,deal-route只是给路由一个名称,可以任意起名。 service-id: microservice-deal-cloud path: /deal/** # service-id对应的路径
-
指定路径和节点而不通过微服务节点做转发:
zuul: routes: deal-route: # 该配置方式中,deal-route只是给路由一个名称,可以任意起名。 url: http://localhost:8000/ # 指定的url path: /deal/** # url对应的路径。
-
指定Path和URL,保留Zuul原有的Hystrix和Ribbon功能:
zuul: routes: deal-route: path: /deal/** service-id: microservice-deal-cloud ribbon: eureka: enabled: true microservice-provider-user: ribbon: listOfServers: localhost:8000,localhost:8001
-
为Zuul转发API添加前缀:
zuul: prefix: /api strip-prefix: false routes: microservice-deal-cloud: /deal/** #访问Zuul的/api/microservice-deal-cloud/1路径,请求将会被转发到microservice-deal-cloud的/api/1,可查看日志打印,有助于理解。 logging: level: com.netflix: DEBUG
zuul: routes: microservice-deal-cloud: path: /deal/** strip-prefix: false logging: level: com.netflix: DEBUG
-
通过通配符配置忽略一些URL:
zuul: ignoredPatterns: /**/admin/** # 忽略所有包括/admin/的路径 routes: microservice-deal-cloud: /deal/**
-
使用正则过滤URL:
/** * 该示例是将userservice-v1映射到/v1/uservice/中,常用于版本管理中,如APP端调用的API带有版本信息(服务-版本), * Zuul为这些不同版本的微服务应用生成以版本代号作为路由前缀定义的路由规则。 * 通过具有版本号前缀的URL路径,可以很容易通过路径表达式来归类和管理这些具有版本信息的微服务 * @return */ @Bean public PatternServiceRouteMapper serviceRouteMapper() { // 调用构造函数PatternServiceRouteMapper(String servicePattern, String // routePattern) // servicePattern指定微服务的正则 // routePattern指定路由正则 return new PatternServiceRouteMapper("(?<name>^.+)-(?<version>v.+$)", "${version}/${name}"); }
-
…
-
小结
- 使用Zuul作为服务网关需要引入对Zuul的依赖:spring-cloud-starter-netflix-zuul。改以来声明了对Eureka Client的依赖故在Zuul所在的节点中不需要特别申明对Eureka Client的依赖。
- 在主类上开启@EnableZuulProxy注解,该注解默认开启了@EnableDiscoveryClient。
- 对Zuul的配置参考配置文件。
- 本小节用到的案例:microservice-deal-eureka-authentication、microservice-deal-cloud、microservice-deal-gateway-zuul