高并发的限流例子

原文:高并发的限流例子

总体思路是这样:

1.  用一个环形来代表通过的请求容器。

2.  用一个指针指向当前请求所到的位置索引,来判断当前请求时间和当前位置上次请求的时间差,依此来判断是否被限制。

3.  如果请求通过,则当前指针向前移动一个位置,不通过则不移动位置

4.  重复以上步骤 直到永远.......

以下代码的核心思路是这样的:指针当前位置的时间元素和当前时间的差来决定是否允许此次请求,这样通过的请求在时间上表现的比较平滑。

//限流组件,采用数组做为一个环
    class LimitService
    {
        //当前指针的位置
        int currentIndex = 0;
        //限制的时间的秒数,即:x秒允许多少请求
        int limitTimeSencond = 1;
        //请求环的容器数组
        DateTime?[] requestRing = null;
        //容器改变或者移动指针时候的锁
        object objLock = new object();

public LimitService(int countPerSecond,int  _limitTimeSencond)
        {
            requestRing = new DateTime?[countPerSecond];
            limitTimeSencond= _limitTimeSencond;
        }

//程序是否可以继续
        public bool IsContinue()
        {
            lock (objLock)
            {
                var currentNode = requestRing[currentIndex];
                //如果当前节点的值加上设置的秒 超过当前时间,说明超过限制
                if (currentNode != null&& currentNode.Value.AddSeconds(limitTimeSencond) >DateTime.Now)
                {
                    return false;
                }
                //当前节点设置为当前时间
                requestRing[currentIndex] = DateTime.Now;
                //指针移动一个位置
                MoveNextIndex(ref currentIndex);
            }            
            return true;
        }
        //改变每秒可以通过的请求数
        public bool ChangeCountPerSecond(int countPerSecond)
        {
            lock (objLock)
            {
                requestRing = new DateTime?[countPerSecond];
                currentIndex = 0;
            }
            return true;
        }

//指针往前移动一个位置
        private void MoveNextIndex(ref int currentIndex)
        {
            if (currentIndex != requestRing.Length - 1)
            {
                currentIndex = currentIndex + 1;
            }
            else
            {
                currentIndex = 0;
            }
        }
    }

测试程序如下:

static  LimitService l = new LimitService(1000, 1);
        static void Main(string[] args)
        {
            int threadCount = 50;
            while (threadCount >= 0)
            {
                Thread t = new Thread(s =>
                {
                    Limit();
                });
                t.Start();
                threadCount--;
            }

Console.Read();
        }

static void Limit()
        {
            int i = 0;
            int okCount = 0;
            int noCount = 0;
            Stopwatch w = new Stopwatch();
            w.Start();
            while (i < 1000000)
            {
                var ret = l.IsContinue();
                if (ret)
                {
                    okCount++;
                }
                else
                {
                    noCount++;
                }
                i++;
            }
            w.Stop();
            Console.WriteLine($"共用{w.ElapsedMilliseconds},允许:{okCount},  拦截:{noCount}");
        }

转载于:https://mp.weixin.qq.com/s/xIEN_IvR8h-Yc7oZoojTpw

原文地址:https://www.cnblogs.com/lonelyxmas/p/10474498.html

时间: 2024-08-30 15:08:49

高并发的限流例子的相关文章

高并发解决方案限流技术-----计数器

1.它是限流算法中最简单最容易的一种算法 计数器实现限流 每分钟只允许10个请求 第一个请求进去的时间为startTime,在startTime + 60s内只允许10个请求 当60s内超过十个请求后,拒绝,不超过,到第60s 重新设置时间 package com.aiyuesheng.utils; import java.util.concurrent.atomic.AtomicInteger; import lombok.Getter; import lombok.Setter; /** *

coding++:高并发解决方案限流技术-使用RateLimiter实现令牌桶限流-Demo

RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率. 通常可应用于抢购限流防止冲垮系统:限制某接口.服务单位时间内的访问量,譬如一些第三方服务会对用户访问量进行限制:限制网速,单位时间内只允许上传下载多少字节等. guava的maven依赖 <dependency> <groupId>com.google.guava</groupId> <artifactId>guav

coding++:高并发解决方案限流技术--计数器

1.它是限流算法中最简单最容易的一种算法 计数器实现限流 每分钟只允许10个请求 第一个请求进去的时间为startTime,在startTime + 60s内只允许10个请求 当60s内超过十个请求后,拒绝,不超过,到第60s 重新设置时间 package com.aiyuesheng.utils; import java.util.concurrent.atomic.AtomicInteger; import lombok.Getter; import lombok.Setter; /** *

并发、限流、缓存

1.并发 使用CompletableFuture可以控制并发,并且等待所有异步处理完成后返回allOff: 2.限流 使用guava中的RateLimiter可以控制秒级限流. 3.缓存 使用guava中的CacheBuilder和LoadingCache.其中设置超时可用expireAfterAccess.

高并发之限流实现(三)

本次样例从单机层面上,采用拦截器的方式对请求限流. 资源:https://github.com/xiaozhuanfeng/rateLimiterProj 工程结构: pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/

高并发限流算法

开篇 在高并发系统中,有很多手段来保护系统,如缓存.降级和限流等. 缓存:让数据尽早进入缓存,离程序近一点,不要大量频繁的访问DB,可提供系统访问速度和增大系统处理能力. 降级:当服务出问题或者影响到核心流程的性能,需要将服务暂时屏蔽掉,待高峰期过去或问题解决后再启用. 然后,有些场景不能用缓存和降级来解决.比如电商的双十一,用户的购买,下单等行为,是涉及到大量写操作,而且是核心链路,无法降级的. 限流:通过把并发访问/请求进行限速或者一定时间窗口内的请求限制在一定范围内来保护系统,一旦达到限制

Sentinel如何通过限流实现服务的高可用性

摘要: 在复杂的生产环境下可能部署着成千上万的服务实例,当流量持续不断地涌入,服务之间相互调用频率陡增时,会产生系统负载过高.网络延迟等一系列问题,从而导致某些服务不可用.如果不进行相应的流量控制,可能会导致级联故障,并影响到服务的可用性,因此如何对高流量进行合理控制,成为保障服务稳定性的关键. 在复杂的生产环境下可能部署着成千上万的服务实例,当流量持续不断地涌入,服务之间相互调用频率陡增时,会产生系统负载过高.网络延迟等一系列问题,从而导致某些服务不可用.如果不进行相应的流量控制,可能会导致级

限流从概念到实现

并发数限流并发数限流限制的是同一时刻的并发数,所以不考虑线程安全的话,我们只要用一个int变量就能实现,伪代码如下: int maxRequest=100;int nowRequest=0; public void request(){if(nowRequest>=maxRequest){return ;}nowRequest++;//调用接口try{invokeXXX(); }finally{nowRequest--;}}显然,上述实现会有线程安全的问题,最直接的做法是加锁: int maxR

Spring Cloud Alibaba 之 Sentinel 限流规则和控制台实例

这一节我们通过一个简单的实例,学习Sentinel的基本应用. 一.Sentinel 限流核心概念 在学习Sentinel的具体应用之前,我们先来了解一下Sentinel中两个核心的概念,资源和规则. 资源 资源 是 Sentinel 中的核心概念之一.既然是限流,或者系统保护,那么是针对什么做限流?保护的是什么?就是我们所说的资源. 其实 Sentinel 对资源的定义,和并发编程中 Synchronized的使用很类似,这里的资源,可以是服务里的方法,也可以是一段代码. 规则 定义了资源之后