上次学了灰度发布,这次我们学习流控。
=======================================================
当资源成为瓶颈时,服务框架需要对消费者做限流,启动流控保护机制。
想做流控,就得有策略,比较常用的有:
1)针对访问速率的静态流控
2)针对资源占用的动态流控
3)针对消费者并发连接数的动态控制
4)针对并行访问数的并发控制
也就是说,你得有策略才可以!
在实际情况中,需要综合使用才可以发挥最大威力!
===14.1 静态流控===
静态流控主要针对客户端访问速率进行控制,做全局流量控制。
无论集群有多少台应用,总和不超过某个流量控制。
===14.1.1 传统静态流控设计方案===
传统的采取预分配方案,在软件安装时,根据集群节点个数和静态流控阀值,计算每个节点的分摊值
系统运行时,各个服务节点按照自己分配的阀值进行流控,对于超出阀值的请求则拒绝。
原理如图:略
服务框架启动时,将本节点的静态流控阀值加载到内存中,通过Handler拦截器在服务调用前做拦截技术,当计数器在指定周期T到达QPS上限时,启动流控,拒绝新的消息接入。
有2点需要注意:
1)一个进程有多个线程,计数器要考虑线程安全问题。
2)是拒绝新的请求,不是响应。
===14.1.2 传统方案的缺点===
这个方案没有考虑到服务实例的动态变化:
1)云端服务的弹性伸缩使服务节点处于动态变化过程中,预分配方案行不通。
2)有节点宕机或者加入,服务节点数发生变化,静态分配的QPS需要实时动态调整,否则会导致流控不准。
分布式服务框架的特点就是服务的动态上下线和自动发现规则,这就决定了在运行期服务节点数会随着业务量的变化而频繁变化,在这种场景下静态分配方案显然无法满足需求。
当在云上的时候,PAAS平台的一个重要功能就是支持应用和服务的弹性伸缩,在云上,资源都是动态分配和调整的,静态分配阀值方案无法适应服务迁移到云上。
14.1.3)+14.1.4) 动态配额分配制 VS 动态配额申请制
为了解决这个问题,通常采用动态配额分配制。
原理如下:
服务注册中心周期性的,动态推送每个节点分配的流控阀值
当服务节点发生变更时,会触发服务注册中心重新计算每个节点的配额,然后进行推送。
这样无论是新增还是减少服务节点数,都能够在下一个流控周期内被识别和处理
这就解决了动态的问题。
流程如下:略
在生产环境中,每台机器的配置可能不同,如果每个服务节点采用平均主义,可能会发生性能高处理快的节点配额很快用完,性能差的节点配额有剩余,这会导致总的配额没有用完。
一种解决方案是:服务注册中心在做配额计算时,根据各个服务节点的性能KPI数据做加权,这样就可能降低流控偏差。
还有另外1种方案是 配额指标返还和重新申请。略!
最后1点就是结合负载均衡进行静态流控,才能够实现更精确的调度和控制,消费者根据各服务节点的负载情况做加权路由,性能差的节点路由到的消息更少,由于配额计算也根据负载做了加权调整,最终分配给性能差的节点配额指标也比较少,这样既保证了系统的负载均衡,又实现了配额的更合理分配。
动态配额申请制---非常复杂,不看了。
14.2)动态流控
动态流控的目的是为了保命,不是对流量和访问速度做精确控制。
当系统负载压力非常大时,系统进入负载状态,可能资源已经过载,也可能是应用内部的资源几乎耗尽。
影响不好。
触发动态流控的因子是资源,资源又分为系统资源和应用资源2大类。
根据不同的资源负载情况,动态流控又分为多个级别,每个级别流控系数都不同,也就是被拒绝掉的消息比率不同,每个级别都有相应的流控阀值,这个阀值通常支持在线动态调整。
14.2.1)动态流控因子
因子包括系统资源和应用资源两大类,常用的系统资源包括:
1)CPU
2)内存
采集算法非常多,要注意区别。
常用的应用资源包括:
1)JVM堆内存使用率
2)消息队列积压率
3)会话积压率(可选)
具体实现策略是:
系统启动时,拉起一个管理线程,定时采集应用资源的使用率,刷新动态流控的应用资源阀值。
14.2.2)分级流控
高深了!