您当前的位置:首页 > 电脑百科 > 程序开发 > 语言 > JAVA

Java后端精选技术:谈谈 API 网关

时间:2019-08-03 15:40:45  来源:  作者:

背景

理论上,客户端可以直接向微服务发送请求,每个微服务都有一个公开的URL,该URL将映射到微服务的负载均衡器,由它负责在可用实例之间分发请求。但这种方式存在如下缺陷:

1. 客户端需求和微服务暴露的细粒度 API 不匹配

经常有一个业务调用很多个服务,假如客户端发送许多请求,这在公网上可能会很低效,而且会使客户端代码变得更复杂。

2. 服务使用的协议不是 Web 友好的

有的服务可能使用二进制 RPC(比如 thrift),有的服务可能使用 AMQP 消息传递协议。不管哪种协议都不是浏览器友好或防火墙友好的,最好是内部使用。在防火墙之外,应用程序应该使用诸如 HTTP 和 WebSocket 之类的协议。

3. 难重构

随着时间推移可能想要更改系统划分成服务的方式。例如,合并两个服务或者将一个服务拆分成两个或更多服务。如果客户端与微服务直接通信,那么执行这类重构就很困难。

由于以上问题,客户端与微服务直接通信很少是合理的,更好的方法是使用 API 网关,由 API 网关作为后端服务系统的唯一入口。它封装了系统内部架构,为每个客户端提供一个定制的 API 。由它负责服务请求路由、组合及协议转换。有的 API 网关还有其它职责,如身份验证、监控、负载均衡、缓存。

 

整体架构

完备的服务网关应该包括三大部分:API 网关、网关控制台、度量数据采集分析。实际形态各异,可以按需搭建,但肯定少不了 API 网关,网关控制台的功能职责可能会放到服务注册等地方而没有单独抽取出来,至于度量数据采集可能会在整个微服务架构中存一个通用的度量数据采集应用以监控所有类型应用。

 

API服务网关整体架构

API 网关的优缺点

1. 优点

封装了应用程序的内部结构。客户端只需要同网关交互,而不必调用特定的服务。API 网关为每一类客户端提供了特定的 API ,从而减少客户端与应用程序间的交互次数,简化客户端代码的处理。

2. 缺点

增加了一个必须开发、部署和维护的高可用组件。还有一个风险是 API 网关变成了开发瓶颈。为了暴露每个微服务,开发人员必须更新 API 网关。API 网关的更新过程要尽可能地简单,否则为了更新网关,开发人员将不得不排队等待。不过,虽然有这些不足,但对于大多数现实世界的应用程序而言使用 API 网关是合理的。

实现的技术

1. 开发语言

对于大多数应用程序而言,API 网关的性能和可扩展性通常都非常重要。因此,API 网关将构建在一个支持异步、I/O 非阻塞的平台上。JAVA系可以使用一种基于 NIO 的框架,比如Netty、Vertx、Spring Reactor ,还可以使用 Node.js、Nginx Plus。

2. 响应式编程

API 网关通过简单地将请求路由给合适的后端服务来处理部分请求,而通过调用多个后端服务并合并结果来处理其它请求。对于没有依赖关系的请求,API 网关应该并发执行以最小化响应时间。使用传统的异步回调方法编写 API 组合代码会陷入回调地狱。代码会变得混乱、难以理解、容易出错。可以使用响应式编程以一种声明式样式编写代码。比如 Scala 中的Future 、Java 8 中的 CompletableFuture 和 JavaScript 中的 Promise ,还有最初是微软为 .NET 平台开发的 Reactive Extensions(RX)。Netflix 创建了 RxJava for JVM ,专门用于他们的 API 网关。

3. 进程通信模型

微服务的应用程序必定是一个分布式系统,所以必须使用进程间的通信机制。有两种类型的进程间通信机制可供选择。一种是使用异步的、基于消息传递的机制。有些实现使用诸如JMS 或 AMQP 那样的消息代理,而其它的实现(如 Zeromq )则没有代理,服务间直接通信。另一种是诸如 HTTP 或 Thrift 那样的同步机制。通常,一个系统会同时使用异步和同步两种类型。它甚至还可能使用同一类型的多种实现。总之,API 网关需要支持多种通信机制。

4. 服务发现

API 网关需要知道它与之通信的每个微服务的位置(IP 地址和端口)。应用程序服务的位置是动态分配的。而且,单个服务的一组实例也会随着自动扩展或升级而动态变化。API 网关需要使用系统的服务发现机制,可以是服务器端发现,也可以是客户端发现。如果系统使用客户端发现,那么 API 网关必须能够查询服务注册中心,这是一个包含所有微服务实例及其位置的数据库。

Spring cloud 提供了服务注册和发现功能,如果需要自己实现,可以考虑用 Zookeeper 作为注册表,客户端用 Curator 。

5. 局部失败

在实现 API 网关时,还有一个问题需要处理,就是局部失败的问题。该问题在所有的分布式系统中都会出现,无论什么时候,当一个服务调用另一个响应慢或不可用的服务,就会出现这个问题。API 网关永远不能因为无限期地等待下游服务而阻塞。不过,如何处理失败取决于特定的场景以及哪个服务失败。如果缓存数据可用,那么 API 网关还可以返回缓存数据。数据可以由API网关自己缓存,也可以存储在像 redis 或 Memcached 那样的外部缓存中。通过返回默认数据或者缓存数据,API 网关可以确保系统故障不影响用户的体验。

在编写代码调用远程服务方面,Netflix Hystrix 是一个异常有用的库。Hystrix 会将超出设定阀值的调用超时。它实现了一个“断路器(circuit breaker)”模式,可以防止客户端对无响应的服务进行不必要的等待。如果服务的错误率超出了设定的阀值,那么 Hystrix 会切断断路器,在一个指定的时间范围内,所有请求都会立即失败。Hystrix 允许用户定义一个请求失败后的后援操作,比如从缓存读取数据,或者返回一个默认值。如果你正在使用 JVM,那么你绝对应该考虑使用 Hystrix 。而如果你正在使用一个非 JVM 环境,那么你应该使用一个等效的库。

6.参考实现方案

以上列出在 diy 这个 API 网关时需要考虑的点,以及参考的技术实现。下面是几种目前比较流行的 API 网关搭建的技术方案供参考,后续文章将给出这些方案搭建的例子

1)Nginx + Lua实现负载均衡、限流、服务发现等功能

2)使用 spring cloud 技术栈,其中 zuul 就是用作 API 网关的

3)Mashape 的开源 API 网关 Kong

7.网关控制台

提供 domain 管理、应用管理、服务授权、服务监控、统计和度量数据展示、查看服务全局视图等功能。服务消费者和服务提供者都要在网关控制台进行应用注册,控制台为每个应用分配应用id(AppId唯一)和应用密钥(appSecret)。注册时需要提供的信息:应用名称、应用描述、应用负责人相关信息。



Tags:API 网关   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
一 背景介绍下图是我从网络上找到的一个微服务架构的简单架构图,如图可见 API Gateway 在其中起到一个承上启下的作用,是关键组件。图片来源于网络在更通用的场景下我们会使用...【详细内容】
2020-10-14  Tags: API 网关  点击:(571)  评论:(0)  加入收藏
前言假设你正在开发一个电商网站,那么这里会涉及到很多后端的微服务,比如会员、商品、推荐服务等等。 那么这里就会遇到一个问题,APP/Browser怎么去访问这些后端的服务? 如果...【详细内容】
2020-04-11  Tags: API 网关  点击:(47)  评论:(0)  加入收藏
soul网关发布2.1.0版本 (做Java界最好的API-Gateway) 这是soul网关开源以来的最大的一次更新,收集了很多社区反馈的问题,进行了更新. 之前的文档不是很完善,使用成本较高,这里先...【详细内容】
2019-12-27  Tags: API 网关  点击:(124)  评论:(0)  加入收藏
背景理论上,客户端可以直接向微服务发送请求,每个微服务都有一个公开的URL,该URL将映射到微服务的负载均衡器,由它负责在可用实例之间分发请求。但这种方式存在如下缺陷:1. 客户...【详细内容】
2019-08-03  Tags: API 网关  点击:(355)  评论:(0)  加入收藏
▌简易百科推荐
面向对象的特征之一封装 面向对象的特征之二继承 方法重写(override/overWrite) 方法的重载(overload)和重写(override)的区别: 面向对象特征之三:多态 Instanceof关键字...【详细内容】
2021-12-28  顶顶架构师    Tags:面向对象   点击:(2)  评论:(0)  加入收藏
一、Redis使用过程中一些小的注意点1、不要把Redis当成数据库来使用二、Arrays.asList常见失误需求:把数组转成list集合去处理。方法:Arrays.asList 或者 Java8的stream流式处...【详细内容】
2021-12-27  CF07    Tags:Java   点击:(3)  评论:(0)  加入收藏
文章目录 如何理解面向对象编程? JDK 和 JRE 有什么区别? 如何理解Java中封装,继承、多态特性? 如何理解Java中的字节码对象? 你是如何理解Java中的泛型的? 说说泛型应用...【详细内容】
2021-12-24  Java架构师之路    Tags:JAVA   点击:(5)  评论:(0)  加入收藏
大家好!我是老码农,一个喜欢技术、爱分享的同学,从今天开始和大家持续分享JVM调优方面的经验。JVM调优是个大话题,涉及的知识点很庞大 Java内存模型 垃圾回收机制 各种工具使用 ...【详细内容】
2021-12-23  小码匠和老码农    Tags:JVM调优   点击:(12)  评论:(0)  加入收藏
前言JDBC访问Postgresql的jsonb类型字段当然可以使用Postgresql jdbc驱动中提供的PGobject,但是这样在需要兼容多种数据库的系统开发中显得不那么通用,需要特殊处理。本文介绍...【详细内容】
2021-12-23  dingle    Tags:JDBC   点击:(13)  评论:(0)  加入收藏
Java与Lua相互调用案例比较少,因此项目使用需要做详细的性能测试,本内容只做粗略测试。目前已完成初版Lua-Java调用框架开发,后期有时间准备把框架进行抽象,并开源出来,感兴趣的...【详细内容】
2021-12-23  JAVA小白    Tags:Java   点击:(11)  评论:(0)  加入收藏
Java从版本5开始,在 java.util.concurrent.locks包内给我们提供了除了synchronized关键字以外的几个新的锁功能的实现,ReentrantLock就是其中的一个。但是这并不意味着我们可...【详细内容】
2021-12-17  小西学JAVA    Tags:JAVA并发   点击:(11)  评论:(0)  加入收藏
一、概述final是Java关键字中最常见之一,表示“最终的,不可更改”之意,在Java中也正是这个意思。有final修饰的内容,就会变得与众不同,它们会变成终极存在,其内容成为固定的存在。...【详细内容】
2021-12-15  唯一浩哥    Tags:Java基础   点击:(17)  评论:(0)  加入收藏
1、问题描述关于java中的日志管理logback,去年写过关于logback介绍的文章,这次项目中又优化了下,记录下,希望能帮到需要的朋友。2、解决方案这次其实是碰到了一个问题,一般的情况...【详细内容】
2021-12-15  软件老王    Tags:logback   点击:(19)  评论:(0)  加入收藏
本篇文章我们以AtomicInteger为例子,主要讲解下CAS(Compare And Swap)功能是如何在AtomicInteger中使用的,以及提供CAS功能的Unsafe对象。我们先从一个例子开始吧。假设现在我们...【详细内容】
2021-12-14  小西学JAVA    Tags:JAVA   点击:(22)  评论:(0)  加入收藏
最新更新
栏目热门
栏目头条