redis实现限流
令牌桶逻辑

计算逻辑:

代码:
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;/*** @ClassName RedisRateLimiterTokenBucket* @Description TODO* @Author zhang zhengdong* @DATE 2025/1/17 20:22* @Version 1.0*/
public class RedisRateLimiterTokenBucket {private JedisPool jedisPool;private String rateLimitKey;private int timeWindow; // 限制的时间窗口,单位为秒private int maxTokens; // 每个时间窗口的最大令牌数private int refillRate; // 每秒钟生成的令牌数public RedisRateLimiterTokenBucket(JedisPool jedisPool, String rateLimitKey, int timeWindow, int maxTokens, int refillRate) {this.jedisPool = jedisPool;this.rateLimitKey = rateLimitKey;this.timeWindow = timeWindow;this.maxTokens = maxTokens;this.refillRate = refillRate;}/*** 尝试获取令牌*/public boolean acquire() {try (Jedis jedis = jedisPool.getResource()) {long currentTime = System.currentTimeMillis() / 1000;String key = rateLimitKey + ":tokens";String lastRefillKey = rateLimitKey + ":lastRefillTime";// 获取最后一次令牌补充的时间String lastRefillTime = jedis.get(lastRefillKey);if (lastRefillTime == null) {jedis.set(lastRefillKey, String.valueOf(currentTime));jedis.set(key, String.valueOf(maxTokens));lastRefillTime = String.valueOf(currentTime);}// 计算补充令牌的数量long elapsed = currentTime - Long.parseLong(lastRefillTime);int tokensToAdd = (int) (elapsed * refillRate);// 计算当前令牌数int tokens = Integer.parseInt(jedis.get(key));tokens = Math.min(tokens + tokensToAdd, maxTokens);// 如果令牌数大于 0,则消费一个令牌if (tokens > 0) {jedis.set(key, String.valueOf(tokens - 1));jedis.set(lastRefillKey, String.valueOf(currentTime));return true;}return false; // 没有令牌,拒绝请求}}
}
验证代码
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;/*** @ClassName RedisRateLimiterTokenBucketTest* @Description TODO* @Author zhang zhengdong* @DATE 2025/1/17 20:25* @Version 1.0*/
public class RedisRateLimiterTokenBucketTest {public static void main(String[] args) {// 初始化 Jedis 连接池JedisPoolConfig poolConfig = new JedisPoolConfig();poolConfig.setMaxTotal(10);JedisPool jedisPool = new JedisPool(poolConfig, "localhost", 6379);// 限流设置:10 秒内最多 20 次请求int timeWindow = 10;int maxRequestsPerWindow = 10;// 使用 令牌桶 算法实现限流RedisRateLimiterTokenBucket rateLimiterTokenBucket = new RedisRateLimiterTokenBucket(jedisPool,"rate_limit_token_bucket", timeWindow, maxRequestsPerWindow, 1);for (int i = 0; i < 25; i++) {boolean allowed = rateLimiterTokenBucket.acquire();if (allowed) {System.out.println("请求 " + (i + 1) + " 被允许");} else {System.out.println("请求 " + (i + 1) + " 被拒绝");}// try {
// Thread.sleep(400); // 模拟请求间隔
// } catch (InterruptedException e) {
// e.printStackTrace();
// }}}
}
zset实现限流逻辑

import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;import java.util.UUID;/*** @ClassName RedisRateLimiterZSet* @Description TODO* @Author zhang zhengdong* @DATE 2025/1/17 19:50* @Version 1.0*/
public class RedisRateLimiterZSet {private JedisPool jedisPool;private String rateLimitKey;private int timeWindow; // 限制的时间窗口,单位为秒private int maxRequestsPerWindow; // 每个窗口允许的最大请求次数public RedisRateLimiterZSet(JedisPool jedisPool, String rateLimitKey, int timeWindow, int maxRequestsPerWindow) {this.jedisPool = jedisPool;this.rateLimitKey = rateLimitKey;this.timeWindow = timeWindow;this.maxRequestsPerWindow = maxRequestsPerWindow;}public boolean acquire() {try (Jedis jedis = jedisPool.getResource()) {Long currentTime = System.currentTimeMillis();System.out.println(currentTime);if (jedis.zcard(rateLimitKey) > 0) {Integer count = jedis.zrangeByScore(rateLimitKey, currentTime - 10 * 1000, currentTime).size(); // 注意这里使用zrangeByScore,以时间作为score。zrange key start stop 命令的start和stop是序号。System.out.println(count);if (count != null && count > maxRequestsPerWindow) {return false;}}jedis.zadd(rateLimitKey, Double.valueOf(currentTime), UUID.randomUUID().toString());return true;}}}
测试
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;/*** @ClassName RateLimiterZSetTest* @Description TODO* @Author zhang zhengdong* @DATE 2025/1/17 20:00* @Version 1.0*/
public class RedisRateLimiterZSetTest {public static void main(String[] args) {JedisPoolConfig jedisConfig = new JedisPoolConfig();jedisConfig.setMaxTotal(10);JedisPool jedisPool = new JedisPool(jedisConfig, "localhost", 6379);// 限流设置:10 秒内最多 20 次请求RedisRateLimiterZSet rateLimiter = new RedisRateLimiterZSet(jedisPool, "rate_limit_zset", 10, 20);// 测试:连续请求for (int i = 0; i < 25; i++) {boolean allowed = rateLimiter.acquire();if (allowed) {System.out.println("请求 " + (i + 1) + " 被允许");} else {System.out.println("请求 " + (i + 1) + " 被拒绝");}// 延迟 400ms 后再次尝试
// try {
// Thread.sleep(400); // 模拟请求间隔
// } catch (InterruptedException e) {
// e.printStackTrace();
// }}}
相关文章:
redis实现限流
令牌桶逻辑 计算逻辑: 代码: import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool;/*** ClassName RedisRateLimiterTokenBucket* Description TODO* Author zhang zhengdong* DATE 2025/1/17 20:22* Version 1.0*/ public class…...
基于SpringBoot和PostGIS的各国及所属机场信息检索及可视化实现
目录 前言 一、空间数据简介 1、全球国家信息表 2、机场信息表 3、国家机场检索实现 二、SpringBoot后台实现 1、模型层实现 2、控制层实现 三、WebGIS可视化实现 1、Leaflet界面实现 2、国家及其机场可视化成果 3、全球机场数量排行榜 四、总结 前言 新春佳节即将…...
python http server运行Angular 单页面路由时重定向,解决404问题
问题 当Angular在本地ng server运行时候,可以顺利访问各级路由。 但是运行ng build后,在dist 路径下的打包好的额index.html 必须要在服务器下运行才能加载。 在服务器下我们第一次访问路由页面时是没有问题的,但是尝试刷新页面或手动输入路…...
GPT-4o背后的语音技术
GPT-4o背后的语音技术 GPT-4o是一个any2any的多模态模型,能够接受文本、音频、图像、视频等多模态输入,也能够生成包含文本、语音、图像和视频等混合内容的多模态输出。本文主要谈语音多模态的实现,并分享一些对于语音研究未来发展的看法。 GPT-4o (“o” 代表 “omni”) …...
微透镜阵列精准全检,白光干涉3D自动量测方案提效70%
广泛应用的微透镜阵列 微透镜是一种常见的微光学元件,通过设计微透镜,可对入射光进行扩散、光束整形、光线均分、光学聚焦、集成成像等调制,进而实现许多传统光学元器件难以实现的特殊功能。 微透镜阵列(Microlens Array&#x…...
Spring boot框架下的RocketMQ消息中间件
1. RocketMQ 基础概念 1.1 核心概念 以下是 RocketMQ 核心概念在 Spring Boot 的 Java 后端代码中的实际使用方式: Producer(生产者) 定义:Producer 是负责发送消息到 RocketMQ 的组件。它可以将消息发送到指定的 Topic。 实…...
记录一次 centos 启动失败
文章目录 现场1分析1现场2分析2搜索实际解决过程 现场1 一次断电,导致 之前能正常启动的centos 7.7 起不来了有部分log , 关键信息如下 [1.332724] XFS(sda3): Internal error xfs ... at line xxx of fs/xfs/xfs_trans.c [1.332724] XFS(sda3): Corruption of in-memory data…...
C++学习第五天
创作过程中难免有不足,若您发现本文内容有误,恳请不吝赐教。 提示:以下是本篇文章正文内容,下面案例可供参考 一、构造函数 问题1 关于编译器生成的默认成员函数,很多童鞋会有疑惑:不实现构造函数的情况下…...
openharmony标准系统方案之瑞芯微RK3568移植案例
标准系统方案之瑞芯微RK3568移植案例 本文章是基于瑞芯微RK3568芯片的DAYU200开发板,进行标准系统相关功能的移植,主要包括产品配置添加,内核启动、升级,音频ADM化,Camera,TP,LCD,…...
深入理解 SSH 端口转发:本地 vs 远程 vs 动态转发
🌟 简介 SSH 端口转发(SSH Port Forwarding)作为一种强大而灵活的技术,不仅可以帮助我们安全地访问远程服务,还能轻松突破网络限制。本文将带你深入了解 SSH 端口转发的原理、类型和实战应用。 🌈 目录 &a…...
postman请求参数化
postman界面介绍 一、使用环境变量(Environment Variables)进行参数化 1、在请求中使用环境变量 在请求的url、请求头(Headers)、请求体(Body)等部分都可以使用环境变量。 URL 部分示例 点击 Postman 界面右上角的 “眼睛” 图标(Environment Quick Look)打开环境管理…...
基于 WEB 开发的汽车养护系统设计与实现
标题:基于 WEB 开发的汽车养护系统设计与实现 内容:1.摘要 本文介绍了基于 WEB 开发的汽车养护系统的设计与实现。文章首先阐述了系统的背景和目的,即随着汽车保有量的增加,汽车养护需求日益增长,传统的汽车养护方式已经无法满足人们的需求&…...
Nginx正向代理配置
Nginx 正向代理默认只支持 http 协议,不支持 https 协议,需借助 "ngx_http_proxy_connect_module" 模块实现 https 正向代理,详情请参考: https://github.com/chobits/ngx_http_proxy_connect_module 安装Nginx某些模块…...
本地仓库管理之当前分支内的操作
以刚搭建好的git仓库为例,刚搭建完的仓库只有master分支,使用git branch查看当前的分支情况。 elfubuntu:~/work/example/hello$ git branch *所在分支为当前分支,即master分支 当前分支进行源码修改时简单流程图如下: 在当前分…...
《内网穿透:网络拓展与安全防护的平衡艺术》
一、引言:开启内网穿透的大门 在当今数字化浪潮席卷全球的时代,网络已成为人们生活和工作中不可或缺的一部分。我们日常使用的网络,如同一个庞大而复杂的生态系统,其中内网和外网犹如两个相互关联却又有所区别的世界。 想象一下…...
【python写个可以运行的2048小游戏】
写一个完整的2048小游戏在Python中是一个相对复杂的任务,因为它涉及到用户界面、事件处理、游戏逻辑等多个方面。为了简化这个过程,我们可以使用Python的图形库,比如pygame。下面是一个简单的2048游戏的实现。 首先,确保你已经安…...
【Flink系列】9. Flink容错机制
9. 容错机制 在Flink中,有一套完整的容错机制来保证故障后的恢复,其中最重要的就是检查点。 9.1 检查点(Checkpoint) 9.1.1 检查点的保存 1)周期性的触发保存 “随时存档”确实恢复起来方便,可是需要我…...
DETR论文阅读
1. 动机 传统的目标检测任务需要大量的人工先验知识,例如预定义的先验anchor,NMS后处理策略等。这些人工先验知识引入了很多人为因素,且较难处理。如果能够端到端到直接生成目标检测结果,将会使问题变得很优雅。 2. 主要贡献 提…...
关于vite+vue3+ts项目中env.d.ts 文件详解
env.d.ts 文件是 Vite 项目中用于定义全局类型声明的 TypeScript 文件。它帮助开发者向 TypeScript提供全局的类型提示,特别是在使用一些特定于 Vite 的功能时(如 import.meta.env)。以下是详细讲解及代码示例 文章目录 **1. env.d.ts 文件的…...
如何优化Elasticsearch大文档查询?
记录一次业务复杂场景下DSL优化的过程 背景 B端商城业务有一个场景就是客户可见的产品列表是需要N多闸口及各种其它逻辑组合过滤的,各种闸口数据及产品数据都是存储在ES的(有的是独立索引,有的是作为产品属性存储在产品文档上)。 在实际使用的过程中&a…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...
Mobile ALOHA全身模仿学习
一、题目 Mobile ALOHA:通过低成本全身远程操作学习双手移动操作 传统模仿学习(Imitation Learning)缺点:聚焦与桌面操作,缺乏通用任务所需的移动性和灵活性 本论文优点:(1)在ALOHA…...
rnn判断string中第一次出现a的下标
# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...
深度学习习题2
1.如果增加神经网络的宽度,精确度会增加到一个特定阈值后,便开始降低。造成这一现象的可能原因是什么? A、即使增加卷积核的数量,只有少部分的核会被用作预测 B、当卷积核数量增加时,神经网络的预测能力会降低 C、当卷…...
PAN/FPN
import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...
tomcat入门
1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效,稳定,易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...
