草庐IT

微服务架构 | 5. 服务容灾

多氯环己烷 2023-03-28 原文

@


前言

参考资料
《Spring Microservices in Action》
《Spring Cloud Alibaba 微服务原理与实战》
《B站 尚硅谷 SpringCloud 框架开发教程 周阳》

当服务器压力剧增的情况下,根据实际业务情况及流量,对一些服务和页面有策略的不处理或换种简单的方式处理,从而释放服务器资源以保证核心交易正常运作或高效运作;


1. 服务容灾基础知识

1.1 由一个服务资源耗尽引发的连锁反应

  • A 服务调用 B 服务,B 服务调用 C 服务;
  • 当 C 服务出现调用缓慢问题是,影响 B 服务的响应;B 服务又会影响 A 服务,导致其他服务不可用;

1.2 服务雪崩效应

  • 在微服务架构中,我们将业务拆分成一个个的服务,服务与服务之间可以相互调用,但是由于网络原因或者自身的原因,服务并不能保证服务的 100% 可用,如果单个服务出现问题,调用这个服务就会出现网络延迟,此时若有大量的网络涌入,会形成任务堆积,最终导致服务瘫痪;
  • 在分布式系统中,由于网络原因或自身的原因,服务一般无法保证 100% 可用。如果一个服务出现了问题,调用这个服务就会出现线程阻塞的情况,此时若有大量的请求涌入,就会出现多条线程阻塞等待,进而导致服务瘫痪;

1.3 四种客户端弹性模式

  • 客户端负载均衡模式(client load balance):让客户端从服务注册中心查找服务的所有实例,然后缓存服务实例的物理位置;
  • 断路器模式(circuit breaker):远程服务调用时间太长,断路器将会介入并中断调用 ;
  • 后备模式(fallback):远程服务调用失败时,服务消费者将执行替代代码路径, 并尝试通过其他方式执行操作,而不是生成一个异常;
  • 舱壁模式(bulkhead):每个远程资源、都是隔离的,并分配给线程池;

1.4 服务容灾的几种解决方案

  • 服务隔离:即舱壁模式。将系统按照一定的原则划分为若干个服务模块,各个模块之间相对独立,无强依赖。常见的隔离方式有:线程池隔离和信号量隔离;
  • 服务超时:在上游服务调用下游服务的时候,设置一个最大响应时间,如果超过这个时间,下游未作出反应,就断开请求,释放线程;
  • 服务降级:即后备模式。服务提供一个托底方案,一旦服务无法正常调用,就使用托底方案;
  • 服务熔断:即断路器。上游服务为了保护系统整体的可用性,可以暂时切断对下游服务的调用。一种“牺牲局部,保全整体”的策略;
  • 服务限流:限制系统的输入和输出流量已达到保护系统的目的;

1.5 服务降级的参考指标

  • 服务降级需要有一个参考指标,一般来说有以下几种常见方案;
    • 平均响应时间:比如15内持续进入5个请求,对应时刻的平均响应时间均超过阈值,那么接下来在一个固定的时间窗口内,对这个方法的访问都会自动熔断;
    • 异常比例:当某个方法每秒调用所获得的异常总数的比例超过设定的阈值时,该资源会自动进入降级状态,也就是在接下来的一个固定时间窗口中,对这个方法的调用都会自动返回;
    • 异常数量:和异常比例类似,当某个方法在指定时间窗口内获得的异常数量超过闽值时会触发熔断;

1.6 服务限流的作用

  • 限流的主要目的是通过限制并发访问数或者限制一个时间窗口内允许处理的请求数量来保护系统,一旦达到限制数量则对当前请求进行处理采取对应的拒绝策略,比如跳转到错误页面拒绝请求、进入排队系统、降级等;
  • 从本质上来说,限流的主要作用是损失一部分用户的可用性,为大部分用户提供稳定可靠的服务;
  • 实际开发中的限流应用:
    • 在 Nginx 层添加限流模块限制平均访问速度;
    • 通过设置数据库连接池、线程池的大小来限制总的并发数;
    • 通过 Guava 提供的 Ratelimiter 限制接口的访问速度;
    • TCP 通信协议中的流量整形;

1.7 常见的几种限流算法

1.7.1 计数器算法

  • 一种比较简单的限流实现算法;
  • 原理:在指定周期内累加访问次数,当访问次数达到设定的闽值时,触发限流策略,当进入下一个时间周期时进行访问次数的清零;
  • 存在临界问题:前一个周期的后半部分与后一个周期的前半部分的总访问次数可能超过阈值;

1.7.2 滑动窗口算法

  • 是一种流量控制技术,在 TCP 网络通信协议中,就采用了滑动窗口算法来解决网络拥塞的情况;
  • 原理:在固定窗口中分割出多个小时间窗口,分别在每个小时间窗口中记录访问次数,然后根据时间将窗口往前滑动并删除过期的小时间窗口。最终只需要统计滑动窗口范围内的所有小时间窗口总的计数即可;
  • 该算法解决了临界问题,Sentinel 采用滑动窗口算法来实现限流

1.7.3 令牌桶算法

  • 网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法;
  • 原理:对于每一个请求,都需要从令牌桶中获得一个令牌,如果没有获得令牌,则需要触发限流策略;
  • 由于令牌桶有固定的大小,当请求速度小于令牌生成速度时,令牌桶会被填满。所以令牌桶能够处理突发流量,也就是在短时间内新增的流量系统能够正常处理,这是令牌桶的特性;

1.7.4 漏桶限流算法

  • 主要作用是控制数据注入网络的速度,平滑网络上的突发流量;
  • 原理:在漏桶算法内部同样维护一个容器,这个容器会以恒定速度出水,不管上面的水流速度多快,漏桶水滴的流出速度始终保持不变;
  • 消息中间件就使用了漏桶限流的思想;
  • 请求速度大于漏桶流出水滴的速度时,触发限流策略;
  • 令牌桶算法的区别:漏桶无法处理短时间内的突发流量,漏桶限流算法是一种恒定速度的限流算法;

1.8 利用 Postman 模拟请求高并发场景

  • Postman 里新建多线程集合组;

  • 右键添加请求

  • 将访问地址添加进新新线程组;

  • 设置多线程组的运行状态;
  • 使用 postman 密集访问 testA,下面配置的含义是:
    • 20个线程每次间隔 0.3s 访问一次;

1.9 目前几种流行的服务降级组件对比

比较项 Hystrix Sentinel Resilience4j
贡献者 Netflix Alibaba Apache 基金会
隔离策略 线程池隔离/信号量隔离 信号量隔离(并发线程数限流) 信号量隔离
熔断降级策略 基于异常比率 基于响应时间、异常比率、异常数 基于异常比率、响应时间
实时统计实现 滑动窗口(基于 RxJava) 滑动窗口(LeapArray) Ring Bit Buffer
动态规则配置 支持多种数据源 支持多种数据源 有限支持
扩展性 插件的形式 多个扩展点 接口的形式
基于注解的支持 支持 支持 支持
限流 有限的支持 基于 QPS,支持基于调用关系的限流 Rate Limiter
流量整形 不支持 支持预热模式、匀速器模式、预热排队模式 简单的 Rate Limiter模式
系统自适应保护 不支持 支持 不支持
控制台 简单的监控查看 提供开箱即用的控制台,可配置规则、查看秒级监控、机器发现等 不提供控制台,可对接其它监控系统

2. Hystrix

Hystrix 是一个延迟和容灾库,旨在隔离远程系统、服务和第三方库的访问点,停止级联故障,并在故障不可避免的复杂分布式系统中实现弹性;


3. Sentinel

Sentinel 是面向分布式服务架构的轻量级流量控制组件,主要以流量为切入点,从限流、流量整形、服务降级、系统负载保护等多个维度来帮助我们保障微服务的稳定性;


4. Resilience4j

Resilicence4j 一款非常轻量、简单,并且文档非常清晰、丰富的熔断工具,这也是Hystrix官方推荐的替代产品。不仅如此,Resilicence4j 还原生支持Spring Boot 1.x/2.x,而且监控也支持和 prometheus 等多款主流产品进行整合

  • 点击访问:


最后

新人制作,如有错误,欢迎指出,感激不尽!
欢迎关注公众号,会分享一些更日常的东西!
如需转载,请标注出处!

有关微服务架构 | 5. 服务容灾的更多相关文章

  1. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  2. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  3. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  4. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  5. ruby - 用 Ruby 编写一个简单的网络服务器 - 2

    我想在Ruby中创建一个用于开发目的的极其简单的Web服务器(不,不想使用现成的解决方案)。代码如下:#!/usr/bin/rubyrequire'socket'server=TCPServer.new('127.0.0.1',8080)whileconnection=server.acceptheaders=[]length=0whileline=connection.getsheaders想法是从命令行运行这个脚本,提供另一个脚本,它将在其标准输入上获取请求,并在其标准输出上返回完整的响应。到目前为止一切顺利,但事实证明这真的很脆弱,因为它在第二个请求上中断并出现错误:/usr/b

  6. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  7. Observability:从零开始创建 Java 微服务并监控它 (二) - 2

    这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/

  8. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  9. ruby - Rails 开发服务器、PDFKit 和多线程 - 2

    我有一个使用PDFKit呈现网页的pdf版本的Rails应用程序。我使用Thin作为开发服务器。问题是当我处于开发模式时。当我使用“bundleexecrailss”启动我的服务器并尝试呈现任何PDF时,整个过程会陷入僵局,因为当您呈现PDF时,会向服务器请求一些额外的资源,如图像和css,看起来只有一个线程.如何配置Rails开发服务器以运行多个工作线程?非常感谢。 最佳答案 我找到的最简单的解决方案是unicorn.geminstallunicorn创建一个unicorn.conf:worker_processes3然后使用它:

  10. ruby - Dropbox 类似 git 的服务——没有 rsync 和 inotify - 2

    关于如何使用git设置类似Dropbox的服务,您有什么建议吗?您认为git是解决此问题的合适工具吗?我在考虑使用git+rush解决方案,你觉得怎么样? 最佳答案 检查这个开源项目:https://github.com/hbons/SparkleShare来自项目的自述文件:Howdoesitwork?SparkleSharecreatesaspecialfolderonyourcomputer.Youcanaddremotelyhostedfolders(or"projects")tothisfolder.Theseprojec

随机推荐