弹力设计篇

拆分方式
1、按服务种类
2、按用户种类(多租户)

 

 异步通讯方式
1、请求响应式
2、订阅、发布的方式    (直接订阅)
3、通过 Broker 的方式  (消息队列)(中间人订阅)

 

事件驱动
好处
服务间的依赖没有了,服务间是平等的,每个服务都是高度可重用并可被替换的。
服务的开发、测试、运维,以及故障处理都是高度隔离的。
服务间通过事件关联,所以服务间是不会相互 block 的。
在服务间增加一些 Adapter(如日志、认证、版本、限流、降级、熔断等)相当容易。
服务间的吞吐也被解开了,各个服务可以按照自己的处理速度处理。
坏处
业务流程不再那么明显和好管理。整个架构变得比较复杂。    解决这个问题需要有一些可视化的工具来呈现整体业务流程。 事件可能会乱序。这会带来非常 Bug 的事。          解决这个问题需要很好地管理一个状态机的控制。 事务处理变得复杂。                     需要使用两阶段提交来做强一致性,或是退缩到最终一致性。

 

全局ID
uuid占用空间较大,索引效率低

Twitter开源项目Snowflake  ;核心思想是产生一个long型
41bits,作为毫秒数。
10bits,作为机器编号(5数据中心,5机器ID)支持1024个实例
12bits,作为毫秒内的序列号。
情景
1、生成id
2、判断是否存在
3、没有插入


改进:
1、生成
2、插入,直接报错
insert into … values … on DUPLICATE KEY UPDATE …
update table set status = “paid” where id = xxx and status = “unpaid”;

 

 

 事务补偿
与传统ACID不同,为了提高性能 出现了变种BASE
1、Basic Availability:基本可用。这意味着,系统可以出现暂时不可用的状态,而后面会快速恢复。
2、Soft-state:软状态。它是我们前面的“有状态”和“无状态”的服务的一种中间状态。也就是说,为了提高性能,
  我们可以让服务暂时保存一些状态或数据,这些状态和数据不是强一致性的。 3、Eventual Consistency:最终一致性,系统在一个短暂的时间段内是不一致的,但最终整个系统看到的数据是一致的。
1、收到订单
|- 2、锁定库存
-- 2、致歉邮件,没有库存
业务补偿主要做两件事
1、努力地把一个业务流程执行完成
2、如果执行不下去,需要启动补偿机制,回滚业务流程
所以,一个好的业务补偿机制需要做到以下这几点
1、要能清楚地描述出要达到什么样的状态(比如:请假、机票、酒店这三个都必须成功,租车是可选的)以及如果其中的条件不满足,
  那么我们要回退到哪一个状态。这就是所谓的整个业务的起始状态定义。
2、当整条业务跑起来的时候,我们可以穿行或并行地做这些事。对于路由订票是可以并行的,但是对于网购流程(下单、支付、送货)
  是不能并行地。总之,我们的系统需要努力地通过一系列的操作达到一个我们想要的状态。如果达不到,就需要通过补偿机制回滚
  到之前的状态。这就是所谓的状态拟合。
3、对于已经完成的事务进行整体修改,可以考虑成一个修改事务

 

 

 重试策略
什么情况下需要重试,例如,调用超时、被调用端返回了某种可以重试的错误(如繁忙中、流控中、维护中、资源不足等)
什么情况下最好不要重试,比如:业务级的错误(如没有权限、或是非法数据等错误),技术上的错误。


注意点:
  重试的时间和重试的次数
  重试还需要考虑调用方是否有幂等性设计
  多次重试失败,再试没有意义;但是当被调用方可用时,如何恢复调用(熔断器Hystrix


sdk,services mesh 最好不要嵌入代码
  
 1 在实现熔断器模式的时候,以下这些因素需可能需要考虑。
 2 
 3 错误的类型。需要注意的是请求失败的原因会有很多种。你需要根据不同的错误情况来调整相应的策略。所以,熔断和重试一样,需要对返回的错误进行识别。一些错误先走重试的策略(比如限流,或是超时),重试几次后再打开熔断。一些错误是远程服务挂掉,恢复时间比较长;这种错误不必走重试,就可以直接打开熔断策略。
 4 
 5 日志监控。熔断器应该能够记录所有失败的请求,以及一些可能会尝试成功的请求,使得管理员能够监控使用熔断器保护服务的执行情况。
 6 
 7 测试服务是否可用。在断开状态下,熔断器可以采用定期地 ping 一下远程服务的健康检查接口,来判断服务是否恢复,而不是使用计时器来自动切换到半开状态。这样做的一个好处是,在服务恢复的情况下,不需要真实的用户流量就可以把状态从半开状态切回关闭状态。否则在半开状态下,即便服务已恢复了,也需要用户真实的请求来恢复,这会影响用户的真实请求。
 8 
 9 手动重置。在系统中对于失败操作的恢复时间是很难确定的,提供一个手动重置功能能够使得管理员可以手动地强制将熔断器切换到闭合状态。同样的,如果受熔断器保护的服务暂时不可用的话,管理员能够强制将熔断器设置为断开状态。
10 
11 并发问题。相同的熔断器有可能被大量并发请求同时访问。熔断器的实现不应该阻塞并发的请求或者增加每次请求调用的负担。尤其是其中对调用结果的统计,一般来说会成为一个共享的数据结构,它会导致有锁的情况。在这种情况下,最好使用一些无锁的数据结构,或是 atomic 的原子操作。这样会带来更好的性能。
12 
13 资源分区。有时候,我们会把资源分布在不同的分区上。比如,数据库的分库分表,某个分区可能出现问题,而其它分区还可用。在这种情况下,单一的熔断器会把所有的分区访问给混为一谈,从而,一旦开始熔断,那么所有的分区都会受到熔断影响。或是出现一会儿熔断一会儿又好,来来回回的情况。所以,熔断器需要考虑这样的问题,只对有问题的分区进行熔断,而不是整体。
14 
15 重试错误的请求。有时候,错误和请求的数据和参数有关系,所以,记录下出错的请求,在半开状态下重试能够准确地知道服务是否真的恢复。当然,这需要被调用端支持幂等调用,否则会出现一个操作被执行多次的副作用。
熔断设计的重点

 

限流的策略

 

1、拒绝服务: 统计当前那个客户端来的请求最多,直接拒掉这个客户端
2、服务降级:
    -    把不重要的服务停掉,把CPU、内存或是数据资源让给更重要的功能
    -    不再返回全量数据,只返回部分数据
3、特权请求:资源不够了,把有限的资源给重要的客户
4、延时处理:
    一般会有一个队列来缓冲大量的请求,这个队列如果满了,那么就只能拒绝用户了,如果这个队列中的任务超时了,也要返回系统繁忙的错误了。使用缓冲队列只是为了减缓压力,一般用于应对短暂的蜂刺请求
5、弹性伸缩:
    动用自动化运维的方式对相应的服务做自动化的伸缩。这就需要一个应用性能的监控系统,能够感知目前最繁忙的TOP5的服务是哪几个。然后去伸缩他们,还需要一个自动化的发布、部署、和服务注册的运维系统,
   而且还要快,越快越好。否则,系统会被压死掉了。当然,如果是数据库的压力过大,弹性伸缩应用是没什么用的,这时候应该限流

 

1、漏斗算法
    当访问量过大时这个漏斗就会积水,如果水太多了就会溢出
    
  通过一个队列实现的,当请求过多时,队列就会开始积压请求,如果队列满了,就会开始拒绝请求。
  其实就是在队列中加上一个限流器,来让Processor 以一个均匀的速度处理请求
2、令牌桶算法
  按照一定的速度放入一些token,然后处理请求时,都需要拿到token,才能处理;

3、基于响应时间的动态限流
  1、2的缺点在于,需要设置一个确定的限流值。因此每次发布服务时,都需要作相应的性能测试。
    影响因素:
      数据库
      不同API有不同的性能
      现在的服务都是能自动伸缩的,不同的集群性能也不一样
  实现方法:
    记录下每次调用后端请求的响应时间,然后在一个时间区间内(比如,过去10秒)的请求计算一个响应时间的
  P90或P99值,也就是把过去10秒内的请求的响应时间排个序,然后看90%或99%的位置是多少    


《编程珠玑》里讲过这个算法,你也可以自行 Google,英文叫 Reservoir Sampling    
限流应该是在架构的早期考虑。当架构形成后,限流不是很容易加入。

限流模块性能必须好,而且对流量的变化也是非常灵敏的,否则太过迟钝的限流,系统早因为过载而挂掉了。

限流应该有个手动的开关,这样在应急的时候,可以手动操作。

当限流发生时,应该有个监控事件通知。让我们知道有限流事件发生,这样,运维人员可以及时跟进。而且还可以自动化触发扩容或降级,以缓解系统压力。

当限流发生时,对于拒掉的请求,我们应该返回一个特定的限流错误码。这样,可以和其它错误区分开来。而客户端看到限流,可以调整发送速度,或是走重试机制。

限流应该让后端的服务感知到。限流发生时,我们应该在协议头中塞进一个标识,比如 HTTP Header 中,放入一个限流的级别,告诉后端服务目前正在限流中。这样,后端服务可以根据这个标识决定是否做降级
以下考量

 

 服务降级

 

目的:
    解决资源不足和访问量过大的问题。当资源和访问量出现矛盾的时候,在有限的资源下,为了能抗住大量的请求,我们需要对系统进行降级操作。
  也就是说,暂时要牺牲掉一些东西,以保障整个系统的平稳运行
降级的条件
    吞吐量大
    响应时间过慢
    失败的次数过多
    服务故障
    

 



牺牲掉的东西
1、降低一致性
2、停止次要功能
3、简化功能

 

 

 

 

 

 

 

 

 

 

posted @ 2020-06-05 20:09  慕沁  阅读(194)  评论(0)    收藏  举报