当前位置: 首页 > news >正文

有一个服务器,用于提供HTTP服务,但是需要限制每个用户在任意的100秒内只能请求60次,怎么实现这个功能

问题

有一个服务器,用于提供HTTP服务,但是需要限制每个用户在任意的100秒内只能请求60次,怎么实现这个功能

我的回答

嗯,这个问题其实挺经典的,就是限流嘛。任意100秒内最多60次请求,这是个滑动窗口的问题。

我觉得可以这样实现:

方案一:用队列记录时间戳

#include <unordered_map>
#include <queue>
#include <chrono>class RateLimiter {
private:std::unordered_map<std::string, std::queue<long long>> userRequests;public:bool isAllowed(const std::string& userId) {auto now = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();auto& requests = userRequests[userId];// 先把100秒前的请求都清掉while (!requests.empty() && now - requests.front() > 100) {requests.pop();}// 看看是不是已经到60次了if (requests.size() >= 60) {return false;}// 记录这次请求requests.push(now);return true;}
};

这个方案比较直观,就是每个用户维护一个时间戳队列。但是吧,如果用户很多的话,内存消耗会比较大。

方案二:滑动窗口计数器

#include <unordered_map>
#include <chrono>struct WindowData {int prevCount = 0;int currCount = 0;long long currWindowStart = 0;
};class RateLimiter {
private:std::unordered_map<std::string, WindowData> windows;static const int WINDOW_SIZE = 100;static const int MAX_REQUESTS = 60;public:bool isAllowed(const std::string& userId) {auto now = std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()).count();auto& data = windows[userId];long long currentWindow = now / WINDOW_SIZE;// 如果进入了新的窗口if (data.currWindowStart != currentWindow) {data.prevCount = data.currCount;data.currCount = 0;data.currWindowStart = currentWindow;}// 计算滑动窗口内的估算请求数double prevWeight = (double)(WINDOW_SIZE - (now % WINDOW_SIZE)) / WINDOW_SIZE;double estimatedCount = data.prevCount * prevWeight + data.currCount;if (estimatedCount >= MAX_REQUESTS) {return false;}data.currCount++;return true;}
};

这个方案内存占用比较小,每个用户就存几个数字,但是精度会差一点点。

实际使用的话

如果在实际项目中遇到这个问题,可能还会考虑:

1. 线程安全:加个mutex或者用原子操作

#include <mutex>class ThreadSafeRateLimiter {
private:std::mutex mtx;// ... 其他成员public:bool isAllowed(const std::string& userId) {std::lock_guard<std::mutex> lock(mtx);// ... 限流逻辑}
};

2. 内存清理:定期清理过期的用户数据,不然内存会一直涨

3. 如果是分布式的:可能需要用Redis之类的外部存储

我个人比较倾向于第二种方案,因为内存效率高,而且对于大部分场景来说精度够用了。当然如果对精度要求特别高,那就用第一种。

http://www.dtcms.com/a/511317.html

相关文章:

  • 云原生周刊:Helm 十年,成就 Kubernetes 的生态中枢
  • 线段树学习
  • 单页 网站 模板wordpress腾讯云对象存储
  • 【论文阅读】Pore-scale modeling of complex transport phenomena in porous media
  • 大型酒店管理系统源码(多酒店版)
  • 常见的串口助手和遇到问题及解决方法
  • SQL性能优化的思路及策略
  • 怎么样做网站推广1688黄页网品种大全2024
  • shell脚本log打印
  • 反激电源伏秒平衡与占空比设计逻辑全解析
  • Linux网络编程(下)
  • Le Cerfav:使用MANUS手套和动作捕捉技术保存传统玻璃制作方法
  • Lua脚本详解
  • 【Block总结】ESSamp,下采样|保留原始图像信息|即插即用
  • 政务服务中心 网站建设html代码模板免费
  • Java日志收集技术
  • Gartner发布2026年十大战略技术趋势
  • 2025无人机在农业生态中的应用实践
  • 在 UOS(统信操作系统,基于 Debian/Ubuntu 体系)上编译 OpenCV 4.10.0
  • High-quality Surface Reconstruction using Gaussian Surfels 论文阅读
  • 百度地图多维检索:自然语言理解的深度搜索实践
  • 软件下载网站地址网站建设好了怎么进行推广
  • 牛客:NC16783拼数
  • UV技术:高效杀菌与精准固化的未来之光
  • PB级数据洪流下的抉择:从大数据架构师视角,深度解析时序数据库选型与性能优化(聚焦Apache IoTDB)
  • 时序数据库TDengine用法
  • 重庆市建设网站公司经济师考试时间2023报名时间
  • 第3章,[标签 Win32] :窗口类06,实例句柄与图标光标
  • 带你了解STM32:PWR电源控制
  • React Hooks完全指南