聊一聊限流、降级、熔断

神机军师
• 阅读 10251

熔断

小时候村里一到夏天,全村都开空调,村里总闸的保险丝就会因为用电量太大,自动熔断了,直接停服。股市也有一些极端情况开启熔断处理,不到万不得已,不会熔断。在 Web 工程中熔断的最小单元,也不一定是整个应用,可能只是某个服务。这里不深究学术名词定义。

限流

限流场景我们经常遇到,有时候地铁里就被保安人员给我限流了,双十一抢购也被爸爸限流了。坐地铁之所以能限流是因为我们都要安检,有这个统一的地铁入口;浏览网站被限流是因为访问有统一的域名入口。

当我们需要根据路由规则进行限流,只要把握好网关就很方便的实现限流了,以下方案均可行

  • 布点在类似于 WAF(Web 应用防火墙)中,具体见 阿里云WAF手册
  • 如果不想花钱,也可以安装 nginx 限流插件来做类似的工作,自己部署,总之是在 web 应用前面布点拦截操作
  • 也可以在 web 应用里面结合路由组件开发一个限流组件,只要代码有统一入口,就可以方便控制

降级

生活中我也是消费降级的小伙,原来天猫,后来淘宝,现在拼多多和淘宝特价版。消费降级真香,话说回来,重点是又不是不能用。Web 项目中降级的案例,比如微博 feed 流中,用户基本信息压力比较大,而用户的勋章也在该接口中对前端输出,服务降级的重点是又不是不能用

聊一聊限流、降级、熔断

如果是按照现在微服务的理念,勋章查询可能是一个独立的服务,所以降级对应的颗粒度可以是服务降级。既然是独立的服务单元,请求的拦截就又回到了和限流一样的场景;
如果不是微服务架构,接口依赖的用户的勋章输出只是一个独立的函数或者方法,如何进行拦截呢?

方案1. 紧急发布

如果后端服务是 PHP 的脚本语言,我们可以快速的单独发布需要修改的文件,达到快速降级的目的。
如果后端服务是 JAVA 需要编译的,对于这种简单场景的修改,也是支持热部署,单独发布一个 class 文件,也不需要重启也 OK,比如 arthas 就提供类似的功能。

如果发布系统不支持热部署,也不支持单文件发布,只支持发布软件包的方式,那么快速降级就需要 15 ~ 30分钟(业务复杂一点的 Java 应用)才能部署完成,这是互联网应用不能接受的。

方案2. 限流降级中间件

在 Java 生态目前比较成熟,知名的产品有 hystrix,我用的比较多的是 sentinel。支持从路由、方法去做单机的 qps 去限流,只需要在sentinel管控台做配置变更,然后发布推送到各个机器,机器则以最后收到的限流规则单机闭环操作,中间不再需要和中间件服务进行交互。

PHP 能不能像 sentinel 一样对用户态的函数和方法进行拦截控制呢,所以弄了这个 https://github.com/zhoumengka... PHP 7.2.5 线上运行OK

安装使用

编译安装

$ phpize
$ ./configure --with-php-config=/usr/local/php/bin/php-config
# 如果需要调试
# ./configure --with-php-config=/usr/local/php/bin/php-config --enable-debug
$ make && make install

配置php.ini,在其后面追加

[sentinel]
extension=sentinel.so
sentinel.api_url=https://mengkang.net/sentinel.html
sentinel.api_cache_ttl=120
sentinel.api_cache_file=/tmp/sentinel.rule
sentinel.log_enabled=1
sentinel.log_file=/tmp/sentinel.log
  • sentinel.api_url 限流查询接口
  • sentinel.api_cache_ttl 接口查询结果缓存 2 分钟
  • sentinel.api_cache_file 接口查询缓存路径
  • sentinel.log_enabled 是否开启用户自定义的方法和函数日志记录,可以用日志处理工具收集比如阿里云 SLS
  • sentinel.log_file 日志记录路径

原理

PHP_MINIT阶段,通过zend_set_user_opcode_handler注册在opcode运行环节,对用户态的方法和函数(ZEND_DO_UCALL)的运行做处理

zend_set_user_opcode_handler(ZEND_DO_UCALL, php_sentinel_call_handler)

PHP_RINIT阶段,获取中间件配置。对于缓存时长内的不发起网络请求

php_sentinel_fetch()

限流策略闭环

php_sentinel_call_handler

当已经已经在限流列表中的方法或者函数进行拦截,同时对通过的方法和函数进行日志记录(当日志功能开启的情况)然后进行类似 sls 上报,然后中心通过分析 sls 日志再决策是否进行限流,通过接口通知到各个 web 服务器。

注册自定义的异常类SentinelException,当检测到执行的方法或者函数需要被限流,则抛出该异常

zend_class_entry ce;
INIT_CLASS_ENTRY(ce, "SentinelException", NULL);
php_sentinel_exception_class_entry =  zend_register_internal_class_ex(&ce, zend_ce_exception);
php_sentinel_exception_class_entry->ce_flags |= ZEND_ACC_FINAL;

业务层可以对该异常在最外层进行捕获,按照业务协议做标准错误输出。

try{
    // 项目 dispatcher 调度入口
}catch (\SentinelException $exception){
    // 标准的错误输出 可以是 json 可以 html 页面
}

目前的方案更偏向于一个熔断思路,只要运行到指定的方法或者函数就抛出异常,比如(以函数演示,方法也支持)。可惜 PHP set_exception_handler 不能对运行当前行进行捕获处理,并且接管异常。所以只能算是熔断 ,除非被拦截的方法,在一些逻辑下没有进入。

function demo(){
    $ res[] = aa();
    
    if (条件 1) {
        $res[] = bb(); // bb 函数被降级
    } else {
        $resp[] = cc();
    }
    
    return $res;
}
点赞
收藏
评论区
推荐文章
捉虫大师 捉虫大师
3年前
Sentinel在docker中获取CPU利用率的一个BUG
Sentinel简介微服务治理中限流、熔断、降级是一块非常重要的内容。目前市面上开源的组件也不是很多,简单场景可以使用Guava,复杂场景可以选用Hystrix、Sentinel。今天要说的就是Sentinel,Sentinel是一款阿里开源的产品,只需要做较少的定制开发即可大规模线上使用。从使用感受上来说,它有以下几个优点:轻量级,对性能损耗几乎可以忽略
Easter79 Easter79
3年前
springcloud(六) Hystrix 熔断,限流
Hystrix熔断:  首先仍然启动Eureka,这里就不说了。OrderController.java:packagecom.tuling.cloud.study.user.controller;importorg.slf4j.Log
高并发场景下常见的限流算法及方案介绍
现代互联网很多业务场景,比如秒杀、下单、查询商品详情,最大特点就是高并发,而往往我们的系统不能承受这么大的流量,这时候限流熔断就发挥作用了,限制请求数,快速失败,保证系统满负载又不超限。本文为大家介绍几种常见的限流算法及方案
Stella981 Stella981
3年前
Spring Cloud Feign 异常处理
问题最近在项目开发中,使用Feign调用服务,当触发熔断机制时,遇到了以下问题:异常信息形如:TestServiceaddRecord(ParamVO)failedandnofallbackavailable.;获取不到服务提供方抛出的原始异常信息;实现某些业务方法不进入熔断,直接往外抛出异常;
Stella981 Stella981
3年前
Hystrix Feign 特定状态码不熔断
HystrixFeign特定状态码不熔断背景部分业务校验规范或疏忽场景,传入badrequest导致接口熔断,影响接口正常流量处理重写Feignerrordecoder逻辑importcom.netflix.hystrix.exception.HystrixB
Stella981 Stella981
3年前
Alibaba Sentinel 限流与熔断初探
点击上方“中间件兴趣圈”,选择“设为星标”做积极的人,越努力越幸运!!(https://oscimg.oschina.net/oscnet/44bed85e8c91c7600c2479df035e2558748.png)(https://www.oschina.net/action/GoToLink?urlhttp%3A%2F%
Easter79 Easter79
3年前
SpringCloud的限流、降级和熔断——Hystrix
!(https://oscimg.oschina.net/oscnet/updb144b1538f24c2488b01c4e66a45d48038.JPEG)一、前言分布式系统环境中,服务间类似依赖非常常见,一个业余调用通常依赖多个基础服务。如下图,对于同步调用,当库存服务不可用时,商品服务请求线程被阻塞,当有大批量请求调用库存服务时,
Stella981 Stella981
3年前
Sentinel 流量控制 熔断降级 初探
    还记得之前写过一篇防雪崩利器:熔断器Hystrix的原理与使用https://my.oschina.net/u/3266761/blog/2654470,讲述了服务降级和熔断的控制,今天带来另一个流量控制与服务降级阿里开源框架sentinel。  首先是两者的对比:    Hystrix的关注点在于以隔离和熔断为主的容错机制
Stella981 Stella981
3年前
Hystrix (容错,回退,降级,缓存)
Hystrix熔断机制就像家里的保险丝一样,若同时使用高功率的电器,就会烧坏电路,这时候保险丝自动断开就有效的保护了电路。而我们程序中也同样是这样。例如若此时数据库压力太大速度很慢,此时还有不断的请求访问后台,就会造成数据库崩溃。这时候hystrix容错机制,可以为客户端请求设置超时链接,添加回退的逻辑,减少集群压力。!(https://os
Stella981 Stella981
3年前
Sentinel断路器与熔断降级
前言Sentinel的熔断降级通过断路器实现,本文通过介绍熔断器的定义、如何构建熔断器、断路器校验逻辑、断路器状态转换、异常/慢调用熔断流量是如何统计等方面梳理断路器的工作原理和实现方式。 一、断路器定义Sentinel中的熔断降级使用断路器实现,先看下断路器概念,来自维基百科的定义:断路器有分简单与较进阶的版本,简单的断路器只需
SpringCloud-Hystrix服务熔断与降级工作原理&源码 | 京东物流技术团队
在生活中,如果电路的负载过高,保险箱会自动跳闸,以保护家里的各种电器,这就是熔断器的一个活生生例子。在Hystrix中也存在这样一个熔断器,当所依赖的服务不稳定时,能够自动熔断,并提供有损服务,保护服务的稳定性。在运行过程中,Hystrix会根据接口的执行状态(成功、失败、超时和拒绝),收集并统计这些数据,根据这些信息来实时决策是否进行熔断。