Hystrix的替換方案
10.1 替換方案介紹
10.2 Sentinel概述
10.2.1 Sentinel簡介
10.2.2 服務熔斷區別
10.2.3 遷移方案
10.2.4 名詞解釋
10.3 Sentinel中的管理控制檯
10.3.1 下載啓動控制檯
1 下載地址
https://github.com/alibaba/Sentinel/releases/download/1.6.3/sentinel-dashboard-1.6.3.jar
2 啓動
java -Dserver.port=8080 -DCSP.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.6.3.jar
其中-Dserver.port=8080用於指定Sentinel控制檯端口8080。
從Sentinel1.6.0起,Sentinel控制檯引入基本的登錄功能,默認用戶密碼都是sentinel。
啓動Sentinel需要JDK1.8及以上版本。
10.3.2 將服務交給控制檯管理
客戶端接入Sentinel管理控制平臺
1 在客戶端引入依賴
在父項目中引入
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Greenwich.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在子項目中引入
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2 在客戶端application.properties配置啓動參數
#配置sentinel 接入sentinel平臺
spring.cloud.sentinel.transport.dashboard=localhost:8080
3 重新啓動程序
10.3.3 查看機器列表以及健康情況
10.4 通用資源保護
10.4.1 熔斷流程
10.4.2 熔斷注入
package xx.study.sc.controller;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@RestController
@RequestMapping("/order")
public class OrderController {
//注入
@Autowired
private RestTemplate restTemplate;
/**
* @SentinelResource
* blockHandler:聲明熔斷降級方法
* fallback:聲明異常執行的降級方法
* value :自定義的資源名稱 不設置的話默認當前類名.方法名
* 調用遠程服務
*/
@SentinelResource(blockHandler = "orderFallBack",fallback = "orderErrorFallBack")
@RequestMapping(value = "/buyBanana",method = RequestMethod.GET)
public String buyBanana(@RequestParam String name){
name=restTemplate.getForObject("http://service-product/product/buy?name= "+name,String.class);
String returnVal="從註冊中心收到"+name+"!!!";
return returnVal;
}
/**
* 定義降級邏輯
* 熔斷執行的降級方法
* 拋出異常的執行方法
* 和需要收到的方法返回值一致 方法參數一致
* @return
*/
public String orderErrorFallBack(String name){
return name+"報錯了,降級了";
}
public String orderFallBack(String name){
return name+"熔斷了,降級了";
}
/**
* 指定同一降級方法
*/
public String defaultFallBack(){
return "降級了";
}
}
10.4.3 Sentinel控制檯配置規則
10.5 本地配置
由於服務放在內存中的重啓後會丟失之前的配置,可以在本地配置解決此問題。
在此類中可找到Json變量定義
10.6 對RestTemplate的支持
1 在創建RestTemplate對象時構造
package xx.study.sc;
import com.alibaba.cloud.sentinel.annotation.SentinelRestTemplate;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import xx.study.sc.exception.ExceptionUtils;
@SpringBootApplication
public class RestOrderApplication {
/**
* sentinel支持對resttemplate的服務調用使用sentinel方法。在構造RestTemplate對象的
* 時候,只需要加載@SentinelRestTemplate即可
* 資源名 httpmethod:sechema://host:port/path:協議、主機、端口和路徑
* @SentinelRestTemplate
* 異常降級:
* fallback :降級方法
* fallbackClass :降級配置類
* 限流熔斷
* blockHandler
* blockHandlerClass
*
*
*/
@LoadBalanced
@Bean
@SentinelRestTemplate(fallback = "handleFallback",fallbackClass = ExceptionUtils.class,
blockHandler = "handleBlock",blockHandlerClass = ExceptionUtils.class)
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(RestOrderApplication.class);
}
}
2 寫降級配置類
package xx.study.sc.exception;
import com.alibaba.cloud.sentinel.rest.SentinelClientHttpResponse;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
public class ExceptionUtils {
/**
* 限流熔斷業務邏輯
* @param request
* @param body
* @param execution
* @param exception
* @return
*/
public static SentinelClientHttpResponse handleBlock(HttpRequest request, byte[] body, ClientHttpRequestExecution execution
, BlockException exception ){
return new SentinelClientHttpResponse("限流熔斷降級");
}
/**
* 異常降級業務邏輯
* @param request
* @param body
* @param execution
* @param exception
* @return
*/
public static SentinelClientHttpResponse handleFallback(HttpRequest request, byte[] body, ClientHttpRequestExecution execution
, BlockException exception ){
return new SentinelClientHttpResponse("限流熔斷降級");
}
}
10.7 對Feign的支持
1 引入依賴
<!-- springcloud整合openFeign-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
2 開啓sentinel支持
application.properties 開啓
#開啓對sentinel的支持
feign.sentinel.enabled=true
3 配置FeignClient
跟Hystrix相同
package xx.study.sc.feign;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
/**聲明需要調用的微服務名稱
* @FeignClient
* name:服務提供者的名稱
* fallback
*
*/
@FeignClient(name="service-product",fallback = ProductFeignClientCallBack.class)
public interface ProductFeignClient {
/**
* 配置需要調用的微服務接口
* 訪問路徑要寫全 類+方法
*/
@RequestMapping(value = "/product/buy",method = RequestMethod.GET)
public String buy(@RequestParam String name);
}
package xx.study.sc.feign;
import org.springframework.stereotype.Component;
@Component
public class ProductFeignClientCallBack implements ProductFeignClient {
@Override
public String buy(String name) {
return "feign調用,觸發降級了";
}
}
package xx.study.sc.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import xx.study.sc.feign.ProductFeignClient;
import java.util.List;
@RestController
@RequestMapping("/order")
public class OrderController {
//idea提示紅色 不用管
@Autowired
public ProductFeignClient productFeignClient;
@RequestMapping(value = "/buyBanana",method = RequestMethod.GET)
public String buyBanana(@RequestParam String name){
name=productFeignClient.buy(name);
String returnVal="從feign收到"+name+"!!!";
return returnVal;
}
}