域名估价哪个网站准确推广项目
- 作者: 五速梦信息网
- 时间: 2026年04月20日 06:52
当前位置: 首页 > news >正文
域名估价哪个网站准确,推广项目,wordpress重新,网站建设需要哪些成本自定义redission装配和集成分布式开源限流业务组件ratelimiter-spring-boot-starter的正确姿势 文章目录 1.说明1.1 pom依赖1.2 引入redisson不引入redisson-spring-boot-starter依赖1.3 引入redisson-spring-boot-starter不引入redisson,启动类排除redisson-spring-boot-start…自定义redission装配和集成分布式开源限流业务组件ratelimiter-spring-boot-starter的正确姿势 文章目录 1.说明1.1 pom依赖1.2 引入redisson不引入redisson-spring-boot-starter依赖1.3 引入redisson-spring-boot-starter不引入redisson,启动类排除redisson-spring-boot-starter的自动装配 2.自定义redission装配2.1 RedissonLockProperties2.2 RedissonLockAutoConfiguration2.4 RedisConfig2.3 nacos配置 3.集成分布式开源限流组件ratelimiter-spring-boot-starter3.1 引入依赖3.2 nacos配置3.3 基础使用3.3.1 在需要加限流逻辑的方法上添加注解 RateLimit3.3.2 RateLimit 注解说明3.3.3 限流的粒度限流 key3.3.4 触发限流后的行为 3.4 进阶用法3.4.1 自定义限流的 key3.4.1.1 RateLimitKey 的方式3.4.1.2 指定 keys 的方式3.4.1.3 自定义 key 获取函数 3.4.2 自定义限流后的行为3.4.2.1 配置响应内容3.4.2.2 自定义限流触发异常处理器3.4.2.3 自定义触发限流处理函数限流降级 3.4.3 动态设置限流大小3.4.3.1 rateExpression 的使用 3.5 直接使用限流器服务-RateLimiterService3.6压力测试3.7版本更新3.7.1 (v1.1.1版本更新内容3.7.2v1.2版本更新内容3.7.3v1.3版本更新内容 4.总结 1.说明 1.1 pom依赖 dependencygroupIdcom.github.taptap/groupIdartifactIdratelimiter-spring-boot-starter/artifactIdversion1.3/version /dependencydependencygroupIdredis.clients/groupIdartifactIdjedis/artifactIdversion3.3.0/version /dependencydependencygroupIdorg.redisson/groupIdartifactIdredisson-spring-boot-starter/artifactIdversion\({redisson.version}/version/dependency由于使用了redisson-spring-boot-starter在自定义redisson装配的时候会被redisson-spring-boot-starter里面的start默认装配了同时在使用开源分布式限流组件ratelimiter-spring-boot-starter的时候这个里面也会自动装配一个redisson所以就会产生冲突容器中会有2个redisson的bean从而导致报错所以解决办法是移除redisson-spring-boot-starter的依赖加入redisson的依赖或者不加redisson的依赖redisson-spring-boot-starter里面包含了redisson-spring-boot-starter的依赖是在启动类上将redisson-spring-boot-starter的start排除 1.2 引入redisson不引入redisson-spring-boot-starter依赖 dependencygroupIdorg.redisson/groupIdartifactIdredisson/artifactIdversion3.13.14/version /dependencyredisson https://github.com/redisson/redisson#quick-start1.3 引入redisson-spring-boot-starter不引入redisson,启动类排除redisson-spring-boot-starter的自动装配 SpringBootApplication(exclude {RedissonAutoConfiguration.class}) EnableTransactionManagement public class Application {public static void main(String[] args) {SpringApplication.run(Application.class, args);} }此时启动容器中还是会有2个redisson的bean所以需要自定义装配一个然后加上Primary为主的redisson 2.自定义redission装配 2.1 RedissonLockProperties package xxx.config;import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties;Data ConfigurationProperties(prefix redisson.lock.config) public class RedissonLockProperties {private String address;private String password;/*** 1.single* 2.master* 3.sentinel* 4.cluster*/private int mode 1;/*** 在master模式下需配置这个*/private String masterAddress;/*** 在master模式下需配置这个*/private String[] slaveAddress;/*** 在sentinel模式下需配置这个*/private String masterName;/*** 在sentinel模式下需配置这个*/private String[] sentinelAddress;/*** 在cluster模式下需配置这个*/private String[] nodeAddress;private int database 5;private int poolSize 64;private int idleSize 24;private int connectionTimeout 10000;private int timeout 3000;}2.2 RedissonLockAutoConfiguration package xx.config;import jodd.util.StringUtil; import org.redisson.Redisson; import org.redisson.api.RedissonClient; import org.redisson.config.ClusterServersConfig; import org.redisson.config.Config; import org.redisson.config.MasterSlaveServersConfig; import org.redisson.config.SentinelServersConfig; import org.redisson.config.SingleServerConfig; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary;/*** 分布式锁自动化配置** author zlf*/ Configuration ConditionalOnClass(RedissonClient.class) EnableConfigurationProperties(RedissonLockProperties.class) ConditionalOnProperty(value redisson.lock.enabled, havingValue true) public class RedissonLockAutoConfiguration {private static Config singleConfig(RedissonLockProperties properties) {Config config new Config();SingleServerConfig serversConfig config.useSingleServer();serversConfig.setAddress(properties.getAddress());String password properties.getPassword();if (StringUtil.isNotBlank(password)) {serversConfig.setPassword(password);}serversConfig.setDatabase(properties.getDatabase());serversConfig.setConnectionPoolSize(properties.getPoolSize());serversConfig.setConnectionMinimumIdleSize(properties.getIdleSize());serversConfig.setIdleConnectionTimeout(properties.getConnectionTimeout());serversConfig.setConnectTimeout(properties.getConnectionTimeout());serversConfig.setTimeout(properties.getTimeout());return config;}private static Config masterSlaveConfig(RedissonLockProperties properties) {Config config new Config();MasterSlaveServersConfig serversConfig config.useMasterSlaveServers();serversConfig.setMasterAddress(properties.getMasterAddress());serversConfig.addSlaveAddress(properties.getSlaveAddress());String password properties.getPassword();if (StringUtil.isNotBlank(password)) {serversConfig.setPassword(password);}serversConfig.setDatabase(properties.getDatabase());serversConfig.setMasterConnectionPoolSize(properties.getPoolSize());serversConfig.setMasterConnectionMinimumIdleSize(properties.getIdleSize());serversConfig.setSlaveConnectionPoolSize(properties.getPoolSize());serversConfig.setSlaveConnectionMinimumIdleSize(properties.getIdleSize());serversConfig.setIdleConnectionTimeout(properties.getConnectionTimeout());serversConfig.setConnectTimeout(properties.getConnectionTimeout());serversConfig.setTimeout(properties.getTimeout());return config;}private static Config sentinelConfig(RedissonLockProperties properties) {Config config new Config();SentinelServersConfig serversConfig config.useSentinelServers();serversConfig.setMasterName(properties.getMasterName());serversConfig.addSentinelAddress(properties.getSentinelAddress());String password properties.getPassword();if (StringUtil.isNotBlank(password)) {serversConfig.setPassword(password);}serversConfig.setDatabase(properties.getDatabase());serversConfig.setMasterConnectionPoolSize(properties.getPoolSize());serversConfig.setMasterConnectionMinimumIdleSize(properties.getIdleSize());serversConfig.setSlaveConnectionPoolSize(properties.getPoolSize());serversConfig.setSlaveConnectionMinimumIdleSize(properties.getIdleSize());serversConfig.setIdleConnectionTimeout(properties.getConnectionTimeout());serversConfig.setConnectTimeout(properties.getConnectionTimeout());serversConfig.setTimeout(properties.getTimeout());return config;}private static Config clusterConfig(RedissonLockProperties properties) {Config config new Config();ClusterServersConfig serversConfig config.useClusterServers();serversConfig.addNodeAddress(properties.getNodeAddress());String password properties.getPassword();if (StringUtil.isNotBlank(password)) {serversConfig.setPassword(password);}serversConfig.setMasterConnectionPoolSize(properties.getPoolSize());serversConfig.setMasterConnectionMinimumIdleSize(properties.getIdleSize());serversConfig.setSlaveConnectionPoolSize(properties.getPoolSize());serversConfig.setSlaveConnectionMinimumIdleSize(properties.getIdleSize());serversConfig.setIdleConnectionTimeout(properties.getConnectionTimeout());serversConfig.setConnectTimeout(properties.getConnectionTimeout());serversConfig.setTimeout(properties.getTimeout());return config;}BeanPrimarypublic RedissonClient redissonClient(RedissonLockProperties properties) {int mode properties.getMode();Config config null;switch (mode) {case 1:config singleConfig(properties);return Redisson.create(config);case 2:config masterSlaveConfig(properties);return Redisson.create(config);case 3:config sentinelConfig(properties);return Redisson.create(config);case 4:config clusterConfig(properties);return Redisson.create(config);}return null;}}2.4 RedisConfig 这里采用jedis的连接池工厂来装配一个redisTemplateLimit这个是上一篇文章中的一个配置,这里需要修改一下的不然有可能会报错的 自定义注解实现Redis分布式锁、手动控制事务和根据异常名字或内容限流的三合一的功能 https://mp.weixin.qq.com/s/aW4PU_wlNVfzPc6uGFnndApackage xxx.config;import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.cloud.context.config.annotation.RefreshScope; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.GenericToStringSerializer; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import org.springframework.stereotype.Component; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import redis.clients.jedis.Protocol;Slf4j RefreshScope Component public class RedisConfig {Value(\){spring.redis.host})private String host;Value(\({spring.redis.port})private String port;Value(\){spring.redis.password})private String password;Value(\({spring.redis.database})private String database;Value(\){spring.redis.jedis.pool.max-active})private String maxActive;Value(\({spring.redis.jedis.pool.max-idle})private String maxIdle;Value(\){spring.redis.jedis.pool.min-idle})private String minIdle;//RedisConnectionFactory是这个spring-boot-starter-data-redis中的redis的连接工厂,如果不用jedis需要引入spring-boot-starter-data-redis即可默认redisson-spring-boot-starter里面有这个依赖如果没有redisson-spring-boot-starter需要引入spring-boot-starter-data-redis可以使用的BeanSuppressWarnings(all)public RedisTemplateString, Object redisTemplate(RedisConnectionFactory factory) {// 定义泛型为 String, Object 的 RedisTemplateRedisTemplateString, Object template new RedisTemplateString, Object();// 设置连接工厂template.setConnectionFactory(factory);// 定义 Json 序列化Jackson2JsonRedisSerializer jackson2JsonRedisSerializer new Jackson2JsonRedisSerializer(Object.class);// Json 转换工具ObjectMapper om new ObjectMapper();om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);//方法二解决jackson2无法反序列化LocalDateTime的问题om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);om.registerModule(new JavaTimeModule());jackson2JsonRedisSerializer.setObjectMapper(om);// 定义 String 序列化StringRedisSerializer stringRedisSerializer new StringRedisSerializer();// key采用String的序列化方式template.setKeySerializer(stringRedisSerializer);// hash的key也采用String的序列化方式template.setHashKeySerializer(stringRedisSerializer);// value序列化方式采用jacksontemplate.setValueSerializer(jackson2JsonRedisSerializer);// hash的value序列化方式采用jacksontemplate.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}BeanJedisPool redisPoolFactory() {JedisPoolConfig jedisPoolConfig new JedisPoolConfig();jedisPoolConfig.setMaxTotal(Integer.valueOf(maxActive).intValue());jedisPoolConfig.setMaxIdle(Integer.valueOf(maxIdle).intValue());jedisPoolConfig.setMinIdle(Integer.valueOf(minIdle).intValue());JedisPool jedisPool new JedisPool(jedisPoolConfig, host, Integer.valueOf(port).intValue(), Protocol.DEFAULT_TIMEOUT, password, database);log.info(JedisPool注入成功);log.info(redis地址 host : port);return jedisPool;}BeanRedisTemplateString, Long redisTemplateLimit(JedisConnectionFactory factory) {final RedisTemplateString, Long template new RedisTemplate();template.setConnectionFactory(factory);template.setKeySerializer(new StringRedisSerializer());template.setHashValueSerializer(new GenericToStringSerializer(Long.class));template.setValueSerializer(new GenericToStringSerializer(Long.class));return template;}//springboot报错Could not resolve placeholder ‘xxx‘ in value “\({XXXX}Beanpublic static PropertySourcesPlaceholderConfigurer placeholderConfigurer() {PropertySourcesPlaceholderConfigurer placeholderConfigurer new PropertySourcesPlaceholderConfigurer();placeholderConfigurer.setIgnoreUnresolvablePlaceholders(true);return placeholderConfigurer;}}2.3 nacos配置 spring:redis:host: xxxport: 6379password: xxxxdatabase: 5# jedis配置jedis:pool:max-active: 200max-idle: 20max-wait: 2000min-idle: 5lettuce:shutdown-timeout: 0ms redisson:lock:enabled: trueconfig:address: redis://xxx:6379password: xxxx3.集成分布式开源限流组件ratelimiter-spring-boot-starter ratelimiter-spring-boot-starter https://github.com/TapTap/ratelimiter-spring-boot-starter#ratelimiter-spring-boot-starter3.1 引入依赖 maven dependencygroupIdcom.github.taptap/groupIdartifactIdratelimiter-spring-boot-starter/artifactIdversion1.3/version /dependencygradle implementation com.github.taptap:ratelimiter-spring-boot-starter:1.33.2 nacos配置 spring:ratelimiter:enabled: trueredis-address: redis://xxx:6379redis-password: xxxxresponse-body: 您请求的太快了,请慢点,不然会有点受不了哦!status-code: 5003.3 基础使用 3.3.1 在需要加限流逻辑的方法上添加注解 RateLimit 如下所示 RestController RequestMapping(/test) public class TestController {GetMapping(/get)RateLimit(rate 5, rateInterval 10s)public String get(String name) {return hello;} }3.3.2 RateLimit 注解说明 属性单位默认值是否必填描述modeenumTIME_WINDOW/TOKEN_BUCKETTIME_WINDOW否限流模式,目前可选时间窗口和令牌桶rateint无是时间窗口模式表示每个时间窗口内的请求数量、令牌桶模式表示每秒的令牌生产数量rateIntervalString1s否用于时间窗口模式表示时间窗口rateExpressionString无否通过 EL 表达式从 Spring Config 上下文中获取 rate 的值rateExpression 的优先级比 rate 高fallbackFunctionString无否自定义触发限流时的降级策略方法默认触发限流会抛 RateLimitException 异常customKeyFunctionString无否自定义获取限流 key 的方法bucketCapacityint无否用于令牌桶模式表示令牌桶的桶的大小这个参数控制了请求最大并发数bucketCapacityExpressionString无否通过 EL 表达式从 Spring Config 上下文中获取 bucketCapacity 的值bucketCapacityExpression 的优先级比 bucketCapacity 高requestedTokensint1否用于令牌桶模式表示每次获取的令牌数一般不用改动这个参数值除非你知道你在干嘛 RateLimit 注解可以添加到任意被 spring 管理的 bean 上不局限于 controller service 、repository 也可以。在最基础限流功能使用上以上三个步骤就已经完成了。 3.3.3 限流的粒度限流 key 限流的粒度是通过限流的 key 来做的在最基础的设置下限流的 key 默认是通过方法名称拼出来的规则如下 keyRateLimiter_ 类名 方法名除了默认的 key 策略ratelimiter-spring-boot-starter 充分考虑了业务限流时的复杂性提供了多种方式。结合业务特征达到更细粒度的限流控制。 3.3.4 触发限流后的行为 默认触发限流后 程序会返回一个 http 状态码为 429 的响应响应值如下 {code: 429,msg: Too Many Requests }同时响应的 header 里会携带一个 Retry-After 的时间值单位 s用来告诉调用方多久后可以重试。当然这一切都是可以自定义的进阶用法可以继续往下看 3.4 进阶用法 3.4.1 自定义限流的 key 自定义限流 key 有三种方式当自定义限流的 key 生效时限流的 key 就变成了默认的 key 自定义的 key。下面依次给出示例 3.4.1.1 RateLimitKey 的方式 RestController RequestMapping(/test) public class TestController {GetMapping(/get)RateLimit(rate 5, rateInterval 10s)public String get(RateLimitKey String name) {return get;} }RateLimitKey 注解可以放在方法的入参上要求入参是基础数据类型上面的例子如果 name kl。那么最终限流的 key 如下 keyRateLimiter_com.taptap.ratelimiter.web.TestController.get-kl3.4.1.2 指定 keys 的方式 RestController RequestMapping(/test) public class TestController {GetMapping(/get)RateLimit(rate 5, rateInterval 10s, keys {#name})public String get(String name) {return get;}GetMapping(/hello)RateLimit(rate 5, rateInterval 10s, keys {#user.name, user.id})public String hello(User user) {return hello;} }keys 这个参数比 RateLimitKey 注解更智能基本可以包含 RateLimitKey 的能力只是简单场景下使用起来没有 RateLimitKey 那么便捷。keys 的语法来自 spring 的 Spel 可以获取对象入参里的属性支持获取多个最后会拼接起来。使用过 spring-cache 的同学可能会更加熟悉 如果不清楚 Spel 的用法可以参考 spring-cache 的注解文档 3.4.1.3 自定义 key 获取函数 RestController RequestMapping(/test) public class TestController {GetMapping(/get)RateLimit(rate 5, rateInterval 10s, customKeyFunction keyFunction)public String get(String name) {return get;}public String keyFunction(String name) {return keyFunction name;} }当 RateLimitKey 和 keys 参数都没法满足时比如入参的值是一个加密的值需要解密后根据相关明文内容限流。可以通过在同一类里自定义获取 key 的函数这个函数要求和被限流的方法入参一致返回值为 String 类型。返回值不能为空为空时会回退到默认的 key 获取策略。 3.4.2 自定义限流后的行为 3.4.2.1 配置响应内容 spring.ratelimiter.enabledtrue spring.ratelimiter.response-bodyToo Many Requests spring.ratelimiter.status-code509添加如上配置后触发限流时http 的状态码就变成了 509 。响应的内容变成了 Too Many Requests 了 3.4.2.2 自定义限流触发异常处理器 默认的触发限流后限流器会抛出一个异常限流器框架内定义了一个异常处理器来处理。自定义限流触发处理器需要先禁用系统默认的限流触发处理器禁用方式如下 spring.ratelimiter.exceptionHandler.enablefalse然后在项目里添加自定义处理器如下 ControllerAdvice public class RateLimitExceptionHandler {private final RateLimiterProperties limiterProperties;public RateLimitExceptionHandler(RateLimiterProperties limiterProperties) {this.limiterProperties limiterProperties;}ExceptionHandler(value RateLimitException.class)ResponseBodypublic String exceptionHandler(HttpServletResponse response, RateLimitException e) {response.setStatus(limiterProperties.getStatusCode());response.setHeader(Retry-After, String.valueOf(e.getRetryAfter()));return limiterProperties.getResponseBody();} }3.4.2.3 自定义触发限流处理函数限流降级 RequestMapping(/test) public class TestController {GetMapping(/get)RateLimit(rate 5, rateInterval 10s, fallbackFunction getFallback)public String get(String name) {return get;}public String getFallback(String name) {return Too Many Requests name;}}这种方式实现和使用和 2.1.3、自定义 key 获取函数类似。但是多一个要求返回值的类型需要和原限流函数的返回值类型一致当触发限流时框架会调用 fallbackFunction 配置的函数执行并返回达到限流降级的效果 3.4.3 动态设置限流大小 3.4.3.1 rateExpression 的使用 从 v1.2 版本开始在 RateLimit 注解里新增了属性 rateExpression。该属性支持 Spel 表达式从 Spring 的配置上下文中获取值。 当配置了 rateExpression 后rate 属性的配置就不生效了。使用方式如下 GetMapping(/get2) RateLimit(rate 2, rateInterval 10s, rateExpression \){spring.ratelimiter.max}) public String get2(){returnget; }集成 apollo 等配置中心后可以做到限流大小的动态调整在线热更。 3.5 直接使用限流器服务-RateLimiterService 从 v1.3 版本开始限流器框架内部提供了一个限流器服务可以直接使用。当使用 RateLimiterService 后则不用关心限流注解的逻辑了所有限流逻辑都可以高度定制如下 RestController RequestMapping(/test) public class TestController {Autowiredprivate RateLimiterService limiterService;GetMapping(/limiterService/time-window)public String limiterServiceTimeWindow(String key) {Rule rule new Rule(Mode.TIME_WINDOW); // 限流策略,设置为时间窗口rule.setKey(key); //限流的 keyrule.setRate(5); //限流的速率rule.setRateInterval(10); //时间窗口大小单位为秒Result result limiterService.isAllowed(rule);if (result.isAllow()) { //如果允许访问return ok;} else {//触发限流return no;}}GetMapping(/limiterService/token-bucket)public String limiterServiceTokenBucket(String key) {Rule rule new Rule(Mode.TOKEN_BUCKET); // 限流策略,设置为令牌桶rule.setKey(key); //限流的 keyrule.setRate(5); //每秒产生的令牌数rule.setBucketCapacity(10); //令牌桶容量rule.setRequestedTokens(1); //请求的令牌数Result result limiterService.isAllowed(rule);if (result.isAllow()) { //如果允许访问return ok;} else {//触发限流return no;}} }3.6压力测试 压测工具 wrk https://github.com/wg/wrk测试环境: 8 核心 cpu jvm 内存给的 -Xms2048m -Xmx2048m 链接的本地的 redis #压测数据 kldeMacBook-Pro-6:ratelimiter-spring-boot-starter kl$ wrk -t16 -c100 -d15s –latency http://localhost:8080/test/wrk Running 15s test http://localhost:8080/test/wrk16 threads and 100 connectionsThread Stats Avg Stdev Max /- StdevLatency 6.18ms 20.70ms 281.21ms 98.17%Req/Sec 1.65k 307.06 2.30k 76.44%Latency Distribution50% 3.57ms75% 4.11ms90% 5.01ms99% 115.48ms389399 requests in 15.03s, 43.15MB read Requests/sec: 25915.91 Transfer/sec: 2.87MB压测下所有流量都过限流器qps 可以达到 2w。 3.7版本更新 3.7.1 (v1.1.1版本更新内容 1、触发限流时header 的 Retry-After 值单位由 ms 调整成了 s 3.7.2v1.2版本更新内容 1、触发限流时响应的类型从 text/plain 变成了 application/json2、优化了限流的 lua 脚本将原来的两步 lua 脚本请求合并成了一个减少了和 redis 的交互3、限流的时间窗口大小支持 Spel 从 Spring 的配置上下文中获取结合 apollo 等配置中心后支持规则的动态下发热更新 3.7.3v1.3版本更新内容 1、配置策略变化不在从应用的上下文中获取 Redis 数据源而是必须配置。但是配置的数据源在 Spring 上下文中声明了 rateLimiterRedissonBeanName应用也可以获取使用2、代码重构新增了令牌桶的限流策略支持3、抽象了限流器服务 RateLimiterService并在 Spring 上下文中声明了应用可以直接注入使用 4.总结 这个也是在生产实践后遇到的坑的一个总结ratelimiter-spring-boot-starter、redisson-spring-boot-starter同时使用会有冲突已经RedisTemplate装配上一篇文章的redisConfig配置会有报错所以这篇文章做了一个代码调整总结和分享也是方便以后快速使用不至于搞半天所以总结成文是很有必要的也是对以后的一种方便ratelimiter-spring-boot-starter开源分布式限流组件(偏业务)的使用也是非常简单参看官网就可以学会的源码写的也是很好的就不需要自己重复的去制造轮子了有这种开源好用的轮子直接拿来使用解决业务的燃眉之急ratelimiter-spring-boot-starter可以针对一个接口使用令牌桶接口总体上的限流限流 时间窗口限流针对一个用户主键key用户唯一标识对这个用户限制在3s内只能点击一次的操作防止重复点击 redisson分布式锁比如说锁一个用户唯一标识3s钟释放锁这里存在一个问题就是3s内执行的太快就容易点击多次取决于用户3s内的手续和接口每次执行的快慢,经过这3个步骤就可以让系统接口的具有3保险也就是系统接口鲁棒性得到了大大的增强希望我的分享对你有帮助请一键三连么么么哒
相关文章
-
域名购买后如何建设网站wordpress 编辑锚点
域名购买后如何建设网站wordpress 编辑锚点
- 技术栈
- 2026年04月20日
-
域名购买成功后怎么做网站做网站需要宽带
域名购买成功后怎么做网站做网站需要宽带
- 技术栈
- 2026年04月20日
-
域名跟空间都有了怎么做网站wordpress 下载统计
域名跟空间都有了怎么做网站wordpress 下载统计
- 技术栈
- 2026年04月20日
-
域名过期做的网站怎么办网站建设售后服务费包括哪些
域名过期做的网站怎么办网站建设售后服务费包括哪些
- 技术栈
- 2026年04月20日
-
域名价格查询网站搭建跨境电商平台
域名价格查询网站搭建跨境电商平台
- 技术栈
- 2026年04月20日
-
域名价格预估宁波网站推广优化收费情况
域名价格预估宁波网站推广优化收费情况
- 技术栈
- 2026年04月20日
