说明:
本文是基于Spring boot,引入nacos和sentinel实现热更新限流策略,对接口做限流控制
1 引入依赖
<!-- 注册中心--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <!-- 配置中心 --> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <!-- 限流依赖--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId> <version>2021.0.4.0</version> </dependency> |
2 添加配置类
添加配置变更监听,限流策略修改可实时同步到服务
package com.xlt.config; import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager; import com.alibaba.fastjson.JSON; import com.geely.idc.imd.anonymize.worker.config.propety.AnonSentinelProperties; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.context.environment.EnvironmentChangeEvent; import org.springframework.context.ApplicationEvent; import org.springframework.context.annotation.Configuration; import org.springframework.context.event.EventListener; import javax.annotation.PostConstruct; import java.util.Set; @Configuration public class SentinelConfig { private final Logger log = LoggerFactory.getLogger(SentinelConfig.class); @Autowired private SentinelProperties sentinelProperties; @PostConstruct public void init() { loadFlowRules(); } /** * 添加配置变更监听,热更新限流规则 * * @param event */ @EventListener public void handleEvent(ApplicationEvent event) { if (event instanceof EnvironmentChangeEvent) { EnvironmentChangeEvent environmentChangeEvent = (EnvironmentChangeEvent) event; Set<String> keys = environmentChangeEvent.getKeys(); boolean match = keys.stream().anyMatch(e -> e.startsWith(sentinelProperties.getConfigKey())); if (match) { loadFlowRules(); } } } private void loadFlowRules() { if (sentinelProperties.isEnable()) { log.info("Sentinel flow rule changed: {}", JSON.toJSON(sentinelProperties.getRules())); FlowRuleManager.loadRules(sentinelProperties.getRules()); } } } |
配置类封装限流规则对象
@Data @Component @RefreshScope @ConfigurationProperties(prefix = "sentinel") public class SentinelProperties { private boolean enable = false; private List<FlowRule> rules; private String configKey = "sentinel.rules"; } |
3 标明限流资源
接口添加注解@SentinelResource,与限流规则资源相对应
@PostMapping("/images/anonymize") @SentinelResource(value = "imageAnonymize") public ApiResponse<AnonImageVO> anonymize(@RequestBody byte[] file) { return anonymizeService.anonymize(file); } @PostMapping("/images/anonymize/path") @SentinelResource(value = "imageAnonymizePath") public ApiResponse anonymize(@RequestParam(value = "filePath") String filePath) { return ApiResponse.success(anonymizeService.anonymize(filePath)); } |
4 添加nacos配置
模块配置文件anon-worker.yaml添加限流规则配置
sentinel: enable: true rules: - resource: imageAnonymize limitApp: default grade: 1 count: 3 strategy: 0 controlBehavior: 2 maxQueueingTimeMs: 2000 clusterMode: false - resource: imageAnonymizePath limitApp: default grade: 1 count: 1 strategy: 0 controlBehavior: 0 clusterMode: false |
5 配置说明
限流规则配置说明,对于上图的配置Sentinel把它抽象成一个FlowRule类,与其属性一一对应
属性 | 类型 | 取值范围 | 说明 |
---|---|---|---|
resource | String | 资源名,与限流接口注解标识保持一致 | |
limitApp | String | default、other | 限流来源,默认为default不区分来源 |
grade | int | 0(thread)、1(QPS) | 限流类型,有QPS和并发线程数两种类型 |
count | double | 限流阈值 | |
strategy | int | 0(直接)、1(关联)、2(链路) | 流控策略 0.直接:当api大达到限流条件时,直接限流 |
controlBehavior | int | 0(快速失败)、1(预热启动)、2(排队等待)、3(预热启动排队等待) | 流控效果 |
warmUpPeriodSec | int | 流控效果为预热启动时的预热时长(秒),默认10s | |
maxQueueingTimeMs | int | 流控效果为排队等待时的等待时长 (毫秒),默认500ms | |
clusterMode | boolean | 集群模式 |
注意:
上述配置只适配单实例服务资源限流,如要引入到集群模式,还需参考Sentinel集群模式配置方式,做相应适配修改。