SpringCloud - Spring Cloud Alibaba 之 Sentinel DashBoard ;RestTemplate;OpenFeign
Posted MinggeQingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringCloud - Spring Cloud Alibaba 之 Sentinel DashBoard ;RestTemplate;OpenFeign相关的知识,希望对你有一定的参考价值。
阅读本文前请参考
https://blog.csdn.net/MinggeQingchun/article/details/125718964
https://blog.csdn.net/MinggeQingchun/article/details/125725515
一、Sentinel Dashboard通信原理
1、sentinel-transport-simple-http会在客户端主机创建新端口8719
2、 当端口占用时端口逐次+1,直到可用
3、第一次启动sentinel-transport-simple-http会向Dashboard注册
4.、STSH默认间隔10秒钟向Dashboard发送心跳包通知健康状态
5、http://客户端IP:8719/api对Dashboard暴露API接口供其调用,包括获取监控数据/设置规则/查询配置信息等
6、Dashboard与STSH间采用REST风格通信
注:
因涉及开辟新端口,所以不要忘记在客户端防火墙放行8719/8720等端口
微服务暴露给Sentinel Dashboard的API接口列表
[
url: "/cnode",
desc: "get clusterNode metrics by id, request param: id=resourceName"
,
url: "/setParamFlowRules",
desc: "Set parameter flow rules, while previous rules will be replaced."
,
url: "/origin",
desc: "get origin clusterNode by id, request param: id=resourceName"
,
url: "/cluster/server/flowRules",
desc: "get cluster flow rules"
,
url: "/cluster/server/modifyFlowConfig",
desc: "modify cluster server flow config"
,
url: "/cluster/server/modifyTransportConfig",
desc: "modify cluster server transport config"
,
url: "/basicInfo",
desc: "get sentinel config info"
,
url: "/getClusterMode",
desc: "get cluster mode status"
,
url: "/cluster/client/modifyConfig",
desc: "modify cluster client config"
,
url: "/setClusterMode",
desc: "set cluster mode, accept param: mode=0|1 0:client mode 1:server mode"
,
url: "/getRules",
desc: "get all active rules by type, request param: type=ruleType"
,
url: "/api",
desc: "get all available command handlers"
,
url: "/setRules",
desc: "modify the rules, accept param: type=ruleType&data=ruleJson"
,
url: "/cluster/server/modifyNamespaceSet",
desc: "modify server namespace set"
,
url: "/cluster/client/fetchConfig",
desc: "get cluster client config"
,
url: "/cluster/server/paramRules",
desc: "get cluster server param flow rules"
,
url: "/tree",
desc: "get metrics in tree mode, use id to specify detailed tree root"
,
url: "/cluster/server/fetchConfig",
desc: "get cluster server config"
,
url: "/version",
desc: "get sentinel version"
,
url: "/clusterNode",
desc: "get all clusterNode VO, use type=notZero to ignore those nodes with totalRequest <=0"
,
url: "/jsonTree",
desc: "get tree node VO start from root node"
,
url: "/getParamFlowRules",
desc: "Get all parameter flow rules"
,
url: "/cluster/server/modifyParamRules",
desc: "modify cluster param flow rules"
,
url: "/metric",
desc: "get and aggregate metrics, accept param: startTime=startTime&endTime=endTime&maxLines=maxLines&identify=resourceName"
,
url: "/systemStatus",
desc: "get system status"
,
url: "/cluster/server/modifyFlowRules",
desc: "modify cluster flow rules"
,
url: "/cluster/server/metricList",
desc: "get cluster server metrics"
,
url: "/getSwitch",
desc: "get sentinel switch status"
,
url: "/setSwitch",
desc: "set sentinel switch, accept param: value=true|false"
,
url: "/clusterNodeById",
desc: "get clusterNode VO by id, request param: id=resourceName"
,
url: "/cluster/server/info",
desc: "get cluster server info"
]
Sentinel Dashboard控制台配置项,可以修改
二、Sentinel三种保护应用方式
1、拦截所有controller的请求url路径
Sentinel为springboot程序提供了一个starter依赖,由于sentinel starter依赖默认情况下就会为所有的HTTP服务提供限流埋点,所以在springboot 中的Controller都可以受到Sentinel的保护;
只需为应用添加 spring-cloud-starter-alibaba-sentinel依赖,所有的HTTP接口都能获得Sentinel保护,还需要为Sentinel配置保护的规则;
底层通过一个拦截器对请求url进行拦截
com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor
通过如下配置关闭对微服务的保护
#关闭sentinel对controller的url的保护
spring.cloud.sentinel.filter.enabled=false
2、通过代码方式保护应用
@GetMapping("/test3/app")
public String test3(@PathVariable("app") String app)
System.out.println("/test3/app --> " + app);
//跟踪
ContextUtil.enter("test3");
Entry entry = null;
try
entry = SphU.entry("test3");
//受sentinel保护的代码 start
int a = 10 / 0;
return restTemplate.getForObject("http://springcloud-alibaba-1-nacos-discovery-provider/test", String.class);
//受sentinel保护的代码 end
catch (BlockException e)
e.printStackTrace();
不同的异常返回不同的提示语(手动写上服务降级的代码)
if (e instanceof FlowException)
return "限流了...";
else if (e instanceof DegradeException)
return "熔断降级了...";
else if (e instanceof ParamFlowException)
return "热点参数限流了...";
else if (e instanceof SystemBlockException)
return "触发系统保护规则...";
else if (e instanceof AuthorityException)
return "授权规则不通过...";
return "熔断了.....";
catch (ArithmeticException e)
//对 int a = 10 / 0; 异常的监控(跟踪统计到 BlockException 中)
Tracer.trace(e);
return "除数不能为0";
finally
//退出关闭(类似流关闭)
if (entry != null)
entry.exit();
ContextUtil.exit();
3、通过@SentinelResource(value = "app")注解保护应用
属性 | 说明 | 必填与否 | 使用要求 |
---|---|---|---|
value | 用于指定资源的名称 | 必填 | - |
entryType | entry 类型 | 可选项(默认为 EntryType.OUT) | - |
blockHandler | 服务限流后会抛出 BlockException 异常,而 blockHandler 则是用来指定一个函数来处理 BlockException 异常的。 简单点说,该属性用于指定服务限流后的后续处理逻辑。 | 可选项 |
|
blockHandlerClass | 若 blockHandler 函数与原方法不在同一个类中,则需要使用该属性指定 blockHandler 函数所在的类。 | 可选项 |
|
fallback | 用于在抛出异常(包括 BlockException)时,提供 fallback 处理逻辑。 fallback 函数可以针对所有类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。 | 可选项 |
|
fallbackClass | 若 fallback 函数与原方法不在同一个类中,则需要使用该属性指定 blockHandler 函数所在的类。 | 可选项 |
|
defaultFallback | 默认的 fallback 函数名称,通常用于通用的 fallback 逻辑(即可以用于很多服务或方法)。 默认 fallback 函数可以针对所以类型的异常(除了 exceptionsToIgnore 里面排除掉的异常类型)进行处理。 | 可选项 |
|
exceptionsToIgnore | 用于指定哪些异常被排除掉,不会计入异常统计中,也不会进入 fallback 逻辑中,而是会原样抛出。 | 可选项 | - |
三、Sentinel对 RestTemplate 流控熔断
在application.properties配置文件中,开启sentinel对resttemplate的支持
#true开启sentinel对resttemplate的支持,false则关闭
resttemplate.sentinel.enabled=true
@Configuration
public class MyRibbonConfig
/*
在使用springcloud ribbon客户端负载均衡的时候,可以给RestTemplate bean 加一个@LoadBalanced注解,就能让这个RestTemplate在请求时拥有客户端负载均衡的能力
这个@LoadBalanced注解是来自cloud包下的一个注解
*/
// @SentinelRestTemplate(blockHandler="blockA", blockHandlerClass= MyBlockHandlerClass.class) //限流
@SentinelRestTemplate(fallback="fallbackA", fallbackClass = MyBlockHandlerClass.class) // 降级
@Bean
@LoadBalanced //与 Ribbon 集成,并开启负载均衡功能
public RestTemplate restTemplate()
return new RestTemplate();
public class MyBlockHandlerClass
/**
* 该方法一定要是static方法
*/
public static String block(String a, String b, BlockException e)
System.out.println("Block Handler--> " + a + "--" + b);
return "Block Handler.";
/**
* 限流后处理方法
*/
public static SentinelClientHttpResponse blockA(HttpRequest request,
byte[] body, ClientHttpRequestExecution execution, BlockException ex)
System.err.println("block: " + ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse("custom block info");
/**
* 熔断后处理的方法
*/
public static SentinelClientHttpResponse fallbackA(HttpRequest request,
byte[] body, ClientHttpRequestExecution execution, BlockException ex)
System.err.println("fallback: " + ex.getClass().getCanonicalName());
return new SentinelClientHttpResponse("custom fallback info");
/**
* 自定义限流降级错误信息
*/
@Slf4j
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler
@Override
public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception
log.info("UrlBlockHandler.....................................");
RestObject restObject = null;
// 不同的异常返回不同的提示语
if (e instanceof FlowException)
restObject = RestObject.builder().statusCode(100).statusMessage("接口限流了").build();
else if (e instanceof DegradeException)
restObject = RestObject.builder().statusCode(101).statusMessage("服务降级了").build();
else if (e instanceof ParamFlowException)
restObject = RestObject.builder().statusCode(102).statusMessage("热点参数限流了").build();
else if (e instanceof SystemBlockException)
restObject = RestObject.builder().statusCode(103).statusMessage("触发系统保护规则").build();
else if (e instanceof AuthorityException)
restObject = RestObject.builder().statusCode(104).statusMessage("授权规则不通过").build();
//返回json数据
response.setStatus(500);
response.setCharacterEncoding("utf-8");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
//springmvc 的一个json转换类 (jackson)
new ObjectMapper().writeValue(response.getWriter(), restObject);
//跳转
//request.getRequestDispatcher("/index.jsp").forward(request, response);
//重定向
//response.sendRedirect("http://www.baidu.com");
四、Sentinel对 OpenFeign 流控熔断
在application.properties配置文件中,开启sentinel对feign的支持
#true开启sentinel对feign的支持,false则关闭
feign.sentinel.enabled=true
@FeignClient(name = "springcloud-alibaba-1-nacos-discovery-provider",
/*fallback = EchoFeignServiceFallback.class,*/
fallbackFactory = EchoFeignServiceFallbackFactory.class,
configuration = FeignConfiguration.class)
public interface EchoFeignService
@GetMapping("/notFound")
String notFound();
@Component
public class EchoFeignServiceFallback implements EchoFeignService
@Override
public String notFound()
return "notFound fallback";
public class EchoFeignServiceFallbackFactory implements FallbackFactory<EchoFeignService>
@Override
public EchoFeignService create(Throwable throwable)
return new EchoFeignService()
@Override
public String notFound()
return "default feign invoke notFound fallbackFactory 999" + throwable.getMessage();
;
public class FeignConfiguration
@Bean
public EchoFeignServiceFallbackFactory echoFeignServiceFallbackFactory()
return new EchoFeignServiceFallbackFactory();
以上是关于SpringCloud - Spring Cloud Alibaba 之 Sentinel DashBoard ;RestTemplate;OpenFeign的主要内容,如果未能解决你的问题,请参考以下文章
Spring Cloud总结29.Zuul的FallBack回退机制
Oauth2.0 整合springCloud的Zuul 解决关键BUG 报错信息:Principal must not be null
Spring Cloud Alibaba - 02 SpringCloud SpringCloud Alibaba SpringBoot的生产版本选择