phpstudy如何搭建网站,随州市网站建设公司,tomcat做网站属于什么,40个超好玩的网页小游戏高并发场景下#xff0c;如何确保系统稳定运行#xff0c;成为了每一个开发工程师必须面对的挑战。**你是否曾因系统崩溃、请求超时或资源耗尽而头疼不已#xff1f;**高并发限流算法或许能帮你解决这些难题。
在处理高并发请求时#xff0c;应该如何选择合适的限流算法呢…高并发场景下如何确保系统稳定运行成为了每一个开发工程师必须面对的挑战。**你是否曾因系统崩溃、请求超时或资源耗尽而头疼不已**高并发限流算法或许能帮你解决这些难题。
在处理高并发请求时应该如何选择合适的限流算法呢 以下我们将深入分析五种常见的高并发限流算法帮助你做出更合适的技术选型。
在现代高并发系统中随着用户访问量的激增和业务需求的不断扩展限流作为一种至关重要的保护机制被广泛应用于防止系统过载确保系统的稳定性和可用性。 本文将深入剖析几种常见的限流算法探讨它们的原理、优缺点并给出代码实例帮助读者更好地理解和应用这些算法从而在实际项目中构建更加高效、稳定的系统。
随着互联网应用的快速发展和用户流量的增加高并发场景下的限流变得越来越重要。尤其在电商、直播、支付等行业高并发请求的控制直接决定了用户体验和系统的稳定性。选择合适的限流算法能有效减少服务器的负载和资源的过度占用从而保证系统的稳定运行。 01 固定窗口算法Fixed Window Algorithm 固定窗口算法将时间划分为固定大小的窗口如1min在每个窗口内允许一定数量的请求。每当请求到达时系统会检查当前窗口内的请求数量如果未超过限制则允许请求否则拒绝请求。
class FixedWindowRateLimiter {
public:FixedWindowRateLimiter(int max_requests_per_win, std::chrono::seconds window_size): max_requests_per_win_(max_requests_per_win), window_size_(window_size), request_count_(0) {window_start_time_ std::chrono::steady_clock::now();}bool TryAcquire(int request_size) {std::lock_guardstd::mutex lock(mtx_);auto now std::chrono::steady_clock::now();// 如果当前时间在窗口内if (now - window_start_time_ window_size_) {// 检查请求数量是否超过限制if (request_count_ request_size max_requests_per_win_) {request_count_ request_size; // 增加请求计数return true; // 允许请求} else {return false; // 超过最大请求数}} else {// 重置窗口window_start_time_ now;request_count_ request_size; // 重置请求计数为当前请求数量return true; // 允许请求}}private:int max_requests_per_win_; // 最大请求数std::chrono::seconds window_size_; // 窗口大小int request_count_; // 当前请求计数std::chrono::steady_clock::time_point window_start_time_; // 窗口开始时间std::mutex mtx_; // 互斥锁
}; 算法简介通过设定固定的时间窗口在窗口内计算请求的数量如果超出限制则拒绝请求。每当时间窗口到期计数器重置。适用场景适用于请求速率较稳定、对时间窗口的要求不高的场景。案例某银行的API接口每秒钟限制5次请求超过5次即拒绝。当一个时间窗口如1秒结束时计数器会重置。 优点 实现简单非常容易理解。 适用于请求速率相对稳定的场景。 缺点 在短时间流量突发时将会有大量失败无法平滑流量。 有窗口边际效应在窗口切换时可能会出现短时间内请求激增的情况导致系统过载。 02 滑动窗口算法Sliding Window Algorithm 滑动窗口算法是对固定窗口算法的改进它将时间窗口划分为多个小桶并为每个小桶维护一个独立的请求计数器。当请求到达时算法会根据请求的时间戳将其放入相应的小桶中并检查整个滑动窗口内的请求总数是否超过限制。随着时间的推移滑动窗口会不断向右滑动丢弃最旧的小桶并添加新的小桶。
class SlidingWindowRateLimiter {
public:SlidingWindowRateLimiter(int max_requests_per_win, std::chrono::seconds bucket_size, int num_buckets): max_requests_per_win_(max_requests_per_win), bucket_size_(bucket_size), num_buckets_(num_buckets) {request_counts_.resize(num_buckets, 0);last_bucket_time_ std::chrono::steady_clock::now();}bool TryAcquire(int request_size) {std::lock_guardstd::mutex lock(mtx_);auto now std::chrono::steady_clock::now();UpdateBuckets_(now);int total_requests 0;for (int count : request_counts_) {total_requests count;}if (total_requests request_size max_requests_per_win_) {request_counts_[current_bucket_index_] request_size; // 增加当前桶的请求计数return true; // 允许请求} else {return false; // 超过最大请求数}}private:void UpdateBuckets_(std::chrono::steady_clock::time_point now) {auto elapsed std::chrono::duration_caststd::chrono::seconds(now - last_bucket_time_);int buckets_to_update static_castint(elapsed / bucket_size_);if (buckets_to_update 0) {for (int i 0; i std::min(num_buckets_, buckets_to_update); i) {auto next_bucket_index (current_bucket_index_ 1) % num_buckets_;request_counts_[next_bucket_index] 0; // 移除最旧的桶current_bucket_index_ next_bucket_index; // 移动到下一个桶}last_bucket_time_ buckets_to_update * bucket_size_; // 更新最后桶的时间}}int max_requests_per_win_; // 最大请求数std::chrono::seconds bucket_size_; // 每个小桶的大小int num_buckets_; // 小桶的数量std::vectorint request_counts_; // 每个小桶的请求计数std::mutex mtx_; // 互斥锁std::chrono::steady_clock::time_point last_bucket_time_; // 上一个桶的时间int current_bucket_index_ 0; // 当前桶的索引
}; 算法简介滑动窗口计数器算法是对固定窗口计数器算法的改进。它将时间窗口滑动分段每个小段都进行计数精确度更高。相比固定窗口它更加平滑不会出现突如其来的拒绝。适用场景适用于对请求的实时性和稳定性要求较高的场景。案例某社交平台在API访问上使用了滑动窗口算法可以避免短时间内请求量突然增大时的系统压力使请求处理更加平稳。 优点 相比固定窗口算法可以更细粒度地控制流量。 减缓了固定窗口算法中的窗口边际效应。 缺点 在短时间流量突发时将会有大量失败无法平滑流量。 03 滑动日志算法Sliding Log Algorithm 滑动日志算法通过记录每个请求的时间戳来控制请求速率。当一个请求到达时系统会检查最近一段时间内的请求记录计算请求速率是否超过限制。如果超过则拒绝请求否则处理请求并记录当前请求的时间戳。
class SlidingLogRateLimiter {
public:SlidingLogRateLimiter(int max_requests_per_win, std::chrono::seconds window_size): max_requests_per_win_(max_requests_per_win), window_size_(window_size) {}bool TryAcquire(int request_size) {std::lock_guardstd::mutex lock(mtx_);auto now std::chrono::steady_clock::now();CleanUp_(now);int total_requests 0;for (const auto timestamp : request_log_) {total_requests timestamp.second;}if (total_requests request_size max_requests_per_win_) {request_log_.emplace_back(now, request_size); // 记录当前请求return true; // 允许请求} else {return false; // 超过最大请求数}}private:void CleanUp_(std::chrono::steady_clock::time_point now) {auto expiration_time now - window_size_;while (!request_log_.empty() request_log_.front().first expiration_time) {request_log_.pop_front(); // 移除过期的请求记录}}int max_requests_per_win_; // 最大请求数std::chrono::seconds window_size_; // 窗口大小std::dequestd::pairstd::chrono::steady_clock::time_point, int request_log_; // 请求日志std::mutex mtx_; // 互斥锁
}; 优点 可以非常精确地控制请求速率。 缺点 在短时间流量突发时将会有大量失败无法平滑流量。 由于每一次成功请求都要被记录所以会有较大额外的内存开销。 04 漏桶算法Leaky Bucket Algorithm 漏桶算法将请求看作水滴将请求处理过程看作水从漏桶底部中流出。系统以恒定速率处理请求即漏桶的漏水速率当一个请求到达时如果漏桶未满则请求被放入漏桶中等待处理如果漏桶已满则请求被拒绝。
class Task {
public:virtual int GetLoad() 0;virtual void Run() 0;
}class LeakyBucketRateLimiter {
public:LeakyBucketRateLimiter(int capacity, int leak_rate): capacity_(capacity), leak_rate_(leak_rate), current_water_(0) {last_leak_time_ std::chrono::steady_clock::now();}bool TryRun(const TaskPtr task) {std::lock_guardstd::mutex lock(mtx_);Leak();if (current_water_ task.GetLoad() capacity_) {current_water_ task.GetLoad(); // 将请求放入漏桶heap_timer_.Schedule(task, current_water_ / leak_rate); // 定时器在该任务的水漏完后将会执行task的Run方法return true; // 允许请求} else {return false; // 漏桶已满请求被拒绝}}private:void Leak() {auto now std::chrono::steady_clock::now();auto elapsed std::chrono::duration_caststd::chrono::seconds(now - last_leak_time_);int leaked_water static_castint(elapsed.count()) * leak_rate_;if (leaked_water 0) {current_water_ std::max(0, current_water_ - leaked_water); // 减少水量last_leak_time_ now; // 更新最后漏水时间}}int capacity_; // 漏桶的容量int leak_rate_; // 漏水速率每秒漏掉的水量int current_water_; // 当前水量HeapTimer heap_timer_; // 一个任务执行的定时器std::mutex mtx_; // 互斥锁std::chrono::steady_clock::time_point last_leak_time_; // 上次漏水的时间
};
算法简介漏桶算法和令牌桶算法类似但它更加严格。漏桶算法通过固定的出水速率来处理请求桶满后会丢弃新请求。适合用来处理请求的平滑速率控制。适用场景适用于有稳定速率处理的场景比如实时数据处理确保处理流量的一致性。案例一个短视频平台可以使用漏桶算法来平稳处理视频上传流量确保不会因为突发的高并发导致服务器崩溃。 优点 能提供非常平稳的流量。 削峰填谷有一定的应对流量突发能力桶的大小。 缺点 控制比较刻板弹性能力较弱。 在并发时候会产生额外的延迟等待开销比如限制流量为1qps两个请求同时到达必然有其中一个请求需要等1s后才能服务。 05 令牌桶算法Token Bucket Algorithm 令牌桶算法使用一个桶来存储令牌以固定速率向桶中添加令牌。每当请求到达时会先检查桶中是否有令牌如果有则允许请求并消耗相应令牌如果没有则拒绝请求。
class TokenBucketRateLimiter {
public:TokenBucketRateLimiter(int capacity, int refill_rate): capacity_(capacity), refill_rate_(refill_rate), current_tokens_(0) {last_refill_time_ std::chrono::steady_clock::now();}bool TryAcquire(int request_size) {std::lock_guardstd::mutex lock(mtx_);Refill_();if (current_tokens_ request_size) {current_tokens_ - request_size; // 消耗令牌return true; // 允许请求} else {return false; // 令牌不足请求被拒绝}}private:void Refill_() {auto now std::chrono::steady_clock::now();auto elapsed std::chrono::duration_caststd::chrono::seconds(now - last_refill_time_);current_tokens_ std::min(capacity_, current_tokens_ static_castint(elapsed.count()) * refill_rate_); // 更新令牌数量last_refill_time_ now; // 更新最后补充时间}int capacity_; // 令牌桶的容量int refill_rate_; // 令牌补充速率每秒补充的令牌数量int current_tokens_; // 当前令牌数量std::mutex mtx_; // 互斥锁std::chrono::steady_clock::time_point last_refill_time_; // 上次补充令牌的时间
};
算法简介令牌桶算法是一种典型的限流算法通过控制令牌的生成速率和桶的容量来限制请求数量。当令牌不足时请求会被延迟或拒绝。适用场景适合流量突发性较强的场景。能够平滑处理高峰流量避免瞬时请求量过高导致系统崩溃。案例例如一家电商平台的促销活动中用户请求流量很难控制使用令牌桶算法能够保证每秒有一定数量的请求被允许进入系统避免流量瞬间激增时导致系统崩溃。 优点 能够处理突发流量避免系统瞬间过载。 灵活性高可以通过调整令牌生成速率和桶容量来控制流量。 缺点 实现相对复杂。 总结 想要在高并发系统中使用这些算法来优化系统性能使用一些优秀的云平台服务可以帮助你实现灵活的限流与调度如阿里云的云数据库和API Gateway为你的系统提供强有力的支撑
每种限流算法都有其适用的场景和优缺点。在选择限流算法时需要根据具体的业务需求和系统特性进行权衡。通过合理选择和组合这些算法可以有效地保护系统免受过载的影响
在面对高并发压力时选择合适的限流算法至关重要。不同的业务场景需要根据流量特点选择最佳的限流策略以确保系统高效、稳定地运行。希望本文的分析能帮助你在面对复杂的流量控制时做出明智的选择。 “高并发的世界里限流算法不仅是保障系统稳定的利器更是确保用户体验不被破坏的守护者。” 文章转载自: http://www.morning.fpkpz.cn.gov.cn.fpkpz.cn http://www.morning.wqgr.cn.gov.cn.wqgr.cn http://www.morning.qwrb.cn.gov.cn.qwrb.cn http://www.morning.jllnh.cn.gov.cn.jllnh.cn http://www.morning.ywpwq.cn.gov.cn.ywpwq.cn http://www.morning.lcxdm.cn.gov.cn.lcxdm.cn http://www.morning.xzgbj.cn.gov.cn.xzgbj.cn http://www.morning.fydsr.cn.gov.cn.fydsr.cn http://www.morning.njntp.cn.gov.cn.njntp.cn http://www.morning.zzqgc.cn.gov.cn.zzqgc.cn http://www.morning.dcmnl.cn.gov.cn.dcmnl.cn http://www.morning.cknrs.cn.gov.cn.cknrs.cn http://www.morning.ztqyj.cn.gov.cn.ztqyj.cn http://www.morning.bxqpl.cn.gov.cn.bxqpl.cn http://www.morning.hous-e.com.gov.cn.hous-e.com http://www.morning.hmgqy.cn.gov.cn.hmgqy.cn http://www.morning.clqpj.cn.gov.cn.clqpj.cn http://www.morning.tzpqc.cn.gov.cn.tzpqc.cn http://www.morning.zkqwk.cn.gov.cn.zkqwk.cn http://www.morning.qhnmj.cn.gov.cn.qhnmj.cn http://www.morning.gthwr.cn.gov.cn.gthwr.cn http://www.morning.fygbq.cn.gov.cn.fygbq.cn http://www.morning.pcwzb.cn.gov.cn.pcwzb.cn http://www.morning.bxyzr.cn.gov.cn.bxyzr.cn http://www.morning.zqkr.cn.gov.cn.zqkr.cn http://www.morning.npmx.cn.gov.cn.npmx.cn http://www.morning.stprd.cn.gov.cn.stprd.cn http://www.morning.qqbw.cn.gov.cn.qqbw.cn http://www.morning.sqqdy.cn.gov.cn.sqqdy.cn http://www.morning.fwrr.cn.gov.cn.fwrr.cn http://www.morning.jytrb.cn.gov.cn.jytrb.cn http://www.morning.blzrj.cn.gov.cn.blzrj.cn http://www.morning.xdttq.cn.gov.cn.xdttq.cn http://www.morning.gnghp.cn.gov.cn.gnghp.cn http://www.morning.rbrhj.cn.gov.cn.rbrhj.cn http://www.morning.nlqmp.cn.gov.cn.nlqmp.cn http://www.morning.dmcxh.cn.gov.cn.dmcxh.cn http://www.morning.qrsm.cn.gov.cn.qrsm.cn http://www.morning.fsqbx.cn.gov.cn.fsqbx.cn http://www.morning.fpngg.cn.gov.cn.fpngg.cn http://www.morning.cpwmj.cn.gov.cn.cpwmj.cn http://www.morning.hybmz.cn.gov.cn.hybmz.cn http://www.morning.ejknty.cn.gov.cn.ejknty.cn http://www.morning.nqyzg.cn.gov.cn.nqyzg.cn http://www.morning.rxtxf.cn.gov.cn.rxtxf.cn http://www.morning.mrtdq.cn.gov.cn.mrtdq.cn http://www.morning.rhsr.cn.gov.cn.rhsr.cn http://www.morning.cgntj.cn.gov.cn.cgntj.cn http://www.morning.xjpnq.cn.gov.cn.xjpnq.cn http://www.morning.krdxz.cn.gov.cn.krdxz.cn http://www.morning.ghccq.cn.gov.cn.ghccq.cn http://www.morning.rbgwj.cn.gov.cn.rbgwj.cn http://www.morning.bqrd.cn.gov.cn.bqrd.cn http://www.morning.rkck.cn.gov.cn.rkck.cn http://www.morning.brwnd.cn.gov.cn.brwnd.cn http://www.morning.mkfr.cn.gov.cn.mkfr.cn http://www.morning.hxljc.cn.gov.cn.hxljc.cn http://www.morning.krgjc.cn.gov.cn.krgjc.cn http://www.morning.jwcmq.cn.gov.cn.jwcmq.cn http://www.morning.tbknh.cn.gov.cn.tbknh.cn http://www.morning.lmhwm.cn.gov.cn.lmhwm.cn http://www.morning.wknj.cn.gov.cn.wknj.cn http://www.morning.rwzmz.cn.gov.cn.rwzmz.cn http://www.morning.rxyz.cn.gov.cn.rxyz.cn http://www.morning.qxnns.cn.gov.cn.qxnns.cn http://www.morning.qmfhh.cn.gov.cn.qmfhh.cn http://www.morning.wslr.cn.gov.cn.wslr.cn http://www.morning.rxlck.cn.gov.cn.rxlck.cn http://www.morning.mjbjq.cn.gov.cn.mjbjq.cn http://www.morning.mbdbe.cn.gov.cn.mbdbe.cn http://www.morning.zlgth.cn.gov.cn.zlgth.cn http://www.morning.jnvivi.com.gov.cn.jnvivi.com http://www.morning.fgkrh.cn.gov.cn.fgkrh.cn http://www.morning.tslfz.cn.gov.cn.tslfz.cn http://www.morning.qnbzs.cn.gov.cn.qnbzs.cn http://www.morning.cnhgc.cn.gov.cn.cnhgc.cn http://www.morning.jhxtm.cn.gov.cn.jhxtm.cn http://www.morning.24vy.com.gov.cn.24vy.com http://www.morning.qrgfw.cn.gov.cn.qrgfw.cn http://www.morning.ffgbq.cn.gov.cn.ffgbq.cn