「令牌桶java」令牌桶限流
本篇文章给大家谈谈令牌桶java,以及令牌桶限流对应的知识点,希望对各位有所帮助,不要忘了收藏本站喔。
本文目录一览:
- 1、spring cloud gateway系列教程2——GatewayFilter_下篇
- 2、云南java课程分享分布式限流的运行原理
- 3、异步处理http请求同步返回结果
- 4、Spring Cloud微服务体系的组成
- 5、求java多线程遍历目录的完整代码,能运行的那种
- 6、Redis 限流的3种方式,还有谁不会
spring cloud gateway系列教程2——GatewayFilter_下篇
接 上篇
RequestRateLimiter GatewayFilter Factory使用 RateLimiter 来决定当前请求是否允许通过,如果不允许,则默认返回状态码 HTTP 429 - Too Many Requests 。
RequestRateLimiter GatewayFilter可以使用一个可选参数 keyResolver 来做速率限制。
keyResolver 是 KeyResolver 接口的一个实现bean,在配置里面,通过SpEL表达式 #{@myKeyResolver} 来管理bean的名字 myKeyResolver 。
KeyResolver.java.
KeyResolver 接口允许你使用不同的策略来得出限制请求的key,未来,官方也会推出一些 KeyResolver 的不同实现。
KeyResolver 默认实现是 PrincipalNameKeyResolver ,通过 ServerWebExchange 中获取 Principal ,并以 Principal.getName() 作为限流的key。
如果 KeyResolver 拿不到key,请求默认都会被限制,你也可以自己配置 spring.cloud.gateway.filter.request-rate-limiter.deny-empty-key :是否允许空key, spring.cloud.gateway.filter.request-rate-limiter.empty-key-status-code :空key时返回的状态码。
application.properties.
基于 Stripe 的redis实现方案,依赖 spring-boot-starter-data-redis-reactive Spring Boot starter,使用的是令牌桶算法。
redis-rate-limiter.replenishRate 配置的是每秒允许通过的请求数,其实就是令牌桶的填充速率。
redis-rate-limiter.burstCapacity 配置的是一秒内最大的请求数,其实就是令牌桶的最大容量,如果设置为0,则会阻塞所有请求。
所以可以通过设置相同的 replenishRate 和 burstCapacity 来实现匀速的速率控制,通过设置 burstCapacity 大于 replenishRate 来允许系统流量瞬间突发,但是对于这种情况,突发周期为 burstCapacity / replenishRate 秒,如果周期内有两次请求突发的情况,则第二次会有部分请求丢失,返回 HTTP 429 - Too Many Requests 。
application.yml.
Config.java.
上面定义了每个用户每秒10个请求的速率限制,允许20的突发流量,突发完,下一秒只允许10个请求通过了, KeyResolver 定义了通过请求获取请求参数 user 作为key。
你也可以实现 RateLimiter 接口自定义自己的请求速率限制器,在配置文件中使用SpEL表达式配置对应的bean的名字即可。
application.yml.
RedirectTo GatewayFilter Factory使用 status 和 url 两个参数,其中 status 必须是300系列的HTTP状态码, url 则是跳转的地址,会放在响应的 Location 的header中(http协议中转跳的header)。
application.yml.
上面路由会执行302重定向到 。
RemoveNonProxyHeaders GatewayFilter Factory转发请求是会根据 IETF 的定义,默认会移除下列的http头信息:
你也可以通过配置 spring.cloud.gateway.filter.remove-non-proxy-headers.headers 来更改需要移除的header列表。
RemoveRequestHeader GatewayFilter Factory配置header的name,即可以移除请求的header。
application.yml.
上面路由在发送请求给下游时,会将请求中的 X-Request-Foo 头信息去掉。
RemoveResponseHeader GatewayFilter Factory通过配置header的name,会在响应返回时移除header。
application.yml.
上面路由会在响应返回给gateway的客户端时,将 X-Response-Foo 响应头信息去掉。
RewritePath GatewayFilter Factory使用路径 regexp 和替换路径 replacement 两个参数做路径重写,两个都可以灵活地使用java的正则表达式。
application.yml.
对于上面的例子,如果请求的路径是 /foo/bar ,则gateway会将请求路径改为 /bar 发送给下游。
RewriteResponseHeader GatewayFilter Factory的作用是修改响应返回的header内容,需要配置响应返回的header的 name ,匹配规则 regexp 和替换词 replacement ,也是支持java的正则表达式。
application.yml.
举个例子,对于上面的filter,如果响应的header X-Response-Foo 的内容是 /42?user=fordpassword=omg!whatflag=true ,这个内容会修改为 /42?user=fordpassword=***flag=true 。
SaveSession GatewayFilter Factory会在请求下游时强制执行 WebSession::save 方法,用在那种像 Spring Session 延迟数据存储的,并在请求转发前确保session状态保存情况。
application.yml.
如果你将 Spring Secutiry 于 Spring Session 集成使用,并想确保安全信息都传到下游机器,你就需要配置这个filter。
SecureHeaders GatewayFilter Factory会添加在返回响应中一系列安全作用的header,至于为什么,英文好的可以看一下 这篇博客 。
默认会添加这些头信息和默认内容:
如果你想修改这些头信息的默认内容,可以在配置文件中添加下面的配置:
前缀: spring.cloud.gateway.filter.secure-headers
上面的header对应的后缀:
前后缀接起来即可,如: spring.cloud.gateway.filter.secure-headers.xss-protection-header
SetPath GatewayFilter Factory采用路径 template 参数,通过请求路径的片段的模板化,来达到操作修改路径的母的,运行多个路径片段模板化。
application.yml.
对于上面的例子,如果路径是 /foo/bar ,则对于下游的请求路径会修改为 /bar 。
SetResponseHeader GatewayFilter Factory通过设置 name 和 value 来替换响应对于的header。
application.yml.
对于上面的例子,如果下游的返回带有头信息为 X-Response-Foo:1234 ,则会gateway会替换为 X-Response-Foo:Bar ,在返回给客户端。
SetStatus GatewayFilter Factory通过配置有效的Spring HttpStatus 枚举参数,可以是类似于404的这些数字,也可以是枚举的name字符串,来修改响应的返回码。
application.yml.
上面例子中,两种路由都会将响应的状态码设置为401。
StripPrefix GatewayFilter Factory通过配置 parts 来表示截断路径前缀的数量。
application.yml.
如上面例子中,如果请求的路径为 /name/bar/foo ,则路径会修改为 /foo ,即将路径的两个前缀去掉了。
Retry GatewayFilter Factory可以配置针对不同的响应做请求重试,可以配置如下参数:
application.yml.
上面例子,当下游服务返回502状态码时,gateway会重试3次。
RequestSize GatewayFilter Factory会限制客户端请求包的大小,通过参数 RequestSize 来配置最大上传大小,单位字节。
application.yml.
如果请求大小超过5000kb限制,则会返回状态码 413 Payload Too Large 。
Modify Request Body GatewayFilter Factory可以修改请求体内容,这个只能通过java来配置。
Modify Response Body GatewayFilter Factory用于修改响应返回的内容,同样只能通过java配置。
这一章接着上一章介绍了Spring Cloud Gateway官方的Gateway Filter使用场景,下一章讲 Global Filters的使用 。
如果想查看其他spring cloud gateway的案例和使用,可以点击 查看
云南java课程分享分布式限流的运行原理
分布式编程架构技术我们在前几期的文章中已经给大家简单分析过很多次了,今天我们就一起来了解一下API网关分布式限流的运行原理都有哪些。
API网关中针对一个API、API分组、接入应用APPID,IP等进行限流。这些限流条件都将会产生一个限流使用的key,在后续的限流中都是对这个key进行限流。
限流算法通常在API网关中可以采用令牌桶算法实现。
必须说明一点的是分布式限流由于有网络的开销,TPS的支持隔本地限流是有差距的,因此在对于TPS要求很高的场景,建议采用本地限流进行处理。
下面讨论我们应该采用redis的哪一种分布式锁的方案:
由于redis事务要得到锁的效果需要在高TPS时会产生大量的无效的访问请求,所以不建议在这种场景下使用。
SETNX/EX的锁方案会产生在过期时间的问题,同时也有异步复制master数据到slave的问题。相比lua方案会产生更多的不稳定性。
我建议采用lua的方案来实施分布式锁,因为都是单进程单线程的执行,因此在TPS上和二种方案没有大的区别,而且由于只是一个lua脚本在执行,甚至是可能纯lua执行可能会有更高的TPS。当然是lua脚本中可能还是会去设置过期时间,但是应用server宕机并不会影响到redis中的锁。当然master异步复制的问题还是有,但是并不会造成问题,因为数据只会有1个lua脚本执行问题,下一个执行就正常了。
在实现方案的时候使用了Jedis库,云南java课程认为有一些问题在方案的实现层面我已经去做过验证了,可能也会是读者的疑问。
异步处理http请求同步返回结果
异步处理,同步返回?为什么会有这样一个需求?既然接口要求同步返回,那么直接阻塞就好了,要什么异步消息同步返回?高并发保护系统的手段是缓存、限流、降级。限流有许多的手段,想令牌桶、漏桶算法按数量限流,也有使用消息队列,排队限流的。至于使用消息队列的好处就不多说了,这里主要将如何实现这个需求,有一个系统比较的不稳定,但是没人维护,又不能替换它,只能在他的上层加一层来保护她,可以限流处理,也可以用mq让它以他的最大处理能力处理。说白了这东西就是一个缓冲系统,可替代性高,存粹的技术型应用,由于新鲜所以我觉得可以一试;
首先我们来选型,分析需求:使用消息队列异步请求,那么选型消息队列: zeromq、rabbitmq、activemq、kafka、rocketmq等等,消息队列很多如果没有什么要求,那么都可以选,但是首先我们需要考虑实现问题呢,使用的mq是否支持。我们需要可以排队,那么zeromq就不能选了,activemq有较小概率丢失消息,一般我不太爱用这个。好了我们实现这个需求不需要什么复杂的功能,那么剩下的都是可以选的,接下来就是考虑架设成本和易用性的问题。rabbitmq的时效性非常的好,但是吞吐量不及kafka和rocketmq,而且隔热你用的较少;所以一般来说我习惯在kafka和rocketmq中选择。rocketmq综合性能比较好,而且有很多的功能(消息提交重新消费、延时消费等),做支付金融首选rocketmq,但是我们这里不需要用到这些,所以这里用了kafka。
有了异步处理消息的mq,我们还需要一个保存mq处理完的返回值队列,能让阻塞的线程获取到。因为要分布式的,所以这个队列不能是java中的数据,所以这里使用redis保存mq处理完的数据。
接下来我们先构造系统,首先我们有一个web服务,用来接收http的请求,接受请求后发送mq处理,然后阻塞当前处理的线程,等待mq处理完成,从redis的队列中取出数据,现在还差一个mq的接收方,实现一个server服务,接受mq消息并处理,然后将数据放入redis,并且通知web的这个线程消息已经处理完毕,让web这个阻塞的线程取出redis中处理完成的数据。至于通知需要广播通知,因为分布式的话这个处理请求的线程会在任意一台web服务中,至于这个通知我们可以用redis的发布订阅功能来实现;
整体我们就有2个服务,一个web,一个server,之间通过mq通信,redis共享数据,redis发布订阅同步状态唤醒线程。
首先是web端的实现,简单的springboot项目加上web依赖,这里不赘述,这里我们模拟场景:我们需要去一个三方系统获取用户信息,通过后台http调用获取他的用户信息,用户要么输入手机,用户名或邮箱和密码(加密的);
以上是web端的处理,是关键部分,接下来是server端的处理,比较简单,就简单叙述下:
在web中向kafka中推送了一条获取用户信息的消息,接下来就只要处理一下步骤:
srver端消费消息
反序列化
http调用第三方,同步获取返回结果(这里注意配置http调用的超时时间和异常处理)
将http的返回结果用消息中的requestId作为key写入redis
最后通过发布订阅返回requestId处理完成的消息
到这里这条请求的处理又回到了web端:
web端收到了redis的发布订阅消息,从 GlobalThreadMap 中用发布订阅的requestId(也就是一开始的UUID生成的id)取出被park的线程执行unpark唤醒,之后 result.get(5, TimeUnit.SECONDS) 就能获取从redis中取出的数据完成一次请求处理;
Spring Cloud微服务体系的组成
Netflix Eureka是Spring Cloud服务注册发现的基础组件
Eureka提供RESTful风格(HTTP协议)的服务注册与发现
Eureka采用C/S架构,Spring Cloud内置客户端
启用应用,访问
Eureka客户端开发要点
maven依赖spring-cloud-starter-netflix-eureka-client application.yml
配置eureka.client.service-url.defaultZone
入口类增加@EnableEurekaClient
先启动注册中心,在启动客户端,访问 localhost:8761查看eureka注册中心,看到客户端注册
Eureka名词概念
Register - 服务注册, 向Eureka进行注册登记
Renew - 服务续约,30秒/次心跳包健康检查.90秒未收到剔除服务
Fetch Registries - 获取服务注册列表,获取其他微服务地址
Cancel - 服务下线, 某个微服务通知注册中心暂停服务
Eviction - 服务剔除,90秒未续约,从服务注册表进行剔除
Eureka自我保护机制
Eureka在运行期去统计心跳失败率在15分钟之内是否低于 85%
如果低于 85%,会将这些实例保护起来,让这些实例不会被剔除
关闭自我保护:eureka.服务实例.
enable-self-preservation: false
PS: 如非网络特别不稳定,建议关闭
Eureka高可用配置步骤
服务提供者defaultZone指向其他的Eureka
客户端添加所有Eureka 服务实例 URL
Actuator自动为微服务创建一系列的用于监控的端点
Actuator在SpringBoot自带,SpringCloud进行扩展
pom.xml依赖spring-boot-starter-actuator
RestTemplate + @LoadBalanced 显式调用
OpenFeign 隐藏微服务间通信细节
Ribbon是RestTemplate与OpenFeign的通信基础
Feign是一个开源声明式WebService客户端,用于简化服务通信
Feign采用“接口+注解”方式开发,屏蔽了网络通信的细节
OpenFeign是SpringCloud对Feign的增强,支持Spring MVC注解
1.新建Spring boot Web项目,application name 为 product-service
在pom.xml中引入依赖
spring-cloud-starter-alibaba-nacos-discovery作用为向Nacos server注册服务。
spring-cloud-starter-openfeign作用为实现服务调用。
2.修改application.yml配置文件
3.在启动类上添加@EnableDiscoveryClient、@EnableFeignClients注解
4.编写OrderClient Interface
注:/api/v1/order/test 会在下面order-service声明。
OrderClient.java
5.编写Controller和service
ProductController.java
ProductService.java
1.OpenFeign开启通信日志
基于SpringBoot的logback输出,默认debug级别
设置项:feign.client.config.微服务id.loggerLevel
微服务id:default代表全局默认配置
2.通信日志输出格式
NONE: 不输出任何通信日志
BASIC: 只包含URL、请求方法、状态码、执行时间
HEADERS:在BASIC基础上,额外包含请求与响应头
FULL:包含请求与响应内容最完整的信息
3.OpenFeign日志配置项
LoggerLevel开启通信日志
ConnectionTimeout与ReadTimeout
利用httpclient或okhttp发送请求
1.OpenFeign通信组件
OpenFeign基于JDK原生URLConnection提供Http通信
OpenFeign支持Apache HttpClient与Square OkHttp
SpringCloud按条件自动加载应用通信组件
2.应用条件
Maven引入feign-okhttp或者feign-httpclient依赖
设置feign.[httpclient|okhttp].enabled=true
POST方式传递对象使用@RequestBody注解描述参数
GET方式将对象转换为Map后利用@RequestParam注解描述
雪崩效应:服务雪崩效应产生与服务堆积在同一个线程池中,因为所有的请求都是同一个线程池进行处理,这时候如果在高并发情况下,所有的请求全部访问同一个接口,这时候可能会导致其他服务没有线程进行接受请求,这就是服务雪崩效应效应。
服务熔断:熔断机制目的为了保护服务,在高并发的情况下,如果请求达到一定极限(可以自己设置阔值)如果流量超出了设置阈值,让后直接拒绝访问,保护当前服务。使用服务降级方式返回一个友好提示,服务熔断和服务降级一起使用。
1.Hystrix熔断器
Hystrix(豪猪)是Netflix开源的熔断器组件,用于为微服务提供熔断机制预防雪崩,保护整体微服务架构的健康
2.Hystrix功能
预防微服务由于故障,请求长时间等待导致Web容器线程崩溃
提供故障备选方案,通过回退(fallback)机制提供”服务降级”
提供监控仪表盘,实时监控运行状态
3.Hystrix 熔断器工作原理
服务的健康状况 = 请求失败数 / 请求总数.
熔断器开关由关闭到打开的状态转换是通过当前服务健康状况和设定阈值比较决定的.
当熔断器开关关闭时, 请求被允许通过熔断器. 如果当前健康状况高于设定阈值, 开关继续保持关闭. 如果当前健康状况低于
设定阈值, 开关则切换为打开状态.
当熔断器开关打开时, 请求被禁止通过.
当熔断器开关处于打开状态, 经过一段时间后, 熔断器会自动进入半开状态, 这时熔断器只允许一个请求通过. 当该请求调用
成功时, 熔断器恢复到关闭状态. 若该请求失败, 熔断器继续保持打开状态, 接下来的请求被禁止通过.
熔断器的开关能保证服务调用者在调用异常服务时, 快速返回结果, 避免大量的同步等待. 并且熔断器能在一段时间后继续侦测请求执行结果, 提供恢复服务调用的可能.
4.什么情况下会触发服务降级
FAILURE: 执行失败,抛出异常
TIMEOUT:执行超时(默认1秒)
SHORT_CIRCUITED:熔断器状态为Open
THREAD_POOL_REJECTED:线程池拒绝
SEMAPHORE_REJECTED:信号量拒绝
5.使用Hystrix步骤
1.引入pom文件依赖
6.OpenFeign与Hystrix整合
OpenFeign中使用Hystrix
OpenFeign内置Hystrix,feign.hystrix.enable开启即可
feign: hystrix: enabled: true
在@FeignClient增加fallback属性说明Fallback类
@FeignClient(name="message-service",fallback = MessageServiceFallback.class) public interface MessageService { @GetMapping("/sendsms") public CallbackResult sendSMS(@RequestParam("mobile") String mobile , @RequestParam("message") String message); }
Fallback类要实现相同接口,重写服务降级业务逻辑
@Component public class MessageServiceFallback implements MessageService { @Override public CallbackResult sendSMS(String mobile, String message) { return new CallbackResult("INVALID_SERVICE","消息服务暂时无法使用,短信发送失败"); } }
7.Hystrix超时设置
8.部署Hystrix Dashboard监控
Hystrix Client依赖hystrix-metrics-event-stream
Hystrix Client注册HystrixMetricsStreamServlet
监控微服务依赖spring-cloud-starter-netflix-hystrix-dashboard
监控微服务利用@EnableHystrixDashboard开启仪表盘
9.Hystrix熔断设置
产生熔断的条件:
当一个Rolling Window(滑动窗口)的时间内(默认:10秒),最近20次调用请求,请求错误率超过50%,则触发熔断5秒,期间快速失败。
TIPS: 如10秒内未累计到20次,则不会触发熔断
Hystrix熔断设置项:
统一访问出入口,微服务对前台透明
安全、过滤、流控等API管理功能
易于监控、方便管理
Netflix Zuul
Spring Cloud Gateway
Zuul 是Netflix开源的一个API网关, 核心实现是Servlet
Spring Cloud内置Zuul 1.x
Zuul 1.x 核心实现是Servlet,采用同步方式通信
Zuul 2.x 基于Netty Server,提供异步通信
认证和安全
性能监测
动态路由
负载卸载
静态资源处理
压力测试
Spring Cloud Gateway,是Spring“亲儿子”
Spring Cloud Gateway旨在为微服务架构提供一种简单而有效的统一的API路由管理方式
Gateway基于Spring 5.0与Spring WebFlux开发,采用Reactor响应式设计
1.使用三部曲
依赖spring-cloud-starter-netflix-zuul
入口增加 @EnableZuulProxy
application.yml 增加微服务映射
2.微服务映射
Spring Cloud Zuul内置Hystrix
服务降级实现接口:FallbackProvider
1.微服务网关流量控制
微服务网关是应用入口,必须对入口流量进行控制
RateLimit是Spring Cloud Zuul的限流组件
RateLimit采用“令牌桶”算法实现限流
2.什么是令牌桶
1.Zuul的执行过程
2.Http请求生命周期
1.需要实现ZuulFilter接口
shouldFilter() - 是否启用该过滤器
filterOrder() - 设置过滤器执行次序
filterType() - 过滤器类型:pre|routing|post
run() - 过滤逻辑
2.Zuul内置过滤器
3.Zuul+JWT跨域身份验证
1.Spring Cloud Config
2.携程 Apollo
3.阿里巴巴Nacos
1.依赖"spring-cloud-starter-config"
2.删除application.yml,新建bootstrap.yml
3.配置"配置中心"服务地址与环境信息
1、微服务依赖"spring-boot-starter-actuator";
2、动态刷新类上增加@RefreshScope注解
3、通过/actuator/refresh刷新配置
1、通过加入重试机制、提高应用启动的可靠性;
2、重试触发条件1:配置中心无法与仓库正常通信
3、重试触发条件2:微服务无法配置中心正常通信
求java多线程遍历目录的完整代码,能运行的那种
目录结构为树型结构,用多线程不大好做,线程最多在前几层进行分割,比如每个目录下有两个目录,共5层,那么root目录下就能启用2个线程分别进行遍历,所以第二层就启动了2个线程进行遍历,加上主线程共三个线程,虽然这样做是可以做,但是要更具实际情况进行线程的规划,否则容易线程过多导致cpu超负荷,或者假死,再提一点,遍历目录不建议用递归来写,因为目录较多容易栈溢出。
随手写了个,会有点bug就是关闭线程池的时候,还有就是有可能目录太多进入拒绝策略,这个东西 可以考虑使用令牌桶算法,或者计数器算法来做。这里提供个简单的例子。
public class TraverseUtil {
public static BlockingQueue blockingQueue = new LinkedBlockingQueue(100);
public static ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(100,100,10, TimeUnit.SECONDS,blockingQueue);
public static void traverseFolder2(String path) {
File file = new File(path);
if (file.exists()) {
File[] files = file.listFiles();
if (null == files || files.length == 0) {
System.out.println("文件夹是空的!");
return;
} else {
for (File file2 : files) {
if (file2.isDirectory()) {
System.out.println("文件夹:" + file2.getAbsolutePath());
threadPoolExecutor.execute(new Runnable() {
@Override
public void run() {
traverseFolder2(file2.getAbsolutePath());
}
});
} else {
System.out.println("文件:" + file2.getAbsolutePath());
}
}
}
} else {
System.out.println("文件不存在!");
}
}
public static void main(String[] args) throws InterruptedException {
traverseFolder2("C:\\Users\\a8932\\Desktop\\md");
}
}
Redis 限流的3种方式,还有谁不会
面对越来越多的高并发场景,限流显得尤为重要。
当然,限流有许多种实现的方式,Redis具有很强大的功能,我用Redis实践了三种的实现方式,可以较为简单的实现其方式。Redis不仅仅是可以做限流,还可以做数据统计,附近的人等功能,这些可能会后续写到。
我们在使用Redis的分布式锁的时候,大家都知道是依靠了setnx的指令,在CAS(Compare and swap)的操作的时候,同时给指定的key设置了过期实践(expire),我们在限流的主要目的就是为了在单位时间内,有且仅有N数量的请求能够访问我的代码程序。所以依靠setnx可以很轻松地做到这方面的功能。
比如我们需要在10秒内限定20个请求,那么我们在setnx的时候可以设置过期时间10,当请求的setnx数量达到20时候即达到了限流效果。代码比较简单就不做展示了。
当然这种做法的弊端是很多的,比如当统计1-10秒的时候,无法统计2-11秒之内,如果需要统计N秒内的M个请求,那么我们的Redis中需要保持N个key等等问题。
其实限流涉及的最主要的就是滑动窗口,上面也提到1-10怎么变成2-11。其实也就是起始值和末端值都各+1即可。
而我们如果用Redis的list数据结构可以轻而易举的实现该功能。
我们可以将请求打造成一个zset数组,当每一次请求进来的时候,value保持唯一,可以用UUID生成,而score可以用当前时间戳表示,因为score我们可以用来计算当前时间戳之内有多少的请求数量。而zset数据结构也提供了range方法让我们可以很轻易地获取到2个时间戳内有多少请求
代码如下
通过上述代码可以做到滑动窗口的效果,并且能保证每N秒内至多M个请求,缺点就是zset的数据结构会越来越大。实现方式也是比较简单的。 最新面试题整理好了,大家可以在 Java面试库小程序在线刷题。
提到限流就不得不提到令牌桶算法了。
令牌桶算法提及到输入速率和输出速率,当输出速率大于输入速率,那么就是超出流量限制了。
也就是说我们每访问一次请求的时候,可以从Redis中获取一个令牌,如果拿到令牌了,那就说明没超出限制,而如果拿不到,则结果相反。
依靠List的leftPop来获取令牌
再依靠Java的定时任务,定时往List中rightPush令牌,当然令牌也需要唯一性,所以我这里还是用UUID进行了生成
综上,代码实现起始都不是很难,针对这些限流方式我们可以在AOP或者filter中加入以上代码,用来做到接口的限流,最终保护你的网站。
Redis其实还有很多其他的用处,他的作用不仅仅是缓存,分布式锁的作用。他的数据结构也不仅仅是只有String,Hash,List,Set,Zset。有兴趣的可以后续了解下他的GeoHash算法;BitMap,HLL以及布隆过滤器数据(Redis4.0之后加入,可以用Docker直接安装redislabs/rebloom)结构。
原文链接:
关于令牌桶java和令牌桶限流的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息,记得收藏关注本站。