引言
為什麼需要Sentinel,以防業務做的太好,流量太多炸了。再者萬一微服務走了個神,也不能讓上帝的客戶在那苦苦等待吧
為什麼需要Sleuth,說白了就是便于咱取排錯,為了對咱友好,還Zipkin可視化一下
Sentinel
随着微服務的流行,服務和服務之間的穩定性變得越來越重要。Sentinel 是面向分布式服務架構的流量控制元件,主要以流量為切入點,從限流、流量整形、熔斷降級、系統負載保護、熱點防護等多個次元來幫助開發者保障微服務的穩定性。
對于限流熔斷降級這些概念我就不亂科普了,還是取人家首頁看看吧link
1整合Sentinel
1.導入依賴
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2.下載下傳控制台
去link下載下傳對應的控制台版本,啟動并通路
(base) [email protected]-H110M-S2:~/SOFT$ java -jar sentinel-dashboard-1.8.0.jar --server.port=8888
浏覽器通路link
3.配置sentinel的控制台位址資訊
#配置sentinel的控制台位址資訊
spring.cloud.sentinel.transport.dashboard=localhost:8888
#spring.cloud.sentinel.transport.port=8719 #傳輸端口
management.endpoints.web.exposure.include=*
4.在控制台調整參數
預設所有的流控設定儲存在記憶體中,重新開機失效
2允許Endpoints通路
Sentinel Endpoint 裡暴露的資訊非常有用。包括目前應用的所有規則資訊、日志目錄、目前執行個體的 IP,Sentinel Dashboard 位址,Block Page,應用與 Sentinel Dashboard 的心跳頻率等等資訊。
<!--添加sentinel審計子產品-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.2.11.RELEASE</version>
</dependency>
management.endpoints.web.exposure.include=*
參考link整合遠端調用熔斷以及網關層的流控
熔斷降級
伺服器的資源是有限的,而請求是無限的
限流:限制并發的請求通路量,超過門檻值則拒絕;
降級:服務分優先級,犧牲非核心服務(不可用或簡單處理:fallback(退路)錯誤處理資訊),保證核心服務穩定;從整體負荷考慮;
熔斷(服務降級的特殊情況):依賴的下遊服務故障觸發熔斷,避免引發本系統崩潰(應對微服務雪崩效應的一種鍊路保護機制);當檢測到該節點微服務調用響應正常後,恢複調用鍊路。
1.Feign配置服務降級
在調用放配置
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
配置檔案打開 Sentinel 對 Feign 的支援:
feign.sentinel.enabled=true
# 解決Read Timeout 異常
feign.client.config.default.read-timeout=5000
feign.client.config.default.connect-timeout=100
就以product調用seckill為例
@FeignClient(value = "gulimall-seckill",fallback = SeckillFeignServiceFallback.class)
public interface SeckillFeignService {
@GetMapping("/sku/seckill/{skuId}")
public R getSkuSeckillInfo(@PathVariable("skuId") Long skuId);
}
@Slf4j
@Component
public class SeckillFeignServiceFallback implements SeckillFeignService {
@Override
public R getSkuSeckillInfo(Long skuId) {
log.info("遠端調用異常,已降級getSkuSeckillInfo");
return R.error(BazCodeEnum.TO_MANY_REQUEST.getCode(), BazCodeEnum.TO_MANY_REQUEST.getMsg());
}
}
4.網關層流控與自定義資源限流
1.網關層流控
流控還是得從源頭把好關,論一夫當關的重要性
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-sentinel-gateway</artifactId>
<version>2.2.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
PS:為啥我給sentinel-gateway單獨加了個版本呢,因為我在這吃了個虧,沒給com.alibaba.cloud版本管理,也沒給版本,然後也沒檢查依沒依賴上,然後就。。。
下面給出SpringCloud Alibaba以及SpringCloud的版本依賴示例,以此警醒。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.3.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
你會發現下面控制台中,gateway處可以流控降級的資源都是路由
起初沒有網關的界面不對,參考link,在啟動類主函數中增加 System.setProperty(“csp.sentinel.app.type”, “1”); 重新開機sentinel控制台
2.自定義資源限流
com/atguigu/gulimall/seckill/service/impl/SeckillServiceImpl.java
public List<SeckillSkuRedisTo> blockHandler(BlockException e) {
log.error("getCurrentSeckillSkus被限流了");
return null;
}
/**
* 傳回目前時間可以參與的面紗商品資訊
* @return
*/
@SentinelResource(value = "getCurrentSeckillSkus",blockHandler = "blockHandler") //注解方式定義資源
@Override
public List<SeckillSkuRedisTo> getCurrentSeckillSkus() {
...
// 定義一段受保護的資源
try (Entry entry = SphU.entry("seckillSkus")){ //抛出異常的方式定義資源
....
}catch (BlockException e){
log.warn("資源被限流:" + e.getMessage());
}
}
Sleuth+Zipkin
Spring Cloud Sleuth為springCloud實作了一個分布式鍊路追蹤解決方案,可追蹤一個請求的跳轉在鍊路的各個部分耗時(含傳輸、服務的業務處理)為後續優化提供參考,同時如果在整個鍊路中發生了錯誤,會泛紅提醒,進入可檢視錯誤原因。
<!--引入sleuth鍊路追蹤-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>
各微服務中開啟debug日志(這個還是算了,還是用zipkin圖形可視化)
#開啟debug日志
logging.level.org.springframework.cloud.openfeign=debug
logging.level.org.springframework.cloud.sleuth=debug
安裝zipkin服務
docker run -d -p 9411:9411 openzipkin/zipkin
<!--該zipkin依賴內建了sleuth依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>
# zip伺服器位址
#spring.zipkin.base-url=
#關閉服務發現,否則會把zipkin的url當作伺服器名稱
spring.zipkin.discovery-client-enabled=false
#設定傳輸方式
spring.zipkin.sender.type=web
#設定抽樣采集率,預設為0.1即10%
spring.sleuth.sampler.probability=1
配置号之後顯著差別是,多了三逗号,,,
咱去浏覽器zipkin可視化看看,看到有條泛紅的鍊路,進去看看,通路link
原來是seckill服務的上傳三天秒殺商品在擷取coupon中的last3daysession時出錯了,往右看看各部分的時間點
CS -》SS -》… -》 SF -》CF 相鄰的相對時間一減就能擷取相對耗時(無論是網絡傳輸還是計算)
再往下看看到底是哪錯了,原來是讀取逾時(剛剛服務忘記啟動了)
備用參考link