保险丝小时候,村里夏天的时候,全村开空调,村里总开关的保险丝就会烧断自动因为耗电太多,服务会立即停止。股市也有一些极端情况开启熔断处理,不到万不得已不会熔断。Web工程中融合的最小单元不一定是整个应用,可能只是某个服务。这里我们不深究学术术语的定义。我们经常会遇到限行的场景。有时我在地铁里被保安限制,父亲也在双十一限行。地铁之所以能限流,是因为大家都要过安检,有这个统一的地铁口;浏览网站的流量是有限的,因为有统一的域名入口访问。当我们需要根据路由规则进行限流时,只要掌握好网关,就可以很方便的实现限流。以下方案都可以部署在WAF(WebApplicationFirewall)中。详见阿里云WAF手册。如果不想花钱,也可以安装nginx限流插件来做类似的工作,自己部署。简而言之,您可以在Web应用程序前面部署拦截操作。也可以在web应用中结合路由组件开发一个限流组件。只要代码有统一的入口,就可以方便的控制。在我的降级生活中,我也是一个消费降级的家伙。以前是天猫,后来是淘宝,现在是拼多多和淘宝特价版。消费降级真香。话虽如此,重点是它并非无法使用。在web项目降级的情况下,比如微博feedstream,用户基础信息压力比较大,用户的badge也在这个接口输出到前端。服务降级的重点是不是不能用。如果按照现在微服务的概念,勋章查询可能是一个独立的服务,那么降级对应的粒度可以是服务降级。由于是一个独立的服务单元,请求拦截又回到了和限流一样的场景;如果不是微服务架构,接口依赖的用户勋章输出只是一个独立的函数或方法,如何拦截?解决方案1.紧急发布如果后端服务是PHP脚本语言,我们可以快速发布需要单独修改的文件,达到快速降级的目的。如果后端服务需要JAVA编译,这个简单场景的修改也支持热部署。不用重启,单独发布一个class文件就可以了。例如,arthas提供了类似的功能。如果发布系统不支持热部署或单文件发布,只支持发布软件包的方式,快速部署需要15~30分钟(对于业务更复杂的Java应用),这对于互联网来说是无法接受的应用程序。的。方案二、限流降级中间件在Java生态中已经比较成熟。比较知名的产品有hystrix,我用的最多的是sentinel。支持单机qps去限制路由和方法。你只需要在哨兵控制台上进行配置更改,然后发布并推送到每台机器上。机器会和上次收到的限流规则单机闭环运行,中间不需要再和它通信。中间件服务交互。PHP能不能像哨兵一样拦截和控制用户态函数和方法,所以我得到了这个https://github.com/zhoumengka...PHP7.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&&makeinstall配置php.ini并追加[sentinel]extension=sentinel.sosentinel.api_url=https://mengkang.net/sentinel.htmlsentinel.api_cache_ttl=120sentinel.api_cache_file=/tmp/sentinel.rulesentinel.log_enabled=1sentinel.log_file=/tmp/sentinel.logsentinel.api_url限流查询接口sentinel.api_cache_ttl接口查询结果缓存2分钟sentinel.api_cache_file接口查询缓存路径sentinel.log_enabled是否启用自定义方法以及Function日志记录,可以使用日志处理工具收集如阿里云SLSsentinel.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拦截已经在限流列表中的方法或函数,同时记录通过的方法和函数(当log功能开启)然后上报类似sls,然后中心会分析sls日志,决定是否限流,通过接口通知各个web服务器。注册一个自定义的异常类SentinelException,当检测到需要限制执行的方法或函数时,抛出异常->ce_flags|=ZEND_ACC_FINAL;业务层可以在最外层捕获异常,按照业务协议输出标准错误。try{//项目调度器调度入口}catch(\SentinelException$exception){//标准错误输出可以是json或者html页面}目前的方案更倾向于fuse的思路,只要运行到指定的methodorfunction,它会抛出Exception,比如(通过函数演示,也支持方法)。不幸的是,PHPset_exception_handler无法捕获当前行并接管异常。所以只能算是导火索,除非被拦截的方法在某种逻辑下没有进入。函数演示(){$res[]=aa();如果(条件1){$res[]=bb();//bb函数被降级}else{$resp[]=cc();}返回$资源;}
