文章目录
sentinel控制台安装
下载地址:https://github.com/alibaba/Sentinel/releases
本次版本:1.8.6
上一篇文章已介绍
目标
我们先说目标,为各位看官节省不匹配的时间
0、使用sentinel流控中心
1、使用nacos做配置中心
2、使用nacos做注册中心
3、微服务模块化
4、使用dubbo作为服务管理
5、使用springboot做脚手架
本次,制作springboot sentinel starter
当然,如果用springcloudalibaba-sentinel是一样的效果,我门在这只是单纯的使用springboot
实现代码地址
https://github.com/OrderDong/microservice-boot
分支:microservice-boot-1.0.5-sentinel
microservice-boot-middle-sentinel-starter
验证:microservice-boot-plat
版本说明
Dubbo :3.1.0
Springboot:2.3.1.RELEASE
sentinel:1.8.6
Nacos-config:0.2.10
制作实现
先定义yaml可识别的sentinel配置
<!--自定义yml需要引入的依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
新建元数据JSON格式文件
• 在resource文件夹下新建META-INF文件夹
• 在META-INF文件夹下新建spring-configuration-metadata.json文件
{
"groups": [
{
"name": "lwd.sentinel.dashboard",
"type": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelServerConfigurationProperties",
"sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelServerConfigurationProperties"
},
{
"name": "lwd.sentinel.api",
"type": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelApiConfigurationProperties",
"sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelApiConfigurationProperties"
}
],
"properties": [
{
"name": "lwd.sentinel.dashboard.name",
"type": "java.lang.String",
"sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelServerConfigurationProperties",
"defaultValue": "${spring.application.name}",
"description": "sentinel控制台名称"
},
{
"name": "lwd.sentinel.dashboard.server",
"type": "java.lang.String",
"sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelServerConfigurationProperties",
"defaultValue": "localhost:8080",
"description": "sentinel控制台地址"
},
{
"name": "lwd.sentinel.api.addr",
"type": "java.lang.String",
"sourceType": "org.lwd.microservice.boot.middle.sentinel.config.LwdSentinelApiConfigurationProperties",
"description": "sentinel api地址",
"defaultValue": "localhost:8719"
}
]
}
json格式说明
groups:里面的内容是自定义配置项的父节点,有多少个父节点就配置多少个groups.
group里的name是配置yml的父节点名字
group里的type、sourceType是一样的,对应的都是整个配置项对应的配置类的去全路径
properties:里面的内容是每个父节点下具体的子节点项,就是yml文件里具体设置值的地方
properties里的name是配置yml的子节点名字
properties里的type,是子节点对应配置类里的属性的数据类型,如java.lang.String等
prooerties里的description是对该节点配置项的描述
properties里的defaultValue是该节点不配置时的默认值
properties里的sourceType对应的配置类的全路径
新增配置类
package org.lwd.microservice.boot.middle.sentinel.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* sentinel API接口地址
*
* @author weidong
* @version V1.0.0
* @since 2023/7/20
*/
@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "lwd.sentinel.api")
public class LwdSentinelApiConfigurationProperties {
private String addr;
}
package org.lwd.microservice.boot.middle.sentinel.config;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
/**
* 控制台配置
*
* @author weidong
* @version V1.0.0
* @since 2023/7/20
*/
@Setter
@Getter
@Component
@ConfigurationProperties(prefix = "lwd.sentinel.dashboard")
public class LwdSentinelServerConfigurationProperties {
private String name;
private String server;
}
配置sentinel starter
• 在resource文件夹下新建META-INF文件夹
• 在META-INF文件夹下新建spring.factories文件
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.lwd.microservice.boot.middle.sentinel.MicroSentinelAutoConfiguration
实现类
package org.lwd.microservice.boot.middle.sentinel;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* 操作sentinel自动装配
*
* @author lwd
* @since 2023/6/10
*/
@Slf4j
@ComponentScan(basePackages = "org.lwd.microservice.boot.middle.sentinel.config")
@Configuration
public class MicroSentinelAutoConfiguration {
public MicroSentinelAutoConfiguration() {
log.info("sentinel组件装配完成...");
}
}
sentinel规则定义和初始化
我们在这只是定义了连接sentinel的参数,规则参数也可以这么定义,然后按照这种逻辑去加载
sentinel规则
package org.lwd.microservice.boot.middle.sentinel.rule;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.circuitbreaker.CircuitBreakerStrategy;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 资源控制规则---内存模式
* @author weidong
* @version V1.0.0
* @since 2023/7/17
*/
//@Configuration
public class SentinelRule {
public static void initSentinelRule(){
initFlowQpsRule();
initDegradeRule();
initSystemProtectionRule();
}
/**
* 流量控制规则
*
* Field 说明 默认值
* resource 资源名,资源名是限流规则的作用对象
* count 限流阈值
* grade 限流阈值类型,QPS 或线程数模式 QPS 模式
* limitApp 流控针对的调用来源 default,代表不区分调用来源
* strategy 调用关系限流策略:直接、链路、关联 根据资源本身(直接)
* controlBehavior 流控效果(直接拒绝 / 排队等待 / 慢启动模式),不支持按调用关系限流 直接拒绝
*/
// @PostConstruct
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule flowRule = new FlowRule();
flowRule.setResource("sayHello");
// Set max qps to 20
flowRule.setCount(5);
flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);
flowRule.setLimitApp("default");
rules.add(flowRule);
FlowRuleManager.loadRules(rules);
}
/**
* 熔断降级规则
*
* Field 说明 默认值
* resource 资源名,即规则的作用对象
* grade 熔断策略,支持慢调用比例/异常比例/异常数策略 慢调用比例
* count 慢调用比例模式下为慢调用临界 RT(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
* timeWindow 熔断时长,单位为 s
* minRequestAmount 熔断触发的最小请求数,请求数小于该值时即使异常比率超出阈值也不会熔断(1.7.0 引入) 5
* statIntervalMs 统计时长(单位为 ms),如 60*1000 代表分钟级(1.8.0 引入) 1000 ms
* slowRatioThreshold 慢调用比例阈值,仅慢调用比例模式有效(1.8.0 引入)
*/
private static void initDegradeRule() {
List<DegradeRule> rules = new ArrayList<>();
DegradeRule rule = new DegradeRule("circuitBreaker")
.setGrade(CircuitBreakerStrategy.ERROR_RATIO.getType())
.setCount(0.1) // Threshold is 70% error ratio
.setMinRequestAmount(5)
.setStatIntervalMs(5000) // 5s
.setTimeWindow(20);
rules.add(rule);
DegradeRuleManager.loadRules(rules);
}
/**
* 系统保护规则 (SystemRule)
* Sentinel 系统自适应限流从整体维度对应用入口流量进行控制,结合应用的 Load、CPU 使用率、总体平均 RT、入口 QPS 和并发线程数等几个维度的监控指标,
* 通过自适应的流控策略,让系统的入口流量和系统的负载达到一个平衡,让系统尽可能跑在最大吞吐量的同时保证系统整体的稳定性。
*
* Field 说明 默认值
* highestSystemLoad load1 触发值,用于触发自适应控制阶段 -1 (不生效)
* avgRt 所有入口流量的平均响应时间 -1 (不生效)
* maxThread 入口流量的最大并发数 -1 (不生效)
* qps 所有入口资源的 QPS -1 (不生效)
* highestCpuUsage 当前系统的 CPU 使用率(0.0-1.0) -1 (不生效)
*/
private static void initSystemProtectionRule() {
List<SystemRule> rules = new ArrayList<>();
SystemRule rule = new SystemRule();
rule.setHighestSystemLoad(10);
rules.add(rule);
SystemRuleManager.loadRules(rules);
}
/**
* 来源访问控制(黑白名单)
*
* 我们需要根据调用方来限制资源是否通过,这时候可以使用 Sentinel 的黑白名单控制的功能。
* 黑白名单根据资源的请求来源(origin)限制资源是否通过,若配置白名单则只有请求来源位于白名单内时才可通过;
* 若配置黑名单则请求来源位于黑名单时不通过,其余的请求通过。
*
* 调用方信息通过 ContextUtil.enter(resourceName, origin) 方法中的 origin 参数传入。
*
* 黑白名单规则(AuthorityRule)非常简单,主要有以下配置项:
*
* resource:资源名,即限流规则的作用对象
* limitApp:对应的黑名单/白名单,不同 origin 用 , 分隔,如 appA,appB
* strategy:限制模式,AUTHORITY_WHITE 为白名单模式,AUTHORITY_BLACK 为黑名单模式,默认为白名单模式
*
*/
private static void initAuthorityRule(){
AuthorityRule rule = new AuthorityRule();
rule.setResource("test");
rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
rule.setLimitApp("appA,appB");
AuthorityRuleManager.loadRules(Collections.singletonList(rule));
}
}
sentinel初始化启动和加载规则
package org.lwd.microservice.boot.middle.sentinel.init;
import com.alibaba.csp.sentinel.init.InitExecutor;
import org.lwd.microservice.boot.middle.sentinel.rule.SentinelRule;
import org.springframework.context.ConfigurableApplicationContext;
/**
* sentinel starter 初始化
*
* @author weidong
* @version V1.0.0
* @since 2023/7/21
*/
public class LwdSentinelInit {
public static void sentinelInitExecutor(ConfigurableApplicationContext context) {
// 连接到控制台,与sentinel控制台通信
//方式一:通过环境变量获取
//System.setProperty("project.name", context.getEnvironment().getProperty("spring.application.name", "sentinel"));
System.setProperty("csp.sentinel.dashboard.server", context.getEnvironment().getProperty("lwd.sentinel.dashboard.server", "1"));
System.setProperty("csp.sentinel.api.port", context.getEnvironment().getProperty("lwd.sentinel.api.addr", "1"));
//System.setProperty("sentinel.dashboard.app.hideAppNoMachineMillis", "60000");
//方式二:手动设置
//dashboard 地址
//System.setProperty("csp.sentinel.dashboard.server", "localhost:7080");
//API端口
//System.setProperty("csp.sentinel.api.port", "localhost:8719");
InitExecutor.doInit();
SentinelRule.initSentinelRule();
}
}
另外
可以用spring cloud alibaba sentinel的包,可以直接配置,我们在这没有使用,只是使用springboot去实现
按照starter的制作sentinel模式,可以制作定义的sentinel规则
外传
😜 原创不易,如若本文能够帮助到您的同学
🎉 支持我:关注我+点赞👍+收藏⭐️
📝 留言:探讨问题,看到立马回复
💬 格言:己所不欲勿施于人 扬帆起航、游历人生、永不言弃!🔥