- 推荐序一
- 推荐序二
- 推荐序三
- 推荐语
- 前言
- 第1章 基础知识
- 第2章 微服务构建:Spring Boot
- 第3章 服务治理:Spring Cloud Eureka
- 第4章 客户端负载均衡:Spring Cloud Ribbon
- 第5章 服务容错保护:Spring Cloud Hystrix
- 第6章 声明式服务调用:Spring Cloud Feign
- 第7章 API网关服务:Spring Cloud Zuul
- 第8章 分布式配置中心:Spring Cloud Config
- 第9章 消息总线:Spring Cloud Bus
- 第10章 消息驱动的微服务:Spring Cloud Stream
- 附录 A Starter POMs
- 后记
第7章 API网关服务:Spring Cloud Zuul
通过前几章的介绍,我们对于Spring Cloud Netflix下的核心组件已经了解了一大半。这些组件基本涵盖了微服务架构中最为基础的几个核心设施,利用这些组件我们已经可以构建起一个简单的微服务架构系统,比如,通过使用Spring Cloud Eureka实现高可用的服务注册中心以及实现微服务的注册与发现;通过Spring Cloud Ribbon或Feign实现服务间负载均衡的接口调用;同时,为了使分布式系统更为健壮,对于依赖的服务调用使用Spring Cloud Hystrix来进行包装,实现线程隔离并加入熔断机制,以避免在微服务架构中因个别服务出现异常而引起级联故障蔓延。通过上述思路,我们可以设计出类似下图的基础系统架构。
在该架构中,我们的服务集群包含内部服务Service A和Service B,它们都会向Eureka Server集群进行注册与订阅服务,而Open Service是一个对外的RESTful API服务,它通过F5、Nginx 等网络设备或工具软件实现对各个微服务的路由与负载均衡,并公开给外部的客户端调用。
在本章中,我们将把视线聚焦在对外服务这块内容,通常也称为边缘服务。首先需要肯定的是,上面的架构实现系统功能是完全没有问题的,但是我们还是可以进一步思考一下,这样的架构是否还有不足的地方会使运维人员或开发人员感到痛苦。
首先,我们从运维人员的角度来看看,他们平时都需要做一些什么工作来支持这样的架构。当客户端应用单击某个功能的时候往往会发出一些对微服务获取资源的请求到后端,这些请求通过F5、Nginx等设施的路由和负载均衡分配后,被转发到各个不同的服务实例上。而为了让这些设施能够正确路由与分发请求,运维人员需要手工维护这些路由规则与服务实例列表,当有实例增减或是IP地址变动等情况发生的时候,也需要手工地去同步修改这些信息以保持实例信息与中间件配置内容的一致性。在系统规模不大的时候,维护这些信息的工作还不会太过复杂,但是如果当系统规模不断增大,那么这些看似简单的维护任务会变得越来越难,并且出现配置错误的概率也会逐渐增加。很显然,这样的做法并不可取,所以我们需要一套机制来有效降低维护路由规则与服务实例列表的难度。
其次,我们再从开发人员的角度来看看,在这样的架构下,会产生一些怎样的问题呢?大多数情况下,为了保证对外服务的安全性,我们在服务端实现的微服务接口,往往都会有一定的权限校验机制,比如对用户登录状态的校验等;同时为了防止客户端在发起请求时被篡改等安全方面的考虑,还会有一些签名校验的机制存在。这时候,由于使用了微服务架构的理念,我们将原本处于一个应用中的多个模块拆成了多个应用,但是这些应用提供的接口都需要这些校验逻辑,我们不得不在这些应用中都实现这样一套校验逻辑。随着微服务规模的扩大,这些校验逻辑的冗余变得越来越多,突然有一天我们发现这套校验逻辑有个BUG需要修复,或者需要对其做一些扩展和优化,此时我们就不得不去每个应用里修改这些逻辑,而这样的修改不仅会引起开发人员的抱怨,更会加重测试人员的负担。所以,我们也需要一套机制能够很好地解决微服务架构中,对于微服务接口访问时各前置校验的冗余问题。
为了解决上面这些常见的架构问题,API 网关的概念应运而生。API 网关是一个更为智能的应用服务器,它的定义类似于面向对象设计模式中的Facade模式,它的存在就像是整个微服务架构系统的门面一样,所有的外部客户端访问都需要经过它来进行调度和过滤。它除了要实现请求路由、负载均衡、校验过滤等功能之外,还需要更多能力,比如与服务治理框架的结合、请求转发时的熔断机制、服务的聚合等一系列高级功能。
既然API网关对于微服务架构这么重要,那么在Spring Cloud中是否有相应的解决方案呢?答案是很肯定的,在Spring Cloud中了提供了基于Netflix Zuul实现的API网关组件—Spring Cloud Zuul。那么,它是如何解决上面这两个普遍问题的呢?
首先,对于路由规则与服务实例的维护问题。Spring Cloud Zuul通过与Spring Cloud Eureka进行整合,将自身注册为Eureka服务治理下的应用,同时从Eureka中获得了所有其他微服务的实例信息。这样的设计非常巧妙地将服务治理体系中维护的实例信息利用起来,使得将维护服务实例的工作交给了服务治理框架自动完成,不再需要人工介入。而对于路由规则的维护,Zuul默认会将通过以服务名作为ContextPath的方式来创建路由映射,大部分情况下,这样的默认设置已经可以实现我们大部分的路由需求,除了一些特殊情况(比如兼容一些老的 URL)还需要做一些特别的配置。但是相比于之前架构下的运维工作量,通过引入Spring Cloud Zuul实现API网关后,已经能够大大减少了。
其次,对于类似签名校验、登录校验在微服务架构中的冗余问题。理论上来说,这些校验逻辑在本质上与微服务应用自身的业务并没有多大的关系,所以它们完全可以独立成一个单独的服务存在,只是它们被剥离和独立出来之后,并不是给各个微服务调用,而是在API网关服务上进行统一调用来对微服务接口做前置过滤,以实现对微服务接口的拦截和校验。Spring Cloud Zuul提供了一套过滤器机制,它可以很好地支持这样的任务。开发者可以通过使用Zuul来创建各种校验过滤器,然后指定哪些规则的请求需要执行校验逻辑,只有通过校验的才会被路由到具体的微服务接口,不然就返回错误提示。通过这样的改造,各个业务层的微服务应用就不再需要非业务性质的校验逻辑了,这使得我们的微服务应用可以更专注于业务逻辑的开发,同时微服务的自动化测试也变得更容易实现。
微服务架构虽然可以将我们的开发单元拆分得更为细致,有效降低了开发难度,但是它所引出的各种问题如果处理不当会成为实施过程中的不稳定因素,甚至掩盖掉原本实施微服务带来的优势。所以,在微服务架构的实施方案中,API 网关服务的使用几乎成为了必然的选择。
下面我们将详细介绍Spring Cloud Zuul的使用方法、配置属性以及一些不足之处和需要进行的思考。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论