微服务网关优雅降级(微服务 网关)

网友投稿 282 2022-12-31


本篇文章给大家谈谈微服务网关优雅降级,以及微服务 网关对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。 今天给各位分享微服务网关优雅降级的知识,其中也会对微服务 网关进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

微信后台如何做的过载保护

首先要谈到架构,微信后台系统的模型大致理解为三层架构,接入层(proxy)、逻辑层(CGI)、存储层(后台模块)。啥意思呢微服务网关优雅降级?由接入层mmproxy调用逻辑层的CGI,比如摇一摇或者发消息的CGI,逻辑层再和存储层通信,比如存取账户信息,文件,地址信息等等。这是常规主流的架构没有什么特别需要说明的了,这边采用的是微服务架构,通信使用RPC框架,调用下级模块过多,就有 高扇出 问题。

我们先来理一下过载可能导致的一些现象。假设后台模块系统极限请求量是60万,我们知道当实际请求量超过这个数值就会过载,那么过载会发生什么情况?是不是发送了70万请求过来,只有60万之外的那10万请求不能被处理?答案显然不是,实际情况要比这个糟很多。很显然系统一旦过载,可能就只能正常处理20万的请求,原来的60万极限值处理能力是保不住的,甚至还有可能雪崩,直至毫无处理能力。当然,这里面的原因有很多,比如无效响应,失败重试,级联传递等等。

假如一时间好多人发送了摇一摇请求,这些请求都依次入队准备去调用寻找同摇好友的CGI并等待响应结果。但是队列很长,假设这些请求的超时时间是5秒,等待时间如果6秒过长就会导致RPC超时,一旦超时调用方可能直接关闭不再等待响应,等队列排到后执行完逻辑返回的响应调用方此时并不接收也等于是属于无效的响应了。来举个栗子,春运快到了,你挤在车站排队买车票,假设最后一班发车只有60分钟了,窝了个大叉,当你排队了半天到达售票窗口时已经用时80分钟了,这时候售票员再给你吐出一张车票已经毫无意义了,车都跑了。这也叫“无效输出”。

当然除了大部分无效的响应处理耗走了资源,别忘了还有失败重试。一般RPC框架都会设置失败重试机制,当请求得不到响应调用端会重试,如果一时间失败过多将会导致短时间内大量重试请求的发起,导致进一步过载,无疑是对本已经并无富裕的系统负载雪上加霜,滚雪球效应。

由于采用微服务架构,各模块之间的调用相互影响。由于服务依赖的复杂性当前模块的雪崩会导致上游模块的变慢,性能下降,如果此时上游模块也开始过载,继续向上级联,从而导致整个系统崩溃。怎么理解呢?假设一个餐厅里的2个厨师,A桌定了2个大菜烹饪时间很长,那么就会影响传菜员的上菜速度,传菜员要等待,假设全店传菜员有限只有2个都在等厨师出A桌的2个菜后才能去服务其微服务网关优雅降级他桌,这个时候就影响了整个餐厅的顾客的用餐速度,最终可能导致好几桌的顾客都吃不上菜且骂骂咧咧跑了。其实这个在Hystrix里采用了资源隔离来解决这个问题,即一个传菜员只服务于一桌,A服务员只服务A桌,B服务B桌,A慢的话就A这一桌慢,B桌的传菜员只传微服务网关优雅降级他B桌的菜哪怕闲着玩手机也不理其他桌。

谈完原因谈解决方法。该怎么处理呢?其实Hystrix的这套思想很好了,基本思想核心也相似,但今天主要是谈微信后台实践的解决方案。

常见的过载保护方法

1.减少需求:调用端的请求限速

2.避免响应超时:根据调用端超时,设置T超时时间微服务网关优雅降级;控制队列长度,容纳T超时时间内的请求。

调用端限速

限多了,服务器能力没有充分利用,限少了,过载问题没解决。而且过载时,响应时间会阶梯式上涨,这样超时时间就会 波动 ,队列长度难设定。虽然极限能力 绝对值 比较难找,但服务器最佳负载点容易找。所以过载保护的目标:尽量让服务端维持在最佳负载点, 让有效输出接近最佳吞吐 。

古希腊水钟

那如何维持在最佳负载点呢?水钟的启示:反馈控制系统。

如图,图中的浮子上浮,上水箱下水减速,相反如果下沉则加速上水箱下水。浮子起到了稳定液位的作用,使得中水箱的水位相对稳定,往下水箱的滴水速率自然也相对稳定,使得计时相对准确。

那么OK啦,也就搞一个像浮子一样的机制,多了及早拒绝,降低通过率,少了缓慢提升通过率。

1、通过反馈动态调整通过率:及早拒绝

根据CPU使用率和队列等待时间,控制输入,这里有个算法FastReject V1计算的是 通过率 ( 过载时 按一定概率通过请求),算法公式暂不展示,主要讲究的是快降慢升。触发降低通过率的场景比如有:比如每隔一秒统计一下队列等待时间,超过n豪秒就降低通过率,或者当前CPU使用率超过阈值(比如85%)也降低通过率。及时反馈控制,不让队列等很久等到轮到自己被处理后前端已经关闭了请求,导致无效的响应。这样请求要么超载被直接拒绝,要么是有效响应,保持原来的处理能力,不让过载雪崩。这就是出队时再判断超时还是入队时就判断的区别。记得这个在Hystrix限流熔断里叫做“降级返回”。

2、同时计算业务的优先级权重:优先服务重要业务

这有点类似早高峰的公交专用道了,由公交车优先通行。实现其实也比较简单,为每个业务(CGI)指定一个优先级(这个优先级可以由后台根据业务实际配置),每个请求带个是属于什么业务的标识,FastReject对每个业务优先级维持一个通过率,低优先级通过率降为0,开始拒绝更高优先级。比如聊天消息发送的优先级为1,上传文件为2,数字越小优先级越高。当上传文件的通过率降为0后开始降聊天消息的通过率,这样保证了优先服务重要业务。这个在Hystrix里类似服务的“优雅降级”。

这里的优先级信息传递用的是RPC COOKIE。因为RPC框架支持cookie,那就刚好借用类似http cookie 的思想,请求/响应包预留cookie 字段,请求携带cookie跨模块自动传递。比如CGI_ID标识或者下面分组提到的用户ID。

3、用户分组:保证要不过第一次就不过

注意了,这里的内容大家可能会比较感兴趣。这里要从刚刚上面的那个优先级说起。我们知道,微服务架构各模块之间的调用相互影响,如果一个请求服务端需要请求多个模块才能处理完逻辑返回结果。那假如说请求R需要经过A模块请求B模块,B模块再请求C,B再请求D等等(注意这里B需要同时请求C、D两个模块获取结果),那么如果请求通过了A模块的通过率,C模块的通过率,到D模块没通过,那么前面的处理是不是都白费了,又违背了我们之前所做的及时拒绝无效响应的原则。那怎么解决呢?这里采用了用户分组的方式。举个例子,比如现在根据QQ号对用户进行分组,从0-9取尾号散列分为10组。QQ号为123的请求过来,首先用户是被分到3组的,如果在C模块被拒绝,那么该用户乃至该组的其他用户直接在D模块或者后续E,F等模块的调用都会被全部拒绝,这就是按组拒绝。保证一个用户要不过第一次请求就不过,不会说在聊天聊一半发不了消息了或者消息在中途某个服务才开始失败。 用户分组思想类似单双号限行。

这里有个有趣的事情,比如某用户被分到3组,3组被拒,那么他是不是每次过来都是被拒的,这要是抢红包那你不是会直呼“不公平”。所以这里做个小调整,如果这里每隔一段时间变换散列算法,前一分钟123可能是3组,后面可能是7组,这样来解决同一个用户每次来都被拒的情况,而其他用户都不会被拒的情况,也算是公平了。

4、让调用端也带FastReject接收服务端反馈:服务不行调用端就直接不发起请求了

这一点也很好理解,RPC将每次返回信息也反馈给调用端,调用端在调RPC前先自我检查,看看服务是不是已经不行了,如果不行了就干脆直接不发起请求过来了,避免请求过多。这一点有点类似Hystrix的熔断器机制,接收反馈并自动作熔断操作,服务降级。

总结:实际上,这和Hystrix思想其实大同小异,可以看下 《通俗一点讲“限流熔断之Hystrix”》 就会发现太多的异曲同工之妙。就到这里,说好的浅谈辄止的,感谢品阅~~。

恭祝大家新年快乐!万事大吉!

相关文献:

《Overload control for scaling WeChat microservices》

《10亿红包从天而降,揭秘微信摇一摇背后的技术细节》

微服务网关Zuul

统一接入:智能路由、AB测试、灰度测试、负载均衡、容灾处理、日志埋点
流量监控:限流处理、服务降级
安全防护:鉴权处理、监控、机器网络隔离

便于直观查看Zuul的路径和微服务的映射。
(3)自定义过滤器:

(4)禁用过滤器

API网关从入门到放弃

假设你正在开发一个电商网站微服务网关优雅降级,那么这里会涉及到很多后端的微服务微服务网关优雅降级,比如会员、商品、推荐服务等等。

那么这里就会遇到一个问题微服务网关优雅降级,APP/Browser怎么去访问这些后端的服务? 如果业务比较简单的话微服务网关优雅降级,可以给每个业务都分配一个独立的域名(https://service.api.company.com),但这种方式会有几个问题:

更好的方式是采用API网关,实现一个API网关接管所有的入口流量,类似Nginx的作用,将所有用户的请求转发给后端的服务器,但网关做的不仅仅只是简单的转发,也会针对流量做一些扩展,比如鉴权、限流、权限、熔断、协议转换、错误码统一、缓存、日志、监控、告警等,这样将通用的逻辑抽出来,由网关统一去做,业务方也能够更专注于业务逻辑,提升迭代的效率。

通过引入API网关,客户端只需要与API网关交互,而不用与各个业务方的接口分别通讯,但多引入一个组件就多引入了一个潜在的故障点,因此要实现一个高性能、稳定的网关,也会涉及到很多点。

API 注册

业务方如何接入网关?一般来说有几种方式。

协议转换

内部的API可能是由很多种不同的协议实现的,比如HTTP、Dubbo、GRPC等,但对于用户来说其中很多都不是很友好,或者根本没法对外暴露,比如Dubbo服务,因此需要在网关层做一次协议转换,将用户的HTTP协议请求,在网关层转换成底层对应的协议,比如HTTP - Dubbo, 但这里需要注意很多问题,比如参数类型,如果类型搞错了,导致转换出问题,而日志又不够详细的话,问题会很难定位。

服务发现

网关作为流量的入口,负责请求的转发,但首先需要知道转发给谁,如何寻址,这里有几种方式:

服务调用

网关由于对接很多种不同的协议,因此可能需要实现很多种调用方式,比如HTTP、Dubbo等,基于性能原因,最好都采用异步的方式,而Http、Dubbo都是支持异步的,比如apache就提供了基于NIO实现的异步HTTP客户端。

因为网关会涉及到很多异步调用,比如拦截器、HTTP客户端、dubbo、redis等,因此需要考虑下异步调用的方式,如果基于回调或者future的话,代码嵌套会很深,可读性很差,可以参考zuul和spring cloud gateway的方案,基于响应式进行改造。

优雅下线

性能

网关作为所有流量的入口,性能是重中之重,早期大部分网关都是基于同步阻塞模型构建的,比如Zuul 1.x。但这种同步的模型我们都知道,每个请求/连接都会占用一个线程,而线程在JVM中是一个很重的资源,比如Tomcat默认就是200个线程,如果网关隔离没有做好的话,当发生网络延迟、FullGC、第三方服务慢等情况造成上游服务延迟时,线程池很容易会被打满,造成新的请求被拒绝,但这个时候其实线程都阻塞在IO上,系统的资源被没有得到充分的利用。另外一点,容易受网络、磁盘IO等延迟影响。需要谨慎设置超时时间,如果设置不当,且服务隔离做的不是很完善的话,网关很容易被一个慢接口拖垮。

而异步化的方式则完全不同,通常情况下一个CPU核启动一个线程即可处理所有的请求、响应。一个请求的生命周期不再固定于一个线程,而是会分成不同的阶段交由不同的线程池处理,系统的资源能够得到更充分的利用。而且因为线程不再被某一个连接独占,一个连接所占用的系统资源也会低得多,只是一个文件描述符加上几个监听器等,而在阻塞模型中,每条连接都会独占一个线程,而线程是一个非常重的资源。对于上游服务的延迟情况,也能够得到很大的缓解,因为在阻塞模型中,慢请求会独占一个线程资源,而异步化之后,因为单条连接所占用的资源变的非常低,系统可以同时处理大量的请求。

如果是JVM平台,Zuul 2、Spring Cloud gateway等都是不错的异步网关选型,另外也可以基于Netty、Spring Boot2.x的webflux、vert.x或者servlet3.1的异步支持进行自研。

缓存

对于一些幂等的get请求,可以在网关层面根据业务方指定的缓存头做一层缓存,存储到Redis等二级缓存中,这样一些重复的请求,可以在网关层直接处理,而不用打到业务线,降低业务方的压力,另外如果业务方节点挂掉,网关也能够返回自身的缓存。

限流

限流对于每个业务组件来说,可以说都是一个必须的组件,如果限流做不好的话,当请求量突增时,很容易导致业务方的服务挂掉,比如双11、双12等大促时,接口的请求量是平时的数倍,如果没有评估好容量,又没有做限流的话,很容易服务整个不可用,因此需要根据业务方接口的处理能力,做好限流策略,相信大家都见过淘宝、百度抢红包时的降级页面。

因此一定要在接入层做好限流策略,对于非核心接口可以直接将降级掉,保障核心服务的可用性,对于核心接口,需要根据压测时得到的接口容量,制定对应的限流策略。限流又分为几种:

稳定性

稳定性是网关非常重要的一环,监控、告警需要做的很完善才可以,比如接口调用量、响应时间、异常、错误码、成功率等相关的监控告警,还有线程池相关的一些,比如活跃线程数、队列积压等,还有些系统层面的,比如CPU、内存、FullGC这些基本的。

网关是所有服务的入口,对于网关的稳定性的要求相对于其他服务会更高,最好能够一直稳定的运行,尽量少重启,但当新增功能、或者加日志排查问题时,不可避免的需要重新发布,因此可以参考zuul的方式,将所有的核心功能都基于不同的拦截器实现,拦截器的代码采用Groovy编写,存储到数据库中,支持动态加载、编译、运行,这样在出了问题的时候能够第一时间定位并解决,并且如果网关需要开发新功能,只需要增加新的拦截器,并动态添加到网关即可,不需要重新发布。

熔断降级

熔断机制也是非常重要的一项。若某一个服务挂掉、接口响应严重超时等发生,则可能整个网关都被一个接口拖垮,因此需要增加熔断降级,当发生特定异常的时候,对接口降级由网关直接返回,可以基于Hystrix或者Resilience4j实现。

日志

由于所有的请求都是由网关处理的,因此日志也需要相对比较完善,比如接口的耗时、请求方式、请求IP、请求参数、响应参数(注意脱敏)等,另外由于可能涉及到很多微服务,因此需要提供一个统一的traceId方便关联所有的日志,可以将这个traceId置于响应头中,方便排查问题。

隔离

比如线程池、http连接池、redis等应用层面的隔离,另外也可以根据业务场景,将核心业务部署带单独的网关集群,与其他非核心业务隔离开。

网关管控平台

这块也是非常重要的一环,需要考虑好整个流程的用户体验,比如接入到网关的这个流程,能不能尽量简化、智能,比如如果是dubbo接口,我们可以通过到git仓库中获取源码、解析对应的类、方法,从而实现自动填充,尽量帮用户减少操作;另外接口一般是从测试-预发-线上,如果每次都要填写一遍表单会非常麻烦,我们能不能自动把这个事情做掉,另外如果网关部署到了多个可用区、甚至不同的国家,那这个时候,我们还需要接口数据同步功能,不然用户需要到每个后台都操作一遍,非常麻烦。

这块个人的建议是直接参考阿里云、aws等提供的网关服务即可,功能非常全面。

其他

其他还有些需要考虑到的点,比如接口mock,文档生成、sdk代码生成、错误码统一、服务治理相关的等,这里就不累述了。

目前的网关还是中心化的架构,所有的请求都需要走一次网关,因此当大促或者流量突增时,网关可能会成为性能的瓶颈,而且当网关接入的大量接口的时候,做好流量评估也不是一项容易的工作,每次大促前都需要跟业务方一起针对接口做压测,评估出大致的容量,并对网关进行扩容,而且网关是所有流量的入口,所有的请求都是由网关处理,要想准确的评估出容量很复杂。可以参考目前比较流行的ServiceMesh,采用去中心化的方案,将网关的逻辑下沉到sidecar中,

sidecar和应用部署到同一个节点,并接管应用流入、流出的流量,这样大促时,只需要对相关的业务压测,并针对性扩容即可,另外升级也会更平滑,中心化的网关,即使灰度发布,但是理论上所有业务方的流量都会流入到新版本的网关,如果出了问题,会影响到所有的业务,但这种去中心化的方式,可以先针对非核心业务升级,观察一段时间没问题后,再全量推上线。另外ServiceMesh的方案,对于多语言支持也更友好。

关于微服务网关优雅降级和微服务 网关的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。 微服务网关优雅降级的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于微服务 网关、微服务网关优雅降级的信息别忘了在本站进行查找喔。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:开源api计费网关设置(开源api计费网关设置参数)
下一篇:宿舍管理系统接口设计(学生宿舍管理系统设计)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~