• 微服务 高可用


    隔离

    隔离:本质上是对系统或资源进行分割,从而实现当系统发生故障时能限定传播范围和影响范围,即当发生故障后只有出问题的服务不可用,保证其他服务仍然可用。
    服务隔离

    • 动静分离,读写分离
      轻重隔离
    • 核心,快慢,热点
      物理隔离
    • 线程,进程,集群,机房

    隔离 - 服务隔离

    动静隔离:

    小到CPU的cacheline false sharing,数据库 mysql表设计避免bufferpool 频繁过期,隔离动静表(我们一般设计两张表,一张表经常更新,一张表不怎么更新,避免将这两张表放在一起),大到架构设计中的图片,静态资源等缓存加速。本质上都体现一种思想,即加速/缓存访问量变化小的。比如 CDN场景中,将静态资源和动态API分离,也是体现了隔离的思路。
    mysql buffer pool 是用于缓存dataPage 的,dataPage 可以理解为缓存了表的行,那么如果频繁更新dataPage ,那么会因为LRU算法会发生不断的置换操作,会导致命中率下降,所以我们在表设计中,仍然可以沿用类似的思路,其主表基本更新,在上游cache未命中,透穿到mysql中,仍然有bufferpool缓存。

    • 读写分离:主从

    核心隔离:

    业务按照Level进行资源池划分(L0/L1/L2)

    • 核心/非核心的故障域的差异隔离(机器资源,依赖资源)
    • 多集群,通过冗余资源来提升吞吐和容灾能力

    热点隔离:

    何为热点?热点即经常访问的数据。很多时候我们希望统计某个热点数据中访问频次最高的top k 数据,并对访问进行缓存。比如:

    • 小表广播:从 remotecache(redis) 提升为 localcache, app 定时更新,甚至可以让运营平台支持广播刷新localcahce,同时使用cop技术,atomic.value
      在这里插入图片描述
    • 主动预热:比如直播房间页高在线情况下 bypass 监控主动防御
      在这里插入图片描述
      假设直播房间高在线,高刷新的情况下怎么处理?如上图我们通过 room-monitor 服务来监控房间人数,一旦人数达到一个阈值(5w),我们就通知room-service 将 remotecache 升级为 localcache,我们会先访问localcache,如果localcahce未命中,再访问redis。我们将房间信息缓存到localcache中,这样用户在疯狂刷新的时候,就能命中。这是一种旁路监控,找到热点房间,主动广播的思路。更好的办法是进程级别的,

    隔离 - case study

    1. 早期转码集群被超大视频攻击,导致转码大量延迟。
      可以采用,将视频集群进行隔离,超大视频用a集群,大视频用b集群,小视频用c集群。这样只会阻塞a集群。将全局故障,转变为局部故障。

    超时

    超时控制

    超时控制,我们的组件能够快速失效(fail fast),因为我们不希望等到断开的实例直到超时。没有什么比挂起的请求和无响应的界面更令人失望。
    超时控制是微服务可用性的第一道关,良好的超时策略,可用尽可能让服务不堆积请求,尽快清空高延迟的请求,释放goroutine,一秒钟法则:pc 互联网必须一秒钟返回。

    过载保护和限流

    过载保护

    • 令牌桶算法
    • 漏桶算法

    漏斗桶/令牌桶确实能够保护系统不被拖垮,但不管漏斗桶还是令牌桶,其防护思路都是设定一个指标,当超过该指标后就阻止或减少流量继续进入,当系统负载降低到某一水平后则恢复流量的进入。但其实通常都是被动的,其实际效果取决于限流阈值设置是否合理,但往往设置合理不是一件容易的事情。

    • 集群增加机器或者减少机器限流阈值是否要重新设置?
    • 设置限流阈值的依据是什么?
    • 人力维护成本是否过高?
    • 当重新设置限流,其流量高峰已经过了重新评估限流是否有意义?
      这些其实都是采用漏斗桶/令牌桶的缺点,总体来说就是太被动,不能快速适应流量变化。因此我们需要一种自适应的限流算法,即:过载保护,根据系统当前的负载自动丢弃流量。
      ???

    限流

    限流是指在一段时间内,定义某个客户或应用可用接收或处理多少个请求的技术。例如,通过限流,你可以过滤掉产生流量峰值的客户和微服务,或者可以确保你的应用程序自动扩展(auto scaling)失效前不会出现过载的情况。

    • 令牌桶,漏桶 针对单个节点,无法分布式限流
    • QPS限流:1.不同的请求可能需要数量迥异的资源来处理。2.某种静态QPS限流不是特别准
    • 给每个租户设置限制:1.全局过载发生的时候,针对某些"异常"进行控制。2. 一定程度的“超卖”配额。
    • 按照优先级丢弃
    • 拒绝请求也需要成本。

    限流 - 分布式限流

    分布式限流,是为了控制某个应用全局的流量,而非真对单个节点维度。
    一般采用redis,来一个请求,就将对应的key+1, 但是这样会有缺点:

    • 单个大流量的接口,使用redis容易产生热点。如果有10w QPS,那么这个流量就会打到redis上。
    • 像这种 pre-request 模式对性能有一定影响,高频的网络往返。
      在这里插入图片描述

    限流 - 熔断

    熔断是从client侧做保护。直接不请求下游。他是对下游做保护的,即对server做保护。

    • 服务依赖的资源出现大量错误。
    • 某个用户超过资源配额的时候,后端任务会快速拒绝请求,返回"配额不足"的错误,但是拒绝回复仍然会消耗一定的资源。有可能后端忙着不停发送拒绝请求导致过载。
      在这里插入图片描述
      如上图所示,熔断刚开始是closed的,这时候请求会成功发送到下游,当下游的服务发生过多的错误的时候,我们会开启熔断,这时候请求进入fast failing状态,直接失败,但是我们会放一个请求去尝试请求下游看看是否恢复。

    降级重试

    通过降级回复来减少工作量,或者丢弃不重要的请求。而且需要了解哪些流量可以降级,并且有能力区分不同的请求。我们通常提供降低回复的质量来答复减少所需的计算量或者时间。我们自动降级通常需要考虑几个点:

    • 确定具体采用哪个指标作为流量评估和优雅降级的决定性指标(cpu,延迟,队列长度,线程数量,错误等)
    • 当服务进入降级模式时,需要执行什么动作
    • 流量抛弃或者优雅降级应该在服务的哪一层实现?是否需要在整个服务的每一层都实现,还是可以选择某个高层面的关键节点来实现?
      同时我们要考虑以下几个点:
    • 优雅降级不应该被经常触发
    • 演练,代码平时不会触发和使用,需要定期针对一小部分的流量进行演练,保证模式的正常
    • 应该足够简单
  • 相关阅读:
    CMake库搜索函数居然不搜索LD_LIBRARY_PATH
    我的sql没问题为什么还是这么慢|MySQL加锁规则
    Python对excel文件批量加密(GUI选择)
    模型部署踩坑(持续更新ing)
    机器学习-学习笔记(一) --> (假设空间 & 版本空间)及 归纳偏好
    武汉新时标文化传媒有限公司短视频的创作和分发
    【7-创建商城系统的子模块并将修改后的信息使用Git提交到Gitee上】
    WebGL笔记:WebGL中绘制圆点,设定透明度,渲染动画
    NR 物理层编码 S2 - 线性码
    大型分布式系统下缓存应该怎么玩,才能用得高效
  • 原文地址:https://blog.csdn.net/leekerian/article/details/127001875