sentinel入门

本地测试需要本地启动本地sentinel

依赖

1
2
3
4
5
6
7
8
9
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- 持久化配置 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

注解

1
2
3
@SentinelResource // d进去自己看
// fallback 后被隐藏能源
// blockhandler 不管了,开摆

配置文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
server:
port: 10000
spring:
application:
name: sentinel-service
cloud:
sentinel:
transport:
dashboard: localhost:8080 # 需要修改
web-context-unify: false # 链路
# 自动推送配置
datasource:
flow-rule: # 随便起名字
nacos:
serverAddr: sdadgz.cn:8849
username: nacos
password: sdadgz.cn
namespase: test # 命名空间
dataId: sentinel-service-flow-rule
rule-type: flow
nacos:
username: nacos
password: sdadgz.cn
discovery:
namespace: test
server-addr: sdadgz.cn:8849
feign:
sentinel:
enabled: true # sentinel接管feign

整合gateway

1
2
3
4
5
spring:
cloud:
sentinel:
transport:
dashboard: localhost:8080

整合feign

1
2
@FeignClient(value = "demo", path = "/test", fallback = DemoServiceFeignFallback.class)
// 写一个DemoServiceFeignFallback类继承当前类(DemoServiceFeign)

配置中心 限速咯

设置持久化配置

  1. 配置文件输入spring.cloud.sentinel.datasource
  2. datasource点进去,是个map
  3. map的value(DataSourcePropertiesConfiguration)点进去
  4. NacosDataSourceProperties点进去,若干配置可自定义
  5. 他的父类AbstractDataSourceProperties点进去
  6. RuleType点进去
  7. 规则名及其类得到了
  8. nacos创建配置 x-x-flow-rule ,内容:上一步获取的rule的对象数组
  9. 配置文件datasource写入对应 nacos创建的配置的dataId

例:FlowRule

狂点shift ,然后搜索FlowRule,下表不全

Field 说明 默认值
resource 资源名,资源名是限流规则的作用对象
count 限流阈值
grade 限流阈值类型,QPS 模式(1)或并发线程数模式(0) QPS 模式
limitApp 流控针对的调用来源 default,代表不区分调用来源
strategy 调用关系限流策略:直接、关联(1)、链路(2) 根据资源本身(直接)
controlBehavior 流控效果(直接拒绝/WarmUp/匀速+排队等待),不支持按调用关系限流 直接拒绝
clusterMode 是否集群限流

strtegy关联,链路

  • 关联:我关注的人限流了我也限 (1)
  • 链路:我达到阈值我关注的人限流(2)

例:匀速,5秒超时,qps1

  • warm up 需要额外增加 warmUpPeriodSec: [s]
  • 削峰填谷 需要额外增加 maxQueueingTimeMs: [ms]
1
2
3
4
5
6
7
8
9
10
11
[
{
"resource": "/sentinel/feign",
"controlBehavior": 2,
"count": 1,
"grade": 1,
"limitApp": "default",
"strategy": 0,
"maxQueueingTimeMs": 5000
}
]

全局捕获异常

你抄我,我抄你,这种谁都用的东西跟hello world一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
package cn.sdadgz.exception;

import cn.sdadgz.common.Result;
import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowException;
import com.alibaba.fastjson.JSON;
import lombok.Cleanup;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
* <p>
* 废物本物
* </p>
*
* @author sdadgz
* @since 2023/2/16 00:52:36
*/
@Component
@Slf4j
public class DefaultBlockExceptionHandler implements BlockExceptionHandler {

@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
//getRule返回资源、规则的详细信息
log.info("BlockExceptionHandler BlockException================" + e.getRule());

Result r = null;
if (e instanceof FlowException) {
r = Result.error(100, "接口被限流了");
} else if (e instanceof DegradeException) {
r = Result.error(101, "服务降级了");
} else if (e instanceof ParamFlowException) {
r = Result.error(102, "热点参数限流了");
} else if (e instanceof AuthorityException) {
r = Result.error(104, "授权规则不通过");
}

//返回Json数据
httpServletResponse.setStatus(500);
httpServletResponse.setCharacterEncoding("UTF-8");
httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
try (PrintWriter writer = httpServletResponse.getWriter()) {
writer.write(JSON.toJSONString(r));
writer.flush();
} catch (IOException ioException) {
log.error("异常:{}", ioException.toString());
}
}
}