指路:
Sentinel服务器容错简介
Sentinel规则详解
docker pull bladex/sentinel-dashboard:1.8.0
docker run --name sentinel -p 8858:8858 --ulimit nofile=1024 -d bladex/sentinel-dashboard:1.8.0
[Service]
LimitNOFILE=1048576
LimitNPROC=1048576
LimitCORE=infinity
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-sentinelartifactId>
dependency>
spring:
cloud:
sentinel:
transport:
dashboard: 虚拟机ip:8858
@Slf4j
@RestController
@RequestMapping("/order")
public class OrderController {
@GetMapping("/message1")
public String message1() {
return "message1";
}
@GetMapping("/message2")
public String message2() {
return "message2";
}
}
@GetMapping("/message1")
@SentinelResource(value = "message1", blockHandler =
"message1BlockHandler")
public String message1() {
return "message1";
}
// 此处需要注意:是 BlockException,而不是 BlockedException
public String message1BlockHandler(BlockException e) {
return "被流控了.....";
}
@RestControllerAdvicepublic class GlobalExceptionHandler implements BlockExceptionHandler {
@Override public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
String s = null;
if (e instanceof FlowException) {
s = "流控限流....";
} else if (e instanceof DegradeException) {
s = "服务降级....";
} else if (e instanceof ParamFlowException) {
s = "热点参数限流....";
} else if (e instanceof SystemBlockException) {
s = "触发系统保护规则....";
} else if (e instanceof AuthorityException) {
s = "授权规则不通过....";
}
response.setStatus(500);
response.setCharacterEncoding("utf-8");
response.setContentType(MediaType.APPLICATION_JSON_VALUE);
response.getWriter().print(s);
}
}
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-loadbalancerartifactId>
dependency>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-openfeignartifactId>
dependency>
server:
port: 8072
spring:
application:
name: order-service # 服务的名称,它会注册到注册中心中,这个名称唯一
cloud:
# 配置nacos地址
nacos:
discovery
server-addr: 192.168.65.128:8848 # 指定注册中心中心地址
# 配置Feign日志
openfeign:
client:
config:
order-service:
logger-level: basic
sentinel:
transport:
dashboard: 192.168.65.128:8858
clientIp: 192.168.65.1
webContextUnify: false # 关闭context收敛
feign:
sentinel:
enabled: true
@Component
public class OpenFeignClientImpl implements OpenFeignClient {
// 当远端服务没找到、服务出错时的一个处理方法。
@Override
public String reduce(String commodityCode, int count) {
return "请求稍后再试......";
}
}
@RestController@RequestMapping("/order")
public class OrderController {
@Resource private OpenFeignClient openFeignClient;
@GetMapping("/add/{commodityCode}/{count}")
public Map<String, Object> add(@PathVariable String commodityCode, @PathVariable int count) {
String result = openFeignClient.reduce(commodityCode, count);
Order order = Order.builder()
.commodityCode(commodityCode)
.count(count)
.money(300)
.build();
Map<String, Object> map = new HashMap<>();
map.put("order", order);
map.put("storage", result);
return map;
}
}
每次重启服务都要重新在 Sentinel客户端设置规则,太麻烦了。
生产环境下一般更常用的是 push 模式的数据源,如远程配置中心(Zookeeper、Nacos、Apollo等),推送的操作不应由 Sentinel 客户端进行,而应该经控制台统一进行管理,直接进行推送。数据源仅负责获取配置中心推送的配置并更新到本地。
因此推送规则正确做法应该是 配置中心控制台 > 配置中心 > Sentinel数据源 > Sentinel,而不是经 Sentinel 数据源推送至配置中心。
其原理就是使用 nacos 配置中心编写 json配置文件,其中配置了 Sentinel 规则;启动 Spring 是由Spring 导入配置,Sentinel 便能自动识别到配置文件,并生成规则。
<dependency>
<groupId>com.alibaba.cspgroupId>
<artifactId>sentinel-datasource-nacosartifactId>
dependency>
[
{
"resource": "/order/message1",
"limitApp": "default",
"grade": 1,
"count": 2,
"strategy": 0,
"controlBehavior": 0
}
]
server:
port: 8072
spring:
application:
name: order-service # 服务的名称,它会注册到注册中心中,这个名称唯一
cloud:
sentinel:
transport:
dashboard: 192.168.65.128:8858
clientIp: 192.168.65.1
webContextUnify: false # 关闭context收敛
datasource:
flow-rule: # 此名称可以自定义
nacos:
server-addr: 192.168.65.128:8848 # nacoc地址
dataId: order-sentinel-flow-rule
groupId: DEFAULT_GROUP
rule-type: flow # 还可以是:degrade、authority、param-flow 等