一、前言

随着微服务的兴起,基于其业务耦合性低、负载能力强、服务边界清晰等优点,大家纷纷使用微服务架构来实现新系统或进行老系统的改造。微服务在带来诸多好处的同时,也有一些问题需要解决,比如:如何做到有效拆分、减少服务间调用,如何统一管理所有服务的接口,如何进行自动化部署等。本文阐述微服务的API网关的一些主要功能,并例举了几种常用的网关,最后结合spring cloud微服务框架对网关做一些简要的论述。

二、API网关简介

API网关,顾名思义,是统一管理API的一个网络关口、通道,是整个微服务平台所有请求的唯一入口,所有的客户端和消费端都通过统一的网关接入微服务,在网关层处理所有的非业务功能。下图为微服务架构的简单示意图,网关起到的作用一目了然。

三、API网关的作用

为微服务云平台提供统一的入口是API网关最主要的用途,除此之外,网关还可承担认证授权、访问控制、路由、负载均衡、缓存、日志、限流限额、转换、映射、过滤、熔断、注册、服务编排、API管理、监控、统计分析等等非业务性的功能。


所以实现或者选择一个好的API网关,是建设容器云和微服务体系中一个至关重要的事项。这也决定了API网关的部署,要尽可能的减少接触面,确保安全。下面介绍几个API网关的核心功能。

1)负载均衡

微服务架构一般都有一个注册中心,后端服务启动时候会将自己的服务地址注册到注册中心,并和注册中心保持心跳,网关用过监听注册中心来进行服务的发现,并根据一定的负载均衡算法(随机、轮询、权重、hash等)将客户端的请求尽量均衡地转发到后端的各个服务中。

2)服务熔断、重试及路由切换

和微服务的熔断道理一样,为了防止服务的雪崩效应,当检测到服务不可用时,需要进行快速失败。当某服务在短时间内多次发生调用失败,服务消费方的断路器会被断开。开路的断路器就像电路跳闸一样,阻止消费方向故障服务发送请求,直接返回失败或者执行消费方的降级逻辑。断路器通常在一定时间后关闭,在这期间可以为底层服务提供足够的空间来恢复。

当前服务调用失败时,可进行一定次数的重试,重试失败的情况下,网关还可以对指定个数实例的路由切换,保证后端服务的可用性。

3)限流

限流的主要目的是防止类似DDos的恶意攻击导致服务器短时间内收到大量请求而造成的服务瘫痪。因此需要在接口层面做流量的控制,API网关统计一个时间窗口内针对某服务的请求数量,如果超过一定的阈值,则应拒绝继续转发请求到后端服务。时间窗口是滑动窗口,下一个时间窗口到来时,计数器清零。可以使用Redis的单线程模型和高性能的并发性来保证高并发下计数器计数准确。

4)认证鉴权

单体应用中,一般用户登录后,服务端会将用户信息存入session中,然后返回给用户(客户端)一个cookie作为登录后调用其他业务接口的凭证。而在微服务架构下,服务被拆分成多个实例,单体应用中的模式就很难试用,于是需要把鉴权的业务从各服务中抽离出来,单独建立一个权限认证服务,利用API网关入口作为切面拦截。网关拦截用户请求,获取请求中附带的用户身份信息,调用认证授权中心的服务,对请求者做身份认证,即确认当前访问者确实是其所声称的身份,检查该用户是否有访问该后台服务的权限。


目前主流的认证鉴权方案有2种。

第一种是引入Redis做分布式会话,即用户登录成功后,将用户身份、权限信息存入Redis,以一个唯一ID作为Key,并设置信息在Redis里的失效时间。这个唯一ID的Key将返回给客户端,客户端可以放入Cookie,sessionStorage等处做本地存储。下次访问的时候,将这个唯一ID放入请求参数中一起发送(一般放入Header)。服务端通过检查Redis里有无这个ID来判断用户是否登录,获取用户身份和权限信息。客户端如果长时间没有操作,则存储在Redis里会话信息过期自动删除。客户端每访问一次服务端,需刷新一次会话信息的过期时间,避免固定过期时间带来的低用户体验。

第二种是JWT,即Java Web Token。用户登录成功后,服务端向客户端返回的唯一ID不再是无意义的字符串,而是包含了用户身份、权限、失效时间等信息的加密字符串。并且这个字符串包含数字签名,服务端可对这个字符串做数字签名验签,确保该字符串未经篡改和伪造。相比分布式会话方案,JWT虽省去了Redis存储,但是每次访问都要做数字签名验证,增加了CPU的资源损耗。

5)灰度发布

灰度发布是服务发布时比较好的一种升级方式,它可以根据客户端的实际情况(版本、IP端等)进行请求分流,将一小部分测试者的请求切到新版本服务上,万一有问题也能及时定位修复,且不影响线上老版本的使用。

四、常见的几种api网关

目前比较常见的几种开源的API网关有以下几种:Kong、Treafik、Ambassador、Tyk、Zuul ,下面对这几种网关做一下简单的介绍和对比。

Kong是一个在 Nginx 中运行的Lua应用程序,并且可以通过lua-nginx模块实现,Kong不是用这个模块编译Nginx,而是与 OpenResty 一起发布,OpenResty已经包含了lua-nginx-module,OpenResty不是Nginx的分支,而是一组扩展其功能的模块。

它的核心是实现数据库抽象,路由和插件管理,插件可以存在于单独的代码库中,并且可以在几行代码中注入到请求生命周期的任何位置。

Traefik是一个现代HTTP反向代理和负载均衡器,可以轻松部署微服务,Traeffik 可以与您现有的组件(Docker、Swarm,Kubernetes,Marathon,Consul,Etcd,…)集成,并自动动态配置。

Ambassador是一个开源的微服务 API 网关,建立在 Envoy 代理之上,为用户的多个团队快速发布,监控和更新提供支持,支持处理 Kubernetes ingress controller 和负载均衡等功能,可以与 Istio 无缝集成。

Tyk是一个开源的、轻量级的、快速可伸缩的 API 网关,支持配额和速度限制,支持认证和数据分析,支持多用户多组织,提供全RESTful API。基于go编写。

Zuul是一种提供动态路由、监视、弹性、安全性等功能的边缘服务。Zuul 是Netflix出品的一个基于JVM路由和服务端的负载均衡器。


由上述对比表格中可以看出:从开源社区活跃度来看,无疑是Kong和Traefik较好;从成熟度来看,较好的是Kong、Tyk、Traefik;从性能角度来看,Kong要比其他几个领先一些;从架构优势的扩展性来看,Kong、Tyk有丰富的插件,Ambassador也有插件但不多,而Zuul是完全需要自研,但Zuul由于与Spring Cloud深度集成,使用度也很高,近年来Istio服务网格的流行,Ambassador因为能够和Istio无缝集成也是相当大的优势。

五、spring cloud

目前能和spring cloud体系紧密集成的有两种API网关:zuul(zuul1)和spring cloud gateway。zuul网关再上面有提到,spring cloud gateway是spring官方推出的用于替代zuul的新组建。这里对于如何集成zuul或spring cloud gateway不做讲述,只对这两种网关做一个简单的阐述与比较。

先来看下zuul,目前zuul有两个版本:zuul1和zuul2,目前spring cloud只集成了zuul1,zuul2是Netflix在2018年5月推出,它最大的特点就是支持异步调用?(zuul1仅支持同步) ,可惜springcloud暂时没有计划集成zuul2,而且还推出spring cloud gateway来替代zuul1。

来看下zuul1的编程模型(同步阻塞)

本质上就是一个同步 Servlet,每来一个请求,zuul会专门分配一个线程去处理,然后转发到后端服务,后端再启线程处理请求,后端处理时网关的线程会阻塞,当请求数量比较大时,很容易造成线程池被沾满而无法接受新的请求,Netflix 为此还专门研发了Hystrix熔断组件来解决慢服务耗尽资源问题。

zuul2的编程模型(异步非阻塞)

zuul2是基于Netty实现的异步非阻塞编程模型,一般异步模式的本质都是使用队列 Queue(或称总线 Bus)。网关中会有一个队列专门处理用户请求,一个队列专门负责后端服务调用,中间有个事件环线程 (Event Loop Thread)同时监听两个队列,它的主要作用是将请求转发给后端,并将后端服务的处理结果返回给客户端,用队列的形式减轻了前端请求数量的压力。

zuul1和zuul2对比:

总结:建议是在生产环境中使用 zuul1

Zuul1 同步编程模型简单,门槛低,开发运维方便,容易调试定位问题。Zuul2 门槛高,调试不方便。

Zuul1 监控埋点容易,比如和调用链监控工具 CAT 集成,如果你用 Zuul2 的话,CAT 不好埋点是个问题。

Zuul1 已经开源超过 6 年,稳定成熟,坑已经被踩平。Zuul2 刚开源很新,实际落地案例不多,难说有 bug 需要踩坑。

大部分公司达不到 Netflix 那个量级,Netflix 是要应对每日千亿级流量,它们才挖空心思搞异步,一般公司亿级可能都不到,Zuul1 绰绰有余。

Zuul1 可以集成 Hystrix 熔断组件,可以部分解决后台服务慢阻塞网关线程的问题。

Zuul1 可以使用 Servlet 3.0 规范支持的 AsyncServlet 进行优化,可以实现前端异步,支持更多的连接数,达到和 Zuul2 一样的效果,但是不用引入太多异步复杂性。

Spring Cloud Gateway构建于 Spring 5+,基于 Spring Boot 2.x 响应式的、非阻塞式的 API。同时,它支持 websockets,和 Spring 框架紧密集成,开发体验相对来说十分不错。由于zuul2没有被spring cloud所集成,所以拿zuul1与spring cloud gateway做一些简单的比较。

spring官方给出的性能测试数据:

从表中可以看出,spring cloud gateway在性能上还是胜zuul一筹的,而且上手也简单。

一些API网关(Zuul 1)是阻塞的,另外一些(Zuul 2、Linkerd、Envoy)是非阻塞的。阻塞架构对开发和跟踪请求友好,但是阻塞可能产生扩展性问题。非阻塞架构对于团队开发和跟踪更复杂,但是有更好的可扩展和弹性。如何选择还是需要根据实际情况再做抉择。

文章来源:微服务网关

897-了解微服务网关相关推荐

  1. 你的微服务网关还只在用负载均衡吗?

    随着业务场景日益复杂,我们经常采用微服务架构来进行松耦合,但由于系统和服务的细分,导致系统结构变得非常复杂,微服务网关作为分散在各个业务系统微服务的API聚合点和统一接入点,需要担负整个流量管控的职责 ...

  2. 微服务网关Zuul迁移到Spring Cloud Gateway

    https://juejin.im/post/5ba8daa56fb9a05cfe486ebf 背景 在之前的文章中,我们介绍过微服务网关Spring Cloud Netflix Zuul,前段时间有 ...

  3. 个推微服务网关架构实践

    作者:个推应用平台基础架构高级研发工程师 阿飞 在微服务架构中,不同的微服务可以有不同的网络地址,各个微服务之间通过互相调用完成用户请求,客户端可能通过调用N个微服务的接口完成一个用户请求.因此,在客 ...

  4. Bumblebee微服务网关之并发限制

    对于服务应用来说支持的并发越高越好,但很多时候资源有限,超负载的并发则会给整体应用带来更大的危险性(更何况有些并发来源是恶意的).作为微服务网关应该具有一定的挡洪作用,这样可以一定程度保障后台逻辑服务 ...

  5. Bumblebee微服务网关之负载策略

    作为一个微服务网关,提供不同负载策略配置是一项非常重要的主要功能:在这方向Bumblebee提供了非常好的支持.Bumblebee可以针对不同路径制定各自的负载策略,更重要的是这些调整都可以在网关运行 ...

  6. Bumblebee微服务网关之请求统一验证

    对于微服务网关来说,统一请求验证是一个比较重要和常用的功能,通过网关验证后台服务就无须关注请求验证:对于多语言平台的服务而言制定验证方式和变更验证配置都是一件比较繁琐和工作量大的事情.Bumblebe ...

  7. 微服务网关Ocelot

    微服务网关是微服务架构中的核心组件,它是客户端请求的门户,它是调用具体服务端的桥梁.下面我们将使用开源项目Ocelot(https://github.com/geffzhang/Ocelot)搭建一款 ...

  8. 基于netty的微服务网关_基于Rx-netty和Karyon2的云就绪微服务

    基于netty的微服务网关 Netflix Karyon提供了一个干净的框架来创建可用于云的微服务. 在您的组织中,如果您使用包含Eureka的Netflix OSS堆栈进行服务注册和发现,使用Arc ...

  9. 微服务网关Gateway

    使用场景 不同的微服务一般会有不同的网络地址,而外部客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信,会有以下的问题: 客户端会多次请求不同的微服务,增加了客户端 ...

  10. spring cloud gateway 网关_微服务网关Spring Cloud Gateway全搞定

    一.微服务网关Spring Cloud Gateway 1.1 导引 文中内容包含:微服务网关限流10万QPS.跨域.过滤器.令牌桶算法. 在构建微服务系统中,必不可少的技术就是网关了,从早期的Zuu ...

最新文章

  1. linux开启FTP以及添加用户配置权限,只允许访问自身目录,不能跳转根目录
  2. Graph Search就是语义搜索
  3. 转载--CentOS 6.3下部署LVS(NAT)+keepalived实现高性能高可用负载均衡
  4. 32位程序调用64位dll_电脑系统怎样区分32位和64位
  5. 区块链架构、跨链和演进
  6. VTK:旋转球体用法实战
  7. Android进程优先级architecture : low memory killer (/system/core/lmkd/lmkd.c)
  8. ASP.NET vs MVC vs WebForms
  9. 实战演示 bacula 软件备份功能
  10. vue.js点击更多加载更多数据,双数组合并
  11. 【英语学习】【Level 07】U07 Stories of my Life L6 An experience worth remembering
  12. matlab 垂直边缘检测,matlab 边缘检测
  13. Navicat for PostgreSQL 怎么维护数据库和表
  14. 数据结构实验:数制转换
  15. excel使用教程_有哪些超好用、高质量的Excel学习网站?
  16. 学习Android studio时的报错Binary XML file line #10: Error inflating class fragment
  17. 共同创业五年,技术总监却突然就这么离职了
  18. [Pytorch系列-24]:神经网络基础 - 单个无激活函数的神经元实现简单线性回归 - 1
  19. win10pe 找不到硬盘 戴尔_要是遇到这样 开机找不到硬盘开不了机怎么办_解决方法教程一览-...
  20. php weixin provider,14、ABPZero系列教程之拼多多卖家工具 新建微信公众号模块

热门文章

  1. 用Python怎么多赚钱?6种办法用上 让你过上挣钱的好日子
  2. (14)[驱动开发]配置环境 VS2019 + WDK10 写 xp驱动
  3. c语言程序设计上海理工,2017年上海理工大学医疗器械与食品学院854C程序设计考研题库...
  4. 3万字BI系统整体建设解决方案
  5. 0205函数的微分-导数与微分-高等数学
  6. 仰望星星的孩子-2014年终总结
  7. java基于ssm+vue+elementui楼盘房屋销售系统 前后端分离
  8. linux kernel 内存相关记录
  9. 什么硬盘保存时间长 硬盘的保存时间
  10. 地下迷宫探索 java_Java 8:探索可能性