赞
踩
在微服务架构中,每个服务都是一个可以独立开发和运行的组件,而一个完整的微服务架构由一系列独立运行的微服务组成。其中每个服务都只会完成特定领域的功能,比如订单服务提供与订单业务场景有关的功能、商品服务提供商品展示功能等。各个微服务之间通过轻量级通信机制REST API或者RPC完成通信。
实现微服务之后在某些层面会带来一定的影响,比如,一个用户查看一个商品的详情,对于客户端来说,可能需要调用商品服务、评论服务、库存服务、营销服务等多个服务来完成数据的渲染。如图10-1所示,在这个场景中,客户端虽然能通过调用多个服务实现数据的获取,但是会存在一些问题,比如:
网关可以用来解决这个问题,如图10-2所示,在客户端与服务端之间增加了一个API网关。整体来看,网关有点类似于门面,所有的外部请求都会先经过网关这一层。
对于商品详情展示的场景来说,增加了API网关之后,在API网关层可以把后端的多个服务进行整合,然后提供唯一的业务接口,客户端只需要调用这个接口即可完成数据的获取及展示。在网关中会再消费后端的多个微服务,进行统一的整合,给客户端返回唯一的响应。
网关不仅只是做一个请求的转发及服务的整合,有了网关这个统一的入口之后,它还能提供以下功能。
下面针对上述网关作用的分析,选择几种常见的方案进行详细说明。
统一认证鉴权包含如下两部分。
在单体应用中,客户端身份认证及访问权限的控制比较简单,只需要在服务端通过session保存该用户信息即可。但是在微服务架构下,单体应用被拆分成多个微服务,鉴权的过程就会变得很复杂。
当然,对于第一个问题,目前已经有非常多的成熟解决方案了,比如AccessToken、Oauth(开放API)等。对于第二个问题,我们可以把鉴权的功能抽离出一个统一认证服务,所有的微服务在被访问之前,先访问该认证服务进行鉴权。这种解决方案看似合理,但是在实际应用中,一个业务场景中可能会调用多个微服务,就会造成一次请求需要进行多次鉴权操作,增加了网络通信开销。
如图10-3所示,增加API网关之后,在网关层进行请求拦截,获取请求中附带的用户身份信息,调用统一认证中心对请求进行身份认证,在确认了身份之后再检查是否有资源的访问权限。
互联网公司的产品有一个特点,就是迭代非常快,很多公司会采用一周发布一个版本的选代模式。在这种高频率的迭代模式下,往往会伴随着一些风险,比如:
为了规避这些问题,对于有较大的功能性改动的版本一般都会采取灰度发布(又名金丝雀发布)的方式来实现平滑过渡。
所谓灰度发布,就是指将要发布的功能先开放给一小部分用户使用,把影响范围控制在一个非常小的范围比如A/B Test就是一种灰度发布方式,即一部分用户继续使用A功能,另外一小部分用户使用新的B功能。通过对使用B功能的用户进行满意度调查,以及对新发布的代码的性能和稳定性指标进行评测,逐步放大该新版本的投放,直到全量或者回滚该版本。
对于应用系统来说,无非就是将新的功能发布在特定的灰度机器上,然后根据设定的规则将部分请求路由到灰度服务器上。
网关是所有客户端请求的入口,因此在网关层可以通过灰度规则进行部分流量的路由,从而实现灰度发布。
如图10-4所示,网关对请求进行拦截之后,会根据分流引擎配置的分流规则进行请求的路由。
通过前面的分析可以发现,网关的本质应该是对请求进行路由转发,以及对请求进行前置和后置的过滤。
常见的开源API网关实现方案有很多,比如OpenResty、Zuu、GateWay、Orange、Kong、Tyk等,下面
OpenResty实际上是由Nginx与Lua集成的一个高性能Web应用服务器,它的内部集成了大量优秀的Lua库、第三方模块。并且OpenResty团队自己研发了很多优秀的Nginx模块,开发人员可以使用Lua脚本来调用Nginx支持的C模块及Lua模块。
简单来说**,OpenResty本质上就是将Lua嵌入Nginx中,在每一个Nginx的进程中都嵌入了一个LuaJIT虚拟机来执行Lua脚本**。
对于OpenResty来说,它本质上仍然是Nginx服务器,可以实现反向代理和负载均衡。但是OpenResty为什么能够实现网关功能呢?
前面我们提到过,网关的本质是对请求进行路由转发及过滤,这意味着OpenResty在接收到客户端的请求时,同样可以拦截请求进行前置和后置的处理。事实上,OpenResty确实支持这种操作,它可以在不同的阶段来挂载Lua脚本实现不同阶段的自定义行为。如图10-5所示,可以看到init_by_lua、init_worker by_lua、setby_ua等11个指令,OpenResty实现网关功能的核心就是在这11个步骤中挂载Lua脚本来实现功能的扩展。
一个请求进入OpenResty之后,会根据请求所在的不同阶段按照如图10-5所示的流程执行不同的指令,每个指令的作用如下。
Zuul是Netflix开源的微服务网关,它的主要功能是路由转发和过滤。大部分读者接触到Zuul应该是在SpringCloud Netflix生态中,它被整合到Spring Cloud中为微服务架构提供API网关的功能。
如图10-6所示,Zuul的核心由一系列过滤器组成,它定义了4种标准类型的过滤器,这些会对应请求的整个生命周期。
Spring Cloud Gateway是Spring官方团队研发的API网关技术,它的目的是取代Zuul为微服务提供一种简单高效的API网关。
一般来说,Spring团队不会重复造轮子,为什么又研发出一个Spring Cloud Gateway呢?有以下几方面原因。
Reactor 是一个用于JVM的完全非阻塞的响应式编程框架,具备高效的需求管理(即对 “背压(backpressure)”的控制)能力。它与 Java 8 函数式 API 直接集成Reactor 是一个用于JVM的完全非阻塞的响应式编程框架,具备高效的需求管理(即对 “背压(backpressure)”的控制)能力。它与 Java 8 函数式 API 直接集成,比如 CompletableFuture, Stream, 以及 Duration。它提供了异步序列 API Flux(用于[N]个元素)和 Mono(用于 [0|1]个元素),并完全遵循和实现了“响应式扩展规范”(Reactive Extensions Specification)。
Reactor 的 reactor-ipc 组件还支持非阻塞的进程间通信(inter-process communication, IPC)。 Reactor IPC 为 HTTP(包括 Websockets)、TCP 和 UDP 提供了支持背压的网络引擎,从而适合 应用于微服务架构。并且完整支持响应式编解码(reactive encoding and decoding)。
<dependencyManagement> <dependencies> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-bom</artifactId> <version>2023.0.0</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-core</artifactId> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-test</artifactId> <scope>test</scope> </dependency> </dependencies>
响应式编程是一种关注于数据流(data streams)和变化传递(propagation of change)的异步编程方式。 这意味着它可以用既有的编程语言表达静态(如数组)或动态(如事件源)的数据流。
参考:https://blog.csdn.net/qq_63438013/article/details/136461257
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。