引入 Sentinel依赖,包含了 核心库和客户端等依赖。
com.alibaba.cloud
spring-cloud-starter-alibaba-sentinel
根据 Sentinel控制台地址为微服务添加 yml配置 。
server:
port: 18084
servlet:
context-path: /app-user-sentinel
spring:
application:
name: app-user-sentinel #应用名称 (nacos会将该名称当做服务名称)
#nacos注册中心地址
cloud:
nacos:
server-addr: 192.168.xxx.xxx:8848
discovery:
username: nacos
password: nacos
namespace: b4d0832b-a7b0-44c2-8ce5-1abe676a4736 # 必须使用命名空间id
# group: prod
#sentinel控制台地址
sentinel:
transport:
# 添加sentinel的控制台地址
dashboard: localhost:17080
# 指定应用与 Sentinel控制台交互的端口
# port: 8719
3、启动项目
启动项目,访问一下接口, Sentinel就会初始化。到此,整合 Sentinel完成。
事实监控接口的通过的 QPS和拒绝的 QPS 。同一个服务下的所有机器的簇点信息会被汇总,并且秒级地展示在"实时监控"下。 实时监控仅存储 5 分钟以内的数据,默认没有持久化。
簇点链路 :用来显示微服务的所监控的API。
簇点链路(单机调用链路)页面实时的去拉取指定客户端资源的运行情况。
提供了两种展示模式:
- 一种用树状结构展示资源的调用链路,
- 一种则不区分调用链路展示资源的运行情况。
流量控制(flow control),其原理是监控应用流量的 QPS 或并发线程数等指标,当达到指定的阈值时对流量进行控制,以避免被瞬时的流量高峰冲垮,从而保障应用的高可用性。
官方文档-流控规则:https://github.com/alibaba/Sentinel/wiki/%E6%B5%81%E9%87%8F%E6%8E%A7%E5%88%B6
- 资源名:接口的API
- 针对来源:默认是default,当多个微服务都调用这个资源时,可以配置微服务名来对指定的微服务设置阈值
- 阈值类型:分为QPS和线程数 假设阈值为2
- QPS类型:只得是每秒访问接口的次数>2就进行限流
- 线程数:为接受请求该资源分配的线程数>2就进行限流
QPS(Query Per Second):每秒请求数,就是说服务器在一秒的时间内处理了多少个请求。
进入簇点链路选择具体的访问的API,然后点击流控按钮,配置上图信息。
@RestController
@RequestMapping("/flow")
@Slf4j
public class FlowController {
@Autowired
private RestTemplate restTemplate;
/**
* http://localhost:18084/app-user-sentinel/flow/getOrderByUserId1/1
*
* @param id
* @return
*/
@RequestMapping(value = "/getOrderByUserId1/{id}")
public R getOrderByUserId1(@PathVariable("id") Integer id) {
log.info("根据userId=" + id + "查询订单信息");
String url = "http://app-order/order/findOrderByUserId/" + id;
R result = restTemplate.getForObject(url, R.class);
return result;
}
/**
* http://localhost:18084/app-user-sentinel/flow/getOrderByUserId2/5
*
* @param id
* @return
*/
@RequestMapping(value = "/getOrderByUserId2/{id}")
@SentinelResource(value = "/flow/getOrderByUserId2", blockHandler = "blockHandlerForGetOrderByUserId2", fallback = "fallbackForGetOrderByUserId2")
public R getOrderByUserId2(@PathVariable("id") Integer id) throws InterruptedException {
log.info("根据userId=" + id + "查询订单信息");
if(id == 20){
TimeUnit.SECONDS.sleep(id);
}
String url = "http://app-order/order/findOrderByUserId/" + id;
R result = restTemplate.getForObject(url, R.class);
return result;
}
public R blockHandlerForGetOrderByUserId2(Integer id, BlockException blockEx) {
log.info("BlockException。id={}, blockEx = {}", id, blockEx.getMessage());
return R.error(" getOrderByUserId2 方法被流控了。id=" + id);
}
public R fallbackForGetOrderByUserId2(Integer id, Throwable e) {
log.info("业务出异常了。ex = {}", e.getMessage());
return R.error(" getOrderByUserId2 业务出异常了。ex = " + e);
}
}
访问接口并添加 QPS流控。上面接口 QPS=2,所以,1秒内多次访问会被流控。
可以通过
@SentinelResource注解
自定义处理异常信息。
也可以新建一个类,实现 BlockExceptionHandler接口
,统一处理BlockException。
Sentinel 并发控制不负责创建和管理线程池,而是简单统计当前请求上下文的线程数目(正在执行的调用数目),如果超出阈值,新的请求会被立即拒绝,效果类似于信号量隔离。并发数控制通常在调用端进行配置。
设置并发线程数为1。
其他 Sentinel控制台的使用查看官方文档。
– 求知若饥,虚心若愚。