Swoft:服務降級和熔斷器的基本使用
阿新 • • 發佈:2018-12-11
服務降級
那麼如果服務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"]);
}