推荐阅读:
背景
我们都知道,在微服务架构风格里,一个应用会被拆分成多个小的服务系统,并且这些小系统都可以自成体系,可以拥有自己的数据库、框架语言等。它们通常都可以提供接口来被各种应用程序调用。
但是在UI上进行展示的时候,我们通常需要在一个界面上展示很多数据,这些数据可能来自于不同的微服务中。
打个比方:要查看一个电商平台的商品详情页,这个商品详情页包括标题、价格、库存、评价等等,这些数据可能在不同的微服务系统之中,如下所示:
- 产品 - 负责提供商品的标题,描述,规格等。
- 价格 - 负责对产品进行定价,价格策略计算,促销价等。
- 库存 - 负责产品库存。
- 评价 - 负责用户对商品的评论,回复等。
现在,商品详情页需要从这些微服务中拉取相应的信息,问题来了?
由于用的是多个服务系统的架构,所以依靠单个数据库的 join 查询结果不可行,那么该怎么访问各个服务呢?
按照微服务设计的指导原则,我们的微服务可能存在下面的问题:
- 服务使用了多种协议,因为不同的协议有不同的应场景用,比如可能同时使用 HTTP, AMQP, gRPC 等。
- 服务的划分可能随着时间而变化。
- 服务的实例或者Host+端口可能会动态的变化。
那么,对于前端的UI需求也可能会有以下几种:
- 粗粒度的API,而微服务通常提供的细粒度的API,对于UI来说如果要调用细粒度的api可能需要调用很多次,这是个不小的问题。
- 不同的客户端设备可能需要不同的数据。Web,H5,APP
- 不同设备的网络性能,对于多个api来说,这个访问需要转移的服务端会快得多
那么如何解决呢?
这种情况下,我们就需要一个今天要讲的这个东西, API 网关(API Gataway)。
API 网关
下面是百度上针对于 API 网关的介绍:
API网关是一个服务器,是系统的唯一入口。从面向对象设计的角度看,它与外观模式类似。API网关封装了系统内部架构,为每个客户端提供一个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分片与管理、静态响应处理。
API网关方式的核心要点是,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。通常,网关也是提供REST/HTTP的访问API。服务端通过API-GW注册和管理服务。
Chris Richardson 在他的博客中把 API 网关划分为以下两种:
- 单节点 API 网关
- Backends for frontends 网关
单节点网关
单节点的 API网关为每个客户端提供不同的API,而不是提供一种万能风格的API。
这个网关和微软在 eShop 项目中推荐的网关是一致的。
Backends for frontends 网关
这种模式是针对不同的客户端来实现一个不同的API网关。
落地方案
以上两种 API 网关有什么问题呢?
通常情况下, API 网关要做很多工作,它作为一个系统的后端总入口,承载着所有服务的组合路由转换等工作,除此之外,我们一般也会把安全,限流,缓存,日志,监控,重试,熔断等放到 API 网关来做,那么可以试想在高并发的情况下,这里可能会出现一个性能瓶颈。
另外,如果没有开源项目的支撑前提下,自己来做这样一套东西,是非常大的一个工作量,而且还要做 API 网关本身的高可用等,如果一旦做不好,有可能最先挂掉的不是你的其他服务,而就是这个API网关。
这个时候,通常我们会去找一些开源的 API 网关项目,博主已经给你找好了,目前社区的关于 API Gataway 的项目有以下这些:
Goku:Goku是一个可扩展的开放源码API Layer(也称为API网关或API中间件)。开箱即用,全界面配置,操作简单,通过插件扩展,它提供了超越核心平台的额外功能和服务。
Orange:基于OpenResty的一个API网关程序,同样是由国人开发的。
Netflix zuul:Zuul是一种提供动态路由、监视、弹性、安全性等功能的边缘服务。Zuul是Netflix出品的一个基于JVM路由和服务端的负载均衡器。
apiaxle: Nodejs 实现的一个 API 网关。
api-umbrella: Ruby 实现的一个 API 网关。
总结
通过本文我们了解到了什么是 API 网关以及API网关的作用和其在微服务架构中所处的地位。然后我们了解到了 API 网关的一些开源项目以及博主介绍的落地方案,在实际的实践中还是多希望大家能够多多思考总结,这样我们才能够变得更加强大。
网友评论