Swoft:服务降级和熔断器的基本使用

服务降级

服务降级,其实对功能的一种容错机制.
https://doc.swoft.org/master/zh-CN/service-governance/fallback.html
在这里插入图片描述
假设一个功能 需要服务A用户注册、服务B发送邮件、服务C记录日志,并且这3者是一个调用链

那么如果服务C崩溃了,就回影响到服务B和服务A。

为了解决这个问题,就需要用到服务降级功能了。

回顾

https://blog.csdn.net/github_26672553/article/details/82784834
前面讲了RPC服务端,需要在app/Lib/目录下写一个接口类,然后在app/Services/目录下实现该接口。

(示例,接口只有一个通过商品id获取库存的方法,并且在实现类中我们写死了所有商品返回的库存都是100)

如果我们的服务发生了异常(也就是app/Services/ProductService.php里方法异常),比如:


/**
 * @method ResultInterface deferGetStockQty(int $product_id)
 * @Service(version="1.0")
 */
class ProductService implements ProductInterface
{
    public function getStockQty(int $product_id)
    {
        throw new Exception("product not exist!");
        return 100;
    }
}

这个时候我们就可以来看看什么是服务降级了。

1、定义降级服务
app/Fallback/目录下创建ProductServiceFallback.php文件,此类同样继承自ProductInterface接口,代码如下:

<?php


namespace App\Fallback;
use App\Lib\ProductInterface;
use Swoft\Core\ResultInterface;
use Swoft\Sg\Bean\Annotation\Fallback;

/**
 * @Fallback("ProductFallback")
 * @method ResultInterface deferGetStockQty(int $product_id)
 */
class ProductServiceFallback implements ProductInterface
{
    public function getStockQty(int $product_id)
    {
        return 50; #我们在这里返回库存为50
    }

}

注意:@Fallback注解,我们这个降价服务名称叫ProductFallback

2、怎么使用降级服务呢?
来到控制器


/**
 * @Controller(prefix="/product")
 * @Middleware(class=ProductMiddleware::class)
 */
class ProductController{
    /**
     * @Reference(name="user", version="1.0", fallback="ProductFallback")
     * @var ProductInterface
     */
    private $productService;

    /**
     * @RequestMapping(route="test", method=RequestMethod::GET)
     */
    public function test()
    {
        // 获取id为110的产品库存
        $qty = $this->productService->getStockQty(110);
        return $qty;
    }
}

@Reference注解里 注定降价服务是ProductFallback

这样当客户端访问到Product控制器test方法的时候,如果getStockQty()方法发生异常情况,就会进入app/Fallback/ProductServiceFallback类中的getStockQty()方法。

熔断器是什么呢?

服务A用户注册、服务B发送邮件、服务C记录日志,我们明知道服务C不可用,何必还要每次都调用它呢?
https://doc.swoft.org/master/zh-CN/service-governance/breaker.html

熔断器文件放在app/Breaker/目录下,默认该目录中已经有了一个名叫user的熔断器UserBreaker.php,熔断器也有单独的配置文件在config/properties/breaker.php,我们看一下user熔断器的配置:

return [
    'user' => [
        'failCount'    => 3,
        'successCount' => 3,
        'delayTime'    => 500,
    ],
];

在这里插入图片描述
当熔断器处于关闭状态的时候,就直接调用降级服务

怎么使用熔断器?

RPC中默认是根据@Reference注解指定的服务名称,加载名称相同的熔断器,进行逻辑处理。

可以再任意逻辑中使用熔断器

\breaker('name')->call($handler, $params, $fallback);

比如我们的案列中:

    // 异常之后 调用这个方法
    public function myFallback(){
        return 9;
    }
    function myCall(){
        // 处理业务
        throw new Exception("异常了");
    }

    /**
     * @RequestMapping(route="test", method=RequestMethod::GET)
     */
    public function test()
    {
        // 获取id为110的产品库存
//        $qty = $this->productService->getStockQty(110);
//        return $qty;

        \breaker("user")->call([$this,"myCall"],[],[$this,"myFallback"]);
    }

猜你喜欢

转载自blog.csdn.net/github_26672553/article/details/82807188