18

Fuse

When I was young, when the whole village had air conditioners in the summer, the fuse of the main switch in the village would automatically blow out because of the excessive electricity consumption, and the service would be stopped. There are also some extreme cases in the stock market that open the fuse processing, and it will not be fuse if it is not a last resort. The smallest unit that is fused in a Web project may not necessarily be the entire application, but may be just a certain service. We do not delve into the definition of academic terms here.

Limiting

We often encounter current limiting scenes. Sometimes the security guards limit the current to me in the subway, and my dad also limits the current to double eleven. The reason why the subway can be restricted is because we have to go through security checks and have this unified subway entrance; browsing the website is restricted because the access has a unified domain name entrance.

When we need to limit the current according to the routing rules, as long as we have a good grasp of the gateway, it is very convenient to achieve the current limit , the following schemes are all feasible

  • The distribution is similar to WAF (Web Application Firewall), see Cloud WAF Manual
  • If you don’t want to spend money, you can also install the nginx current-limiting plug-in to do similar work and deploy it yourself. In short, you can set up interception operations in front of the web application.
  • It is also possible to develop a current-limiting component in combination with the routing component in the web application, as long as the code has a unified entry, it can be easily controlled

Downgrade

In my life, I am also a degraded consumer. I used to be Tmall, then Taobao, and now Pinduoduo and Taobao special edition. Trading down really fragrant, having said that, focus on are not can not be used . Web project demotion cases, such as micro-blog feed stream, the pressure is relatively large user base information, but also the Medal user interface front-end output, service degradation focus on are not can not be used .

image.png

If it is based on the current concept of microservices, the medal query may be an independent service, so the granularity corresponding to the downgrade can be the service downgrade. Since it is an independent service unit, the request interception is back to the same scene as the current limit;
If it is not a microservice architecture, the user's medal output on which the interface depends is just an independent function or method. How to intercept it?

Option 1. Urgent release

If the back-end service is the scripting language of PHP, we can quickly and individually publish the files that need to be modified to achieve the purpose of rapid downgrade.
If the back-end service is JAVA that needs to be compiled, hot deployment is also supported for the modification of this simple scenario. A separate class file is released without restarting. For example, arthas provides similar functions.

If the publishing system does not support hot deployment or single-file publishing, but only supports the method of publishing software packages, then the rapid downgrade will take 15 to 30 minutes (Java applications with a little more complex business) to complete the deployment, which is unacceptable for Internet applications. of.

Scenario 2. Current limiting and downgrading middleware

The Java ecosystem is currently relatively mature. The well-known products are hystrix, and the one I use is sentinel . Supports single-machine qps from routing and methods to limit current. You only need to sentinel control console, and then publish and push to each machine. The machine will operate in a single-machine closed loop based on the last received current-limiting rule, and there is no need to and Middleware services to interact.

Can PHP intercept and control user mode functions and methods sentinel https://github.com/zhoumengkang/php-sentinel PHP 7.2.5 online operation OK

Install and use

Compile and install

$ 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

Configure php.ini , append after it

[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 current limit query interface
  • sentinel.api_cache_ttl interface query result cache for 2 minutes
  • sentinel.api_cache_file interface query cache path
  • sentinel.log_enabled Whether to enable user-defined method and function logging, you can use log processing tools to collect such as Alibaba Cloud SLS
  • sentinel.log_file logging path

principle

PHP_MINIT stage, register in the zend_set_user_opcode_handler opcode running of user-mode methods and functions ( ZEND_DO_UCALL )

zend_set_user_opcode_handler(ZEND_DO_UCALL, php_sentinel_call_handler)

PHP_RINIT stage, obtain the middleware configuration. Do not initiate network requests within the cache duration

php_sentinel_fetch()

Current limit strategy closed loop

php_sentinel_call_handler

When the methods or functions that have been in the current limit list are intercepted, the passed methods and functions are recorded at the same time (when the log function is turned on) and then similar to the sls report, and then the center analyzes the sls log and then decides whether to limit Stream, notify each web server through the interface.

Register a custom exception class SentinelException , and throw this exception when it is detected that the executed method or function needs to be limited.

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;

The business layer can capture the exception at the outermost layer, and output the standard error according to the business protocol.

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

The current scheme is more inclined to a fuse idea, as long as it runs to a specified method or function, an exception will be thrown, for example (with function demonstration, method also supports). It's a pity that PHP set_exception_handler can't capture the current running line and takes over exceptions. So it can only be regarded as a fuse, unless the intercepted method is not entered under some logic.

function demo(){
    $ res[] = aa();
    
    if (条件 1) {
        $res[] = bb(); // bb 函数被降级
    } else {
        $resp[] = cc();
    }
    
    return $res;
}

周梦康
9k 声望6.7k 粉丝

退隐江湖