当你选择采用微服务构建自己的程序,则你需要考虑客户端怎样与后端服务交互。对于一个单体应用,仅有一个服务群提供服务(通过负载均衡器实现)。在微服务架构里面,每一个服务都暴漏了一个服务器集群。本篇文章我们讨论它对于客户端通讯的影响和提出通过API网关的解决办法。

背景介绍

首先让我们想象一下一个购物的移动程序。它需要实现产品详情页展示,例如产品信息、库存信息、订单信息、购物车等。例如,下图显示了你将看到的产品信息:

尽管它仅仅是一个手机程序的详情页,它也显示了产品的一些信息。它不仅展示了一些产品的基本信息(名称、描述和价格),也显示以下信息:

1)购物车中的产品数

2)订单历史

3)客户浏览历史

4)低库存预警

5)物流信息

6)推荐信息,包括经常购买的新、购买过之后的推荐和浏览历史推荐;

7)不同的购买选项

如果采用单体程序,客户端仅仅需要一个链接就能够获取所需要的所有信息。负载均衡器返回任何一个应用程序的反馈数据即可。应用程序将会查询数据表,并向客户返回数据。

相反,微服务架构下,产品详情页数据则需要好几个服务群才能够提供。这里是几个拥有产品详情页信息数据的几个服务器服务:

1)购物车服务-负责显示购物车中的产品数量

2)订单服务-订单历史

3)类目服务-提供产品的名字、描述和价格

4)历史服务-用户的浏览历史

5)库存服务-低库存预警

6)物流服务-从物流提供商返回物流花费、到达时间和物流选项

7)推荐服务-建议选项

我们需要决定,客户端怎样获取这些服务。下面让我们讨论一下可能的方案。

客户端直接连接微服务

理论上微服务可以直接连接微服务。每一个微服务都有一个地址,这个地址映射向服务均衡(提供服务的负载)地址。为了获取产品信息,客户端可以直接连接上述的微服务地址。

不幸的,这种方案存在挑战和限制。其一,其存在客户端和微服务之间的错配问题。客户端不得不发起其次独立的请求。在复杂的系统,它需要返回更多的请求。例如,亚马逊在选择页面的时候描述了数百个微服务。如果客户端发起了过多的请求,会导致 互联网的低效,这也不是移动网络的最佳实践。这也会导致客户端的过度复杂。(个人觉得,如果微服务页面较少,这会提升开发效率和网络请求时间)

直连的另一个问题是微服务对外的协议可能不是web友好的。例如,有些服务采用Thrift binary RPC,而有些则采用AMQP 。这两种协议都不是浏览器和防火墙所友好的协议。一个友好的web协议应该采用WebSocket 或者HTTP协议。

另一个缺陷是这种解决方案使得重构微服务变得困难。随着时间改变,我们想改变微服务划分的标准。例如,我们可能将两个微服务合并,或者拆分一个微服务。这种类型的重构将会使得这种方案变得非常困难。

采用API网关

通常,一个较好的方案采用API网关。API网关是一种从前端到后端的唯一路径服务。它类似于面向对象设计的 Facade 模式。API网关将后端的服务进行了包装,同时提供了客户端所需要的API。它还提供其他职责,像权限、监控、负载均衡、缓存、请求转发和管理、静态请求处理等。

以下图展示了API网关适应的架构:

API网关负责请求的路由转发、组合和协议解释。所有来自客户端的请求都需要经过API网关。它将请求匹配到合适的微服务。它通过请求多个微服务或者聚合结果处理请求。它能够在HTTP、WebSocket和不友好的协议之间转换。

API网关也为客户端提供个性化的接口。它为移动客户端提供了粗粒度的API。例如,产品的详情页。例如,他能够为移动客户端提供一个连接,通过此可以获得所有的所需数据。API网关处理请求分为两步:1)向不同的服务请求数据 2)合并数据。

API网关的一个成功例子是Netflix API Gateway。 Netflix流服务包含数百种终端设备,像电视、移动电话、游戏等。Netflix向提供一种统一形式的API。但是,他们发现由于涵盖的设备太多和个性化需求导致这种方案太难实现。现在,他们为每种类型的设备实现一种设备适配,通过API网关做具体适配。一种适配通过调用六、七种服务处理请求。The Netflix API Gateway每天处理数十亿请求。

API网关的优缺点

正如期望的那样,API网关也存在优点和缺点。最大的优势是API网关屏蔽了后端服务的结构。客户可以简单的通信,而不用处理服务之间的关系。API网关为每种客户端提供单独的接口。它减少了客户端和应用程序之间的往返次数。它也简化了客户端的代码。

API网关也有缺陷。它必须是一个开发、设计和部署的高可用组建。API网关成为开发的瓶颈是一种风险。研发必须升级网关服务以便暴露所有的服务。尽可能的轻量化部署API网关非常重要。开发者发版时必须要线性等待。尽管有这些缺点,程序采用API网关将会是有意义的。

个人认为:在程序框架的前期当服务并不是很多的时候,可以尝试采用客户端直连的形式实现,但是前端必须创建前端路由。如果后期服务较多,则尽量采用API路由网关的形式,因为这种情况下可以缩短请求次数、缩短请求路径,此种问题的请求不包含静态文件的处理。

实现API网关

现在我们已经了解了创建API网关的目的和意义了。让我们看一下创建时需要考虑的事情:

性能和伸缩性

仅有很少的公司如Netflix一样伸缩操作和单日处理数十亿请求。但是,API网关的性能和伸缩性非常重要。在一个平台上创建一个异步、非阻塞的IO API网关是由意义的。有多重技术实现API网关的自由伸缩。在JVM上,你可以实现基于NIO框架的程序,类似于 Netty, Vertx, Spring Reactor, or JBoss Undertow。一个流行的费JVM技术是Node.js,它建立在Chrome的javascr上.另一个解决方案是 NGINX Plus.,它提供了生出的伸缩、高性能Web服务和易于创建、配置和编程的反向代理。

NGINX Plus.能够提供管理权限、获得控制、负载请求、缓存处理结果和提供心跳感知和监控。

采用自适应编程模型

API网关通过简单的路由请求到不同的服务处理客户端请求。它通过引用多个后端服务和聚合结果来处理其他服务。一些请求像请求产品详情的请求独立与其他请求。为了最小化请求,API网关需要并行处理请求。有时,不同请求之间存在依赖。AIP网关在处理请求之前,可能首先验证服务请求。类似的,为了获取与客户相关的产品列表信息,可能首先获取用户信息,其次获取相关的产品信息。API组件的例子是 Netflix Video Grid.。

如果采用传统的异步请求代码变下API网关,可能会进行请求地狱。这些代码非常难写、难于理解和易错。写这种代码的一种较好办法是采用反应法以一种清晰的样式书写。适应抽象的例子包括 Future in Scala, CompletableFuture in Java 8, and Promise in JavaScript. There is also Reactive Extensions (also called Rx or ReactiveX)。

服务调用

服务程序是一个分布式的程序,但是必须提供进程间通信的机制。在进程间通信有两种形式。一种是异步的、基于消息的通信。一些实现采用消息代理例如JMS or AMQP。还有不采用代理的,如 Zeromq(这种消息直接通信)。另一种是直接通信,像HTTP or Thrift。一个系统会用同步或者异步通信。一种形式会有多种的实现形式。因此,API网关需要实现多种通信机制。

服务发现

API网关知道相互通信服务的地址。在传统系统,你可能硬编码地址,但是在现代云服务平台这将是一个巨大的问题。基础服务,像消息代理,可以通过系统变量设置,但是固定一个程序服务地址并不可行。因为一个应用程序服务的地址是动态指定的,同时服务随着伸缩或者更新,地址也可能会发生改变。因此,API网关就像其他客户端程序一样,需要应用系统的服务发现功能:服务端发现和客户端发现。

处理局部报错

另一个你需要关注的问题是局部报错问题。这个问题发生在一个服务调用另一个服务时,导致的原因是服务慢或者服务不可用。API网关永远不要无限制的阻塞服务调用。具体怎么处理依赖于具体的场景和哪个服务失败。例如,如果推荐服务报错,则API网关需要将产品的其他信息返回给客户端,因为这些信息依然对于客户有用。如果产品信息不再服务,则需要向用户返回报错信息。

API网关应该返回在条件允许的情况下,应该返回缓存信息。例如,产品价格不频繁改动,如果产品价格服务不可用,则应该返回缓存中的产品价格。数据应该缓存在API服务器内存或者第三方内容中如Reddis或者memcached。通过返回默认信息或者缓存信息,API网关保证系统错误不影响用户体验。

Netflix Hystrix 是一个有用远程服务引用库。Hystrix 采用调用超时策略。它采用断路模式,即阻止客户端等待调用不反应的服务。如果某个服务发生错误的次数超过阈值,则Hystrix 启动断路并不允许客户端继续调用该服务。Hystrix定义了一个包括返回调用机制,报错后允许你获取缓存或者默认数据。

总结

对于大多数的微服务程序,采用API网关(作为程序的单一访问点)是有意义的。API网关负责请求路由、组合请求结果和协议解析。它为每种程序的客户端提供的单独的接口。它通过获取内存或者默认值可以掩盖后端错误。但是其路由的构建、结果的合并将是核心。

转自:https://blog.csdn.net/sunhaidong886/article/details/80707640

微服务API网关的更多相关文章

  1. .NET Core 微服务—API网关(Ocelot) 教程 [二]

    上篇文章(.NET Core 微服务—API网关(Ocelot) 教程 [一])介绍了Ocelot 的相关介绍. 接下来就一起来看如何使用,让它运行起来. 环境准备 为了验证Ocelot 网关效果,我 ...

  2. .NET Core 微服务—API网关(Ocelot) 教程 [三]

    前言: 前一篇文章<.NET Core 微服务—API网关(Ocelot) 教程 [二]>已经让Ocelot和目录api(Api.Catalog).订单api(Api.Ordering)通 ...

  3. 【微服务】之六:轻松搞定SpringCloud微服务-API网关zuul

    通过前面几篇文章的介绍,我们可以轻松搭建起来微服务体系中比较重要的几个基础构建服务.那么,在本篇博文中,我们重点讲解一下,如何将所有微服务的API同意对外暴露,这个就设计API网关的概念. 本系列教程 ...

  4. 【10】JMicro微服务-API网关

    如非授权,禁止用于商业用途,转载请注明出处作者:mynewworldyyl 往下看前,建议完成前面1到9小节 1. Api网关基本特性: Api网关作为对外网提供服务的基本入口,地位类似于NGINX, ...

  5. .NET Core 微服务—API网关(Ocelot) 教程 [一]

    前言: 最近在关注微服务,在 eShop On Containers 项目中存在一个API网关项目,引起想深入了解下它的兴趣. 一.API网关是什么 API网关是微服务架构中的唯一入口,它提供一个单独 ...

  6. .NET Core 微服务—API网关(Ocelot) 教程 [四]

    前言: 上一篇 介绍了Ocelot网关和认证服务的结合使用,本篇继续介绍Ocelot相关请求聚合和Ocelot限流 一.请求聚合 Ocelot允许声明聚合路由,这样可以把多个正常的Routes打包并映 ...

  7. 微服务API Gateway

    翻译-微服务API Gateway 原文地址:http://microservices.io/patterns/apigateway.html,以下是使用google翻译对原文的翻译. 让我们想象一下 ...

  8. 微服务与网关技术(SIA-GateWay)

    一.背景 软件架构,总是在不断的演进中... 把时间退回到二十年之前,当时企业级领域研发主要推崇的还是C/S模式,PB.Delphi这样的开发软件是企业应用开发的主流.随着时间的推移,基于浏览器的B/ ...

  9. 对微服务API服务网关的理解

    目录微服务专栏地址目录1. 简介2. 什么是API网关3. 为什么需要API网关4. API网关在微服务架构体系中处于什么位置4.1 调用者眼中的API网关4.2 所处的位置5. 网关技术实现有哪些6 ...

随机推荐

  1. 20155239 2016-2017-2 《Java程序设计》第5周学习总结

    教材内容学习 第八章 JAVA异常架构 Java异常是Java提供的一种识别及响应错误的一致性机制. Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性 ...

  2. Python 读写文件中w与wt, r与rt的区别

    w和wt是一们的,r和rt是一样的,t是默认参数,可以省略的,help(open)就能看到open的参数的详细说明. w,r,wt,rt都是python里面文件操作的模式.w是写模式,r是读模式.t是 ...

  3. Python: 在序列上执行聚集函数(比如sum() , min() , max() )

    在序列上执行聚集函数(比如sum() , min() , max() ) eg1: >>>nums = [1, 2, 3, 4, 5]>>>s = sum(x * ...

  4. 中国程序化购买广告解析:RTB/DSP/Ad Exchange/SSP/DMP,思维导图

    中国程序化购买广告解析:RTB/DSP/Ad Exchange/SSP/DMP 概念 程序化购买( Programmatic Buying):通过数字化.自动化.系统化的方式改造广告主.代理公司.媒体 ...

  5. 解决secureCRT 数据库里没有找到防火墙 '无' 此会话降尝试不通过防火墙进行连接。

    解决secureCRT 数据库里没有找到防火墙 '无' 此会话降尝试不通过防火墙进行连接.的方法 中文版的CRT由于汉化的问题(把null翻译成无了),导致每次打开都会有个防火墙的错误提示:数据库里没 ...

  6. JavaScript 方法扩展

    一.String全部替换方法 String.prototype.replaceAll = function(s1, s2){ return this.replace(new RegExp(s1, &q ...

  7. Python入门之Python的单例模式和元类

    一.单例模式 单例模式(Singleton Pattern)是一种常用的软件设计模式,该模式的主要目的是确保某一个类只有一个实例存在. 当你希望在整个系统中,某个类只能出现一个实例时,单例对象就能派上 ...

  8. mysql引擎问题

    今天遇到需要修改数据库引擎问题 /*查看支持的引擎*/ show engines; /*默认引擎*/ show variables like '%storage_engine%'; /*看某个表用了什 ...

  9. 用Win32 实现进度条

    转载:http://www.cctry.com/thread-238862-1-1.html #include <windows.h> #include <commctrl.h> ...

  10. P3709 大爷的字符串题

    题意 询问区间众数出现的次数 思路 唯有水题快人心 离散化+莫队 莫队一定要先加后减,有事会出错的 莫队维护区间众数: 维护两个数组,一个数组记录权值为x的出现次数,一个记录出现次数为x的数的个数 a ...