Sentinel是阿里开源的项目,提供了流量控制、熔断降级、系统负载保护等多个维度来保障服务之间的稳定性
服务雪崩
在微服务项目中,服务与服务之间的调用错综复杂,如果一个服务出现问题,就会引起整个链路的错误,导致服务雪崩
服务雪崩效应:因服务提供者的不可用导致服务调用者的不可用,并将不可用逐渐放大的过程
容错机制
- 超时机制:对服务的调用设置超时时间,超时后做其他处理
- 限流机制:提前对服务做压测,设置服务能承受的流量值
- 隔离:与限流类似,不过是根据线程或者信号量
- 服务熔断:当服务不可用后,调用者直接进行熔断
- 服务降级:当熔断后就需要执行其他逻辑,,即降级
控制台部署
nohup java -Dserver.port=8856 -jar sentinel-dashboard-1.8.0.jar &
客户端整合
依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
配置
# sentinel控制台地址
spring.cloud.sentinel.transport.dashboard=127.0.0.1:8849
启动后访问服务任意接口后再控制台就有了对服务的信息

流量控制(QPS)
单独处理(推荐)
@RequestMapping("/test")
// 使用该注解对该接口的流控异常做处理
@SentinelResource(value = "test", blockHandler = "testBlockHandler")
public String test() {
System.out.println("订单");
return "order";
}
// 自定义流控处理,对应到blockHandler
public String testBlockHandler(BlockException e) {
return "服务繁忙,稍后再试";
}
接口代码处理完成后在控制台进行QPS设置,注意是注解上value的值

当QPS达到阈值就会返回定义的内容
注意:Sentinel没有做持久化,服务重启后配置的流控将失效
全局处理
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.csp.sentinel.slots.system.SystemBlockException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
public class MyBlockExceptionHandler implements BlockExceptionHandler {
Logger logger = LoggerFactory.getLogger(MyBlockExceptionHandler.class);
@Override
public void handle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, BlockException e) throws Exception {
// getRule()记录了哪个资源及其规则等详细信息,记录为日志
logger.info("MyBlockExceptionHandler:{}", e.getRule());
String msg;
if (e instanceof FlowException) {
msg = "接口限流了";
} else if (e instanceof DegradeException) {
msg = "服务降级了";
} else if (e instanceof ParamFlowException) {
msg = "热点参数限流了";
} else if (e instanceof SystemBlockException) {
msg = "触发系统保护规则了";
} else if (e instanceof AuthorityException) {
msg = "授权规则不通过";
} else {
msg = "系统繁忙,稍后再试";
}
httpServletResponse.setStatus(500);
httpServletResponse.setCharacterEncoding("utf-8");
httpServletResponse.setContentType(MediaType.APPLICATION_JSON_VALUE);
new ObjectMapper().writeValue(httpServletResponse.getWriter(), msg);
}
}
全局配置后控制台只需要针对接口进行配置流控即可
持久化
依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-nacos</artifactId>
</dependency>
然后需要在Nacos中添加配置管理,配置的是JSON,详情看文档的流量控制
然后配置
# sentinel持久化配置
spring.cloud.sentinel.datasource.flow-rule.nacos.server-addr=127.0.0.1:8848
# Nacos中配置的名字
spring.cloud.sentinel.datasource.flow-rule.nacos.data-id=order-service-test