1. 程式人生 > >Swoft:服務降級和熔斷器的基本使用

Swoft:服務降級和熔斷器的基本使用

服務降級

那麼如果服務C崩潰了,就回影響到服務B和服務A。

為了解決這個問題,就需要用到服務降級功能了。

回顧

(示例,介面只有一個通過商品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()方法。

熔斷器是什麼呢?

熔斷器檔案放在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"]);
    }