Sentinel | 限流
2020-07-23 本文已影响0人
乌鲁木齐001号程序员
Sentinel
- Sentinel 是面向分布式服务架构的轻量级流量控制组件;
- 可视化、集中化、动态化地管理分布式服务架构下微服务的限流、熔断、降级规则;
非 Springboot 方式 | 使用步骤
依赖
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.6.3</version>
</dependency>
定义资源 | 限流规则
@PostMapping
@PreAuthorize("hasRole('ROLE_ADMIN')")
public OrderInfo create(@RequestBody OrderInfo info, @AuthenticationPrincipal String username) {
// 声明了一个叫 createOrder 的资源
try (Entry entry = SphU.entry("createOrder")) {
// 这里的代码就是资源 createOrder
log.info("user is " + username);
} catch (BlockException e) {
log.info("Blocked!");
}
return info;
}
定义规则
- 为定义的资源制定规则:限流规则、熔断规则、降级规则;
package com.lixinlei.security.order.config;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* ContextRefreshedEvent 在 Springboot 项目成功启动完,所有的 Bean 都组装好之后,会触发;
*/
@Component
public class SentinelConfig implements ApplicationListener<ContextRefreshedEvent> {
/**
* 整个系统启动好了之后,会这行整个方法;
* 这里要声明一个规则;
* 这里是用代码的方式控制规则的制定,这种方式的控制程度是最高的,所有的细节都可以控制,缺点就是麻烦;
* @param contextRefreshedEvent
*/
@Override
public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) {
// 一个流量的规则
FlowRule rule = new FlowRule();
// 这个规则针对哪个资源
rule.setResource("createOrder");
// 这个规则的类型:每秒请求的数量
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// 每秒只能有 1 个请求过去
rule.setCount(1);
List<FlowRule> rules = new ArrayList<FlowRule>();
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
}
Sentinel 的日志
- Sentinel 日志的保存路径是:
~/logs/csp
; -
/home/lixinlei/logs/csp/sentinel-record.log.2020-07-23.0
中的日志记录的 Sentinel 规则的生成; -
/home/lixinlei/logs/csp/com-lixinlei-security-order-OrderApplication-metrics.log.2020-07-23.1
中纪律的是流量详情,后面的几个数字的含义依次是:| 总共放过去几个请求 | 这 1 秒内拒绝的请求 | 这 1 秒内成功响应的请求数 | 这 1 秒内响应失败的请求数 | 响应的时间 | 不知道 | 不知道 | 不知道
1595471230000|2020-07-23 10:27:10|createOrder|1|0|1|0|8|0|0|0
1595471231000|2020-07-23 10:27:11|createOrder|1|0|1|0|0|0|0|0
1595471232000|2020-07-23 10:27:12|createOrder|1|1|1|0|0|0|0|0
1595471233000|2020-07-23 10:27:13|createOrder|0|1|0|0|0|0|0|0
1595471234000|2020-07-23 10:27:14|createOrder|1|1|1|0|0|0|0|0
Sentinel Dashboard
- 从 Github 上下载
sentinel-dashboard-1.6.3.jar
,这个 jar 包本身就是 Springboot 写的一个 Web 项目; - 启动命令:
java -Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard -jar sentinel-dashboard-1.6.3.jar
; - 默认用户名密码:sentinel:sentinel;
把自己的项目接到 sentinel-dashboard 上
添加依赖
<!-- 负责和 sentinel-dashboard 通信 -->
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.6.3</version>
</dependency>
告诉微服务 sentinel-board 的位置
- 通过 JVM 参数传递:
-Dcsp.sentinel.dashboard.server=localhost:8080
; - 微服务启动后,在第一次访问微服务后,才能在 sentinel-dashboard 上看到微服务的监控信息,显示的应用名是微服务启动类的名字;
以 Springboot 的方式将 sentinel 引入微服务
依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
<version>0.9.0.RELEASE</version>
</dependency>
application.yml
spring:
application:
# sentinel-bashboard 中会显示这个名字
name: orderApi
cloud:
sentinel:
transport:
# 在 9080 启动 orderApi 的时候,sentinel 还会在 8719 这个端口起一个服务和 sentinel-dashboard 通信(发心跳)
port: 8719
# sentinel-dashboard 的地址
dashboard: localhost:8082
资源的声明 | 注解的方式
- 整个方法作为一个资源,资源名是:createOrder;
- 此时如果启动微服务,请求如果太快,就会返回 500,不同于之前不是 Springboot 方式整合 sentinel 的时候,抛出的异常在 Controller 的方法中 try...catch 了,这里没有,所以会返回 500;
@PostMapping
@PreAuthorize("hasRole('ROLE_ADMIN')")
@SentinelResource("createOrder")
public OrderInfo create(@RequestBody OrderInfo info, @AuthenticationPrincipal String username) {
// 这里的代码就是资源 createOrder
log.info("user is " + username);
return info;
}