零、系列
歡迎來嫖從零開始SpringCloud Alibaba電商系列:
- 從零開始SpringCloud Alibaba電商系統(一)——Alibaba與Nacos服務註冊與發現
- 從零開始SpringCloud Alibaba電商系統(二)——Nacos配置中心
- 從零開始SpringCloud Alibaba電商系統(三)——Sentinel流量防衛兵介紹、流量控制demo
- 從零開始SpringCloud Alibaba電商系統(四)——Sentinel的fallback和blockHandler
一、Feign
前文我們介紹了Sentinel如何實現單節點上,某服務異常後調用‘替代方法’。那麼在微服務場景下,將Feign和Ribbon代入後,Sentinel又是怎麼玩的呢?
先來給不知道Feign和Ribbon的同學們掃個盲:
Feign:可以像在本地調用接口一樣去調用其他節點的接口。
(如在訂單服務調用庫存服務的‘減庫存方法’,只需要引入一個Serivce調用方法而不需要自己編寫一坨HTTP請求的代碼。)
Ribbon:Ribbon是Feign的底層支持,主要負責負載均衡和HTTP請求。
這裏負載均衡指的是:庫存服務做了多個節點的負載,訂單服務調用方法只需要調用其中一個庫存服務節點即可完成邏輯,如何來選擇哪個庫存節點就是Ribbon的職責。
幹說不易理解,來個例子,邏輯如上所述:庫存服務提供減庫存接口
,訂單服務消費該接口。
- 在服務提供端(即庫存服務),增加
ProductController
和reduceInventory方法(代碼基於之前的product模塊改造)。
package com.lele.mall.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RequestMapping("/product")
@RestController
public class ProductController {
@GetMapping("reduce_inventory")
public String reduceInventory(){
return "庫存減一";
}
}
- 消費端(即訂單服務)則需要另外增加關於Feign的依賴,pom.xml添加如下:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>2.1.2.RELEASE</version>
</dependency>
- 消費端application增加@EnableFeignClients註解
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
- 消費端增加對應庫存服務ProductController的FiegnClient接口,如下:
package com.lele.mall.feignclient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "product")
public interface ProductService {
@GetMapping("/product/reduce_inventory")
public String reduceInventory();
}
- 最後,在消費端新增OrderController用來消費
減庫存服務
,就是如此絲滑清爽的使用方式。
package com.lele.mall.controller;/*
* com.lele.mall.controller
* @author: lele
* @date: 2020-04-08
*/
import com.lele.mall.feignclient.ProductService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
@RequestMapping("/order")
@RestController
public class OrderController {
// 像注入本地服務一樣注入遠端服務
@Resource
private ProductService productService;
@GetMapping("apply")
public String applyOrder(){
return productService.reduceInventory();
}
}
- 分別啓動庫存服務和訂單服務,啓動成功後,頁面訪問訂單服務的 order/apply接口。
發現在order的apply服務中,成功調用到了庫存服務的reduceInventory方法。
二、Sentinel集成Feign實現多節點間的熔斷,保護節點雪崩式故障
通過上面Feign的Demo我們提出兩個問題:
1. 訂單服務調用庫存服務某個接口的時候,有庫存服務宕機了/網絡故障了/庫存服務很忙處理不過來等問題時,
訂單服務該怎麼辦?一直等肯定是不合適的。
2. 訂單服務調用庫存服務時,庫存服務總是返回非業務異常,訂單服務只能一直跟着異常嗎?
Sentinel可以很好的解決上述兩個問題,網絡故障是吧?那我就網絡故障的時候直接服務降級,降級爲本節點的某個方法總不會有問題。
庫存服務異常超過一定次數或頻率(又或是庫存服務響應時間過長)時,我們也可以先進行服務降級,然後再觀察庫存服務節點狀態是否好轉。
基於以上兩點,我們給出兩個案例:庫存服務宕機時,訂單服務進行降級;庫存服務異常次數過多時,訂單服務進行降級。
- 消費端配置feign啓用sentinel,配置文件添加(可以在nacos配置中心添加,我這裏爲了demo易調試放在了bootstrap.peoperties):
feign.sentinel.enabled=true
- 消費端的FiegnClient接口配置FallBack函數,以幫助我們在調用庫存服務失敗時能回調本地服務。
package com.lele.mall.feignclient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
// name與服務名保持一致
@FeignClient(name = "product",fallback = ProductServiceFallback.class,configuration = ProductServiceFallback.class)
public interface ProductService {
@GetMapping("/product/reduce_inventory")
public String reduceInventory();
}
// product的降級服務類
class ProductServiceFallback implements ProductService{
public String reduceInventory(){
return "訂單模塊的庫存減一";
};
}
-
停掉庫存服務系統,模擬宕機。
-
訪問訂單模塊: http://localhost:8081/order/apply 。
發現頁面輸出如下,熔斷成功!
然後來看第二個案例:
-
啓動庫存模塊。
-
啓動sentinel dashboard,不清楚dashboard是什麼的同學可以到前前文lou一眼。
-
爲庫存模塊配置sentinel相關pom、配置文件、@SentinelResource。(詳細介紹可見前前文)
8. 在dashboard找到庫存服務模塊,找到庫存服務模塊的reduceInventory接口並對其設置流量限制。
tips:需要先訪問一次reduceInventory接口纔可以在dashboard上面看到該模塊。
- 連續多次訪問訂單模塊: http://localhost:8081/order/apply
前兩次顯示爲庫存減一
,1s內之後的其他訪問就變成了訂單模塊的庫存減一
,測試成功!
三、Demo地址
六、demo 地址
注意:如果不使用nacos請去除pom中nacos相關依賴、將bootstrap.properties變更爲application.properties並添加server.port屬性。
https://github.com/flyChineseBoy/lel-mall/tree/master/mall05
這裏正在完善一個從零開始的基於SpringCloud Alibaba的電商系統,有興趣就來點個star吧!