前言:高并发对我们来说应该都不陌生,特别想淘宝秒杀,竞价等等,使用的非常多,如何在高并发的情况下,使用限流,保证业务的进行呢。以下是一个实例,不喜勿喷!

总体思路:

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

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

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

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

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

实例使用.net写的,仅供参考,了解思路和原理,需要者完全可以用其他方式语言来实现,很简单:

 public class LimitService
{
/// <summary>
/// 当前指针位置
/// </summary>
public int currentIndex = 0; //限制的时间的秒数,即:x秒允许多少请求
public int limitTimeSencond = 1; /// <summary>
/// 请求环的数组容器
/// </summary>
public DateTime?[] requstRing { get; set; } = null; /// <summary>
/// 容器改变或者移动指针时的锁;
/// </summary>
object obj = new object(); public LimitService(int countPerSecond, int _limitTimeSencond)
{
limitTimeSencond = _limitTimeSencond;
requstRing = new DateTime?[countPerSecond];
} /// <summary>
/// 程序是否可以继续
/// </summary>
/// <returns></returns>
public bool IsContinue()
{
lock (obj)
{
var currentNode = requstRing[currentIndex];
if (currentNode != null && currentNode.Value.AddSeconds(limitTimeSencond) > DateTime.Now)
{
return false;
} //当前节点设置为当前时间
requstRing[currentIndex] = DateTime.Now;
//指针移动一个位置
MoveNextIndex(ref currentIndex);
} return true;
} /// <summary>
/// 改变每秒可以通过的请求数
/// </summary>
/// <param name="countPerSecond"></param>
/// <returns></returns>
public bool ChangeCountPerSecond(int countPerSecond)
{
lock (obj)
{
requstRing = new DateTime?[countPerSecond]; currentIndex = 0;
} return true;
} /// <summary>
/// 指针往前移动一个位置
/// </summary>
/// <param name="currentIndex"></param>
public void MoveNextIndex (ref int currentIndex)
{
if(currentIndex!= requstRing.Length - 1)
{
currentIndex = currentIndex + 1;
}
else
{
currentIndex = 0;
}
}

  

测试程序如下:

  public class Program
{
static LimitService l = new LimitService(, );
public static void Main(string[] args)
{ int threadCount = ; while (threadCount >= )
{
Thread t = new Thread(s => {
Limit(); }); t.Start(); threadCount--;
} Console.ReadKey();
} public static void Limit()
{
int i = ;
int okCount = ;
int noCount = ;
Stopwatch w = new Stopwatch();
w.Start();
while (i < )
{
var ret = l.IsContinue();
if (ret)
{
okCount++;
}
else
{
noCount++;
}
i++;
}
w.Stop();
Console.WriteLine($"共用{w.ElapsedMilliseconds},允许:{okCount}, 拦截:{noCount}");
}
}

测试结果:

最大用时7秒,共处理请求1000000*50=50000000 次

并未发生GC操作,内存使用率非常低,每秒处理 300万次+请求 。以上程序修改为10个线程,大约用时4秒之内

如果是强劲的服务器或者线程数较少情况下处理速度将会更快!!!

以上就是测试的限制高并发的一种简单方案,当然还有其他方式比如:令牌桶算法,漏桶算法等等,可以去研究下!

以上仅为个人观点,如果错误,请大家指针,谢谢!

.NET-高并发及限流方案的更多相关文章

  1. coding++:高并发解决方案限流技术---漏桶算法限流--demo

    1.漏桶算法 漏桶作为计量工具(The Leaky Bucket Algorithm as a Meter)时,可以用于流量整形(Traffic Shaping)和流量控制(TrafficPolici ...

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

    1.它是限流算法中最简单最容易的一种算法 计数器实现限流 每分钟只允许10个请求 第一个请求进去的时间为startTime,在startTime + 60s内只允许10个请求 当60s内超过十个请求后 ...

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

    RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率. 通常可应用于抢购限流防止冲垮系统:限制某接口.服务单位时 ...

  4. 高并发解决方案限流技术-----使用RateLimiter实现令牌桶限流

    1,RateLimiter是guava提供的基于令牌桶算法的实现类,可以非常简单的完成限流特技,并且根据系统的实际情况来调整生成token的速率.通常可应用于抢购限流防止冲垮系统:限制某接口.服务单位 ...

  5. Guava-RateLimiter实现令牌桶控制接口限流方案

    一.前言 对于一个应用系统来说,我们有时会遇到极限并发的情况,即有一个TPS/QPS阀值,如果超了阀值可能会导致服务器崩溃宕机,因此我们最好进行过载保护,防止大量请求涌入击垮系统.对服务接口进行限流可 ...

  6. Java高并发的常见应对方案

    Java高并发的常见应对方案 一.关于并发我们说的高并发是什么? 在互联网时代,高并发,通常是指,在某个时间点,有很多个访问同时到来. 高并发,通常关心的系统指标与业务指标? QPS:每秒钟查询量,广 ...

  7. WCF学习笔记之并发与限流

    最近一直在学习WCF相关知识:本文章将针对并发与限流知识进行一个梳理,由于很多理论的知识所以做一个简单的记录,为今后回顾做一个记录: 一:并发知识 WCF将服务实例封装在一个称为实例上下文的对象中,并 ...

  8. 高并发WEB网站优化方案

    一.什么是高并发在互联网时代,所讲的并发.高并发,通常是指并发访问,也就是在某个时间点,有多少个访问同时到来.比如,百度首页同时有1000个人访问,那么也就是并发为1000.通常一个系统的日PV在千万 ...

  9. Linux海量数据高并发实时同步架构方案杂谈

    不论是Redhat还是CentOS系统,除去从CDN缓存或者数据库优化.动静分离等方面来说,在架构层面上,实 现海量数据高并发实时同步访问概括起来大概可以从以下几个方面去入手,当然NFS的存储也可以是 ...

随机推荐

  1. Could not find modernizr-2.6.2 in any of the sources GitLab: API is not accessible

    Could not find modernizr-2.6.2 in any of the sources GitLab: API is not accessible bundle exec rake ...

  2. Python基础Web服务器案例

    一.WSGI 1.PythonWeb服务器网关接口(Python Web Server Gateway Interface,缩写为WSGI) 是Python应用程序或框架和Web服务器之间的一种接口, ...

  3. 记录利用CSS完美解决前端图片变形问题

    在头条IT学堂看到CSS完美解决前端图片变形问题的文章,就记录分享下: 一.让图片的宽度或者高度等于容器的宽度或高度,多余的裁掉,然后让图片居中: <style type="text/ ...

  4. 第2章 微信小程序的基础组件学习

    小程序也可以用div+css进行排版. flex-direction排列方向,可以控制内部的成员的顺序,比如从左到右.从右到左.上下,纵向和横向. flex-wrap可以控制换行是如何去换行的,控制它 ...

  5. 一个简陋的个人小项目,也是个人第一个真正意义上的独立项目——Graph

    由来 我最早接触到图这个概念是在大二的离散数学当中图论相关的内容,当时是以著名的哥尼斯堡七桥问题引出图论的概念,现在依然记忆犹新(不过只是记得这个名字,具体的解题思路我重新温习了一下才想起来),当时也 ...

  6. DateFormat 多线程问题

    在写实时应用解析日志的时候,有如下代码: public class CalPvLogParse { private static SimpleDateFormat logTimeFormat = ne ...

  7. RabbitMQ指南之五:主题交换器(Topic Exchange)

    在上一章中,我们完善了我们的日志系统,用direct交换器替换了fanout交换器,使得我们可以有选择性地接收消息.尽管如此,仍然还有限制:不能基于多个标准进行路由.在我们的日志系统中,我们可能不仅希 ...

  8. Modbus通讯错误检测方法

    标准的Modbus串行网络采用两种错误检测方法.奇偶校验对每个字符都可用,帧检测(LRC和CRC)应用于整个消息.它们都是在消息发送前由主设备产生的,从设备在接收过程中检测每个字符和整个消息帧. 用户 ...

  9. MVC之参数验证(三)

    在实际开发中,项目经理会一直强调一句话,永远不要相信客户端的数据(前端可以不用验证,但是后端必须验证).大家同意这样的说法吧..新端验证毋庸质疑JS验证,提高用户体验我们不得不添加一些与后端一致的验证 ...

  10. Firebug

    Firebug是网页浏览器火狐下的一款开发类插件,它集HTML查看和编辑.JavaScript控制台.网络状态监视器于一体,是开发JavaScript.CSS.HTML和Ajax的得力助手.F12打开 ...