在微服务架构中,后端服务往往不间接凋谢给调用端,而是通过一个 API 网关依据申请的 url,路由到相应的服务。当增加 API 网关后,在第三方调用端和服务提供方之间就创立了一面墙,这面墙间接与调用方通信进行权限管制,后将申请平衡分发给后盾服务端。
一个简略的微服务架构曾经跃然纸面:(理解源码可 + 求求: 1791743380)
在 Spring Cloud 微服务零碎中,一种常见的负载平衡形式是,客户端的申请首先通过负载平衡(zuul、Ngnix、F5),再达到服务网关(zuul 集群),而后再到具体的服务,服务对立注册到高可用的服务注册核心集群,服务的所有的配置文件由配置服务治理,配置服务的配置文件放在 git 仓库,不便开发人员随时改配置。
1. 为什么须要 API Gateway?
1.1 简化客户端调用复杂度
在微服务架构模式下后端服务的实例数个别是动静的,对于客户端而言很难发现动静扭转的服务实例的拜访地址信息。因而在基于微服务的我的项目中为了简化前端的调用逻辑,通常会引入 API Gateway 作为轻量级网关,同时 API Gateway 中也会实现相干的认证逻辑从而简化外部服务之间互相调用的复杂度。
### 1.2 数据裁剪以及聚合
通常而言不同的客户端对于显示时对于数据的需要是不统一的,比方手机端或者 Web 端又或者在低提早的网络环境或者高提早的网络环境。
因而为了优化客户端的应用体验,API Gateway 能够对通用性的响应数据进行裁剪以适应不同客户端的应用需要。同时还能够将多个 API 调用逻辑进行聚合,从而缩小客户端的申请数,优化客户端用户体验
1.3 多渠道反对
当然咱们还能够针对不同的渠道和客户端提供不同的 API Gateway, 对于该模式的应用由另外一个大家熟知的形式叫 Backend for front-end, 在 Backend for front-end 模式当中,咱们能够针对不同的客户端别离创立其 BFF,进一步理解 BFF 能够参考这篇文章:Pattern: Backends For Frontends
[
](https://springcloud-oss.oss-c…
1.4 遗留零碎的微服务化革新
对于零碎而言进行微服务革新通常是因为原有的零碎存在或多或少的问题,比方技术债权,代码品质,可维护性,可扩展性等等。API Gateway 的模式同样实用于这一类遗留零碎的革新,通过微服务化的革新逐渐实现对原有零碎中的问题的修复,从而晋升对于原有业务响应力的晋升。通过引入形象层,逐渐应用新的实现替换旧的实现。
在 Spring Cloud 体系中,Spring Cloud Zuul 就是提供负载平衡、反向代理、权限认证的一个 API gateway。
在开始聊 Zuul 如何应用之前,先讲一个比拟有意思的事件,就是在 springcloud 组件中,服务网关这个组件,springcloud 提供了两种抉择,一个是 netflix 公司开源的 Zuul,还有一个是 springcloud 本人开源的 Spring Cloud Gateway,具体这两个组件的恩怨情仇,在前面的 Spring Cloud Gateway 的文章中咱们再细聊:)
2. Spring Cloud Zuul
2.1 简略应用
Spring Cloud Zuul 路由是微服务架构的不可或缺的一部分,提供动静路由,监控,弹性,平安等的边缘服务。Zuul 是 Netflix 出品的一个基于 JVM 路由和服务端的负载均衡器。
上面咱们来看一下 Zuul 最简略的应用形式,创立 zuul-simple 工程
2.1 pom.xml
<?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\> <parent\> <groupId\>org.springframework.boot</groupId\> <artifactId\>spring-boot-starter-parent</artifactId\> <version\>2.1.6.RELEASE</version\> <relativePath/> <!-- lookup parent from repository --> </parent\> <groupId\>com.springcloud</groupId\> <artifactId\>zuul-simple</artifactId\> <version\>0.0.1-SNAPSHOT</version\> <name\>zuul-simple</name\> <description\>Demo project for Spring Boot</description\> <properties\> <java.version\>1.8</java.version\> <spring-cloud.version\>Greenwich.SR1</spring-cloud.version\> </properties\> <dependencies\> <dependency\> <groupId\>org.springframework.cloud</groupId\> <artifactId\>spring-cloud-starter-netflix-zuul</artifactId\> </dependency\> <dependency\> <groupId\>org.springframework.boot</groupId\> <artifactId\>spring-boot-starter-test</artifactId\> <scope\>test</scope\> </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\> <plugins\> <plugin\> <groupId\>org.springframework.boot</groupId\> <artifactId\>spring-boot-maven-plugin</artifactId\> </plugin\> </plugins\> </build\> </project\>
引入 spring-cloud-starter-netflix-zuul 包
2.2 配置文件 application.yml
server: port: 8080 spring: application: name: spring-cloud-zuul zuul: routes: baidu: path: /baidu/\*\* url: https://www.baidu.com/
这里的配置示意,拜访 /baidu/ 间接重定向到 https://www.baidu.com/
如果间接拜访 http://localhost:8080/baidu,则会间接跳转到 https://www.baidu.com/。
2.3 启动类
package com.springcloud.zuulsimple; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.zuul.EnableZuulProxy; @SpringBootApplication @EnableZuulProxy public class ZuulSimpleApplication {public static void main(String\[\] args) {SpringApplication.run(ZuulSimpleApplication.class, args); } }
启动类增加 @EnableZuulProxy,反对网关路由。
史上最简略的 zuul 案例就配置完了
2.4 测试
启动我的项目,在浏览器拜访 http://localhost:8080/baidu/,咱们能够看到页面曾经跳转到百度首页。
再尝试拜访 http://localhost:8080/baidu/aa,咱们能够看到页面跳转至:https://www.baidu.com/search/error.html,因为 https://www.baidu.com/aa 这个链接不存在,所以百度帮咱们跳转到的 error 页面。
至此,Zuul 简略应用曾经介绍结束,上面咱们来聊一下服务化的形式。
2.2 服务化
通过 url 映射的形式来实现 Zuul 的转发有局限性,比方每减少一个服务就须要配置一条内容,另外后端的服务如果是动静来提供,就不能采纳这种计划来配置了。实际上在实现微服务架构时,服务名与服务实例地址的关系在 eureka server 中曾经存在了,所以只须要将 Zuul 注册到 eureka server 下来发现其余服务,就能够实现对 serviceId 的映射。
咱们联合示例来阐明,在下面示例我的项目根底上来进行革新
2.2.1 增加依赖
<dependency\> <groupId\>org.springframework.cloud</groupId\> <artifactId\>spring-cloud-starter-netflix-eureka-client</artifactId\> </dependency\>
减少 spring-cloud-starter-netflix-eureka-client 包,增加对 eureka 的反对。
2.2.2 配置文件 application.yml
server: port: 8080 spring: application: name: spring-cloud-zuul zuul: routes: api-producer: path: /producer/\*\* serviceId: spring-cloud-producer eureka: client: service-url: defaultZone: http://localhost:8761/eureka/
在这里咱们减少了对服务的反对,这里的 Zuul 配置的含意为拜访 /producer/**,转向到 eureka 下面 serviceId 为 spring-cloud-producer 的服务。
2.2.3 测试
先从上一篇的我的项目中 copy Eureka 到本篇的文件夹中,再从第五篇的我的项目中 copy 一个 producer 到本篇的文件夹中。
顺次启动 eureka,producer 和 Zuul.
咱们关上浏览器拜访:http://localhost:8080/producer/hello?name=spring,能够看到页面失常显示 producer 的响应:hello spring,producer is ready。阐明通过 zuul 胜利调用了 producer 服务。
这里 producer 能够启动两个服务,屡次刷新 http://localhost:8080/producer/hello?name=spring,能够看到 Zuul 对服务的调用是负载平衡的。
2.3 网关的默认路由
然而如果后端服务多达十几个的时候,每一个都这样配置也挺麻烦的,spring cloud zuul 曾经帮咱们做了默认配置。默认状况下,Zuul 会代理所有注册到 Eureka Server 的微服务,并且 Zuul 的路由规定如下:http://ZUUL_HOST:ZUUL_PORT/ 微服务在 Eureka 上的 serviceId/** 会被转发到 serviceId 对应的微服务。
咱们登记掉 zuul-simple 配置文件中无关路由的配置。
#zuul: \# routes: \# api-producer: \# path: /producer/\*\* \# serviceId: spring-cloud-producer
再次启动 Zuul。
咱们在浏览器中拜访 http://localhost:8080/spring-cloud-producer/hello?name=spring,能够看到和下面一样的返回后果,阐明 Spring cloud zuul 默认曾经提供了转发性能。