zoukankan      html  css  js  c++  java
  • SpringCloud(三) 微服务架构-微服务稳定性

      采用微服务架构后,当分布式系统到达一定量级时,每个环境都可能出错,因此在系统设计时应该考虑如何减轻故障的影响,如何从故障中快速恢复。一般从以下两点来考察系统的稳定性:

    • 高可用:当前服务依赖的下游服务性能降低或者失败时,该服务怎么相应,是快速失败还是重试?大促时如何应对瞬间涌入的流量?
    • 高并发:底层服务如何保证服务的吞吐量?如何提高消费者的处理速度?

    高可用

    限流

       限流算法

      计数器法:该算法维护一个counter,规定在单位时间内counter的大小不能超过最大值,每隔固定时间就将counter的值置为零。

      漏桶算法:水(请求)先进入到漏桶里,漏桶以一定的速度出水,当水流入速度过大会直接溢出(拒绝服务),可以看出漏桶算法能强行限制数据的传输速率

       

      令牌桶算法:一个存放固定容量令牌的桶,按照固定速率(每秒/或者可以自定义时间)往桶里添加令牌,然后每次获取一个令牌,当桶里没有令牌可取时,则拒绝服务。令牌桶分为2个动作,动作1(固定速率往桶中存入令牌)、动作2(客户端如果想访问请求,先从桶中获取token)

      

       限流实践

       Google开源工具包Guava提供了限流工具类RateLimiter,该类基于令牌桶算法(Token Bucket)来完成限流,非常易于使用.RateLimiter经常用于限制对一些物理资源或者逻辑资源的访问速率.它支持两种获取permits接口,一种是如果拿不到立刻返回false,一种会阻塞等待一段时间看能不能拿到.

      RateLimiter设计思路:RateLimiter的主要功能就是通过限制请求流入的速度来提高稳定的服务速度。实现QPS速率的最简单的方式就是记住上一次请求的最后授权时间,然后保证1/QPS秒内不允许请求进入.比如QPS=5,如果我们保证最后一个被授权请求之后的200ms的时间内没有请求被授权,那么我们就达到了预期的速率.如果一个请求现在过来但是最后一个被授权请求是在100ms之前,那么我们就要求当前这个请求等待100ms.按照这个思路,请求15个新令牌(许可证)就需要3秒。如果RateLimiter的一个被授权请求之前很长一段时间没有被使用会怎么样?这个RateLimiter会立马忘记过去这一段时间的利用不足,而只记得刚刚的请求。

    断路器

      Hystrix[hɪst'rɪks]由Netflix开源的一个延迟和容错库,用于隔离访问远程系统、服务或者第三方库,防止级联失败,从而提升系统的可用性、容错性与局部应用的弹性,是一个实现了超时机制和断路器模式的工具类库。

      Hystrix主要提供4个功能:断路器、隔离机制、请求聚合和请求缓存。

    • 断路器(Circuit breaker)

      Hystrix Command请求后端服务失败数量超过一定比例(默认50%), 断路器会切换到开路状态(Open). 这时所有请求会直接失败而不会发送到后端服务. 断路器保持在开路状态一段时间后(默认5秒), 自动切换到半开路状态(HALF-OPEN). 这时会判断下一次请求的返回情况, 如果请求成功, 断路器切回闭路状态(CLOSED), 否则重新切换到开路状态(OPEN).

    • 隔离机制(Bulkheads)

      线程池隔离模式:使用一个线程池来存储当前的请求,线程池对请求作处理,设置任务返回处理超时时间,堆积的请求堆积入线程池队列。这种方式需要为每个依赖的服务申请线程池,有一定的资源消耗,好处是可以应对突发流量(流量洪峰来临时,处理不完可将数据存储到线程池队里慢慢处理)

      信号量隔离模式:使用一个原子计数器(或信号量)来记录当前有多少个线程在运行,请求来先判断计数器的数值,若超过设置的最大线程个数则丢弃该类型的新请求,若不超过则执行计数操作请求来计数器+1,请求返回计数器-1。这种方式是严格的控制线程且立即返回模式,无法应对突发流量(流量洪峰来临时,处理的线程超过数量,其他的请求会直接返回,不继续去请求依赖的服务)

    • 请求聚合

      使用HystrixCollapser将前端的多个请求聚合成为一个请求发送到后端

    • 请求缓存

      HystrixCommand和HystrixObservableCommand实现了对请求的缓存,假如在某个上下文中有多个同时到达的相同参数的查询,利用请求缓存功能,可以减少对后端系统的压力。

    超时与重试

      在微服务系统中,如果上游应用没有设置合理的超时和重试机制,则会造成请求响应变慢,慢请求会积压并耗尽系统资源。超时机制应该和限流、断路器配合使用,最终实现微服务系统的稳定性。

     

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    高并发

      几种常见的高并发策略如下:

    • 异步:提高业务过程中可异步部分的占比,提高异步部分的执行效率
    • 缓存:将频繁访问的数据存储在离业务处理逻辑更近的地方
    • 池化:对于创建起来比较消耗资源的对象进行缓存

    异步

      按照异步操作出现的位置,可用分为两类:在JVM内部,使用异步线程池或者异步回调机制;在JVM外部,可用使用消息队列、Redis队列等中间件

      异步线程池

      Java中可用通过Executors和ThreadPoolExecutor方式创建线程池,通过Executors可用快速创建四种常见的线程池,但这种方式在实际使用中并不推荐,因为这种方式创建出来的线程池的可控性较差(FixedThreadPool和SingleThreadPool:允许的请求队列长度为Integer.MAX_VALUE,可能对堆积大量请求,从而导致OOM;CacheThreadPool和ScheduledThreadPool:允许创建线程数量为Integer.MAX_VALUE,可能创建大量线程,从而导致OOM)。而通过ThreadPoolExecutor的方式去创建,可用让开发人员更明确线程池的运行规则,避免资源耗尽的风险。同时可用实现自定义的拒绝策略,从而打印告警日志,并根据日志监控线程池的运行情况,在发生异常时及时处理。

      异步回调机制

      异步回调与同步调用的不同之处在于,请求发起方不需要等待服务方的响应返回,可用先去做别的业务。接口请求返回后会自动调用预先定义的回调函数,进行后续的业务处理。

      消息队列

      消息队列是系统架构层面的异步策略,应用场景很广泛,如削峰填谷。典型应用就是优惠券发放和电商秒杀系统

    缓存

      

      在分布式系统中,缓存无处不在。从缓存静态资源的CDN,到缓存http请求的nginx,从浏览器或App客户端的缓存,到服务端到数据存储的缓存,不一而足。常见的分布式缓存中间件有Redis、Memcache等。在分布式系统中使用缓存时,还需要处理好缓存穿透、缓存雪崩、大value缓存监测、热点缓存等问题。

      缓存穿透:一般的缓存系统都是按照key去缓存查询的,如果不存在则去后端系统查找。如果key对应的value一定不存在,并且对该key的并发请求量很大,就会对后端系统造成很大的压力。

      缓存雪崩:当缓存服务器重启或者大量缓存集中在某一个时间段消失,在消失的这段时间,也会对后端系统带来很大压力

      

      

  • 相关阅读:
    permission 文档 翻译 运行时权限
    TabLayout ViewPager Fragment 简介 案例 MD
    Log 日志工具类 保存到文件 MD
    OkHttp 官方wiki 翻译 MD
    Okhttp 简介 示例 MD
    OkHttp 官方Wiki之【使用案例】
    DialogPlus
    倒计时 总结 Timer Handler CountDownTimer RxJava MD
    RecyclerView 判断滑到底部 顶部 预加载 更多 分页 MD
    CSS3的媒体查询(Media Queries)与移动设备显示尺寸大全
  • 原文地址:https://www.cnblogs.com/ryjJava/p/14224559.html
Copyright © 2011-2022 走看看