一、Semaphore

限流也可使用令牌桶算法+redis

1.Semaphore定义

类似互斥锁,但它可以允许多个线程同时访问一个共享资源

通过使用一个计数器来控制对共享资源的访问,如果计数器大于0,就允许访问,如果等于0,就拒绝访问。计数器累计的是“许可证”的数目,为了访问某个资源。线程必须从信号量获取一个许可证。

通常在使用信号量时,希望访问共享资源的线程将尝试获取一个许可证,如果信号量的计数器大于0,线程将获取一个许可证并将信号量的计数器减1,否则先线程将阻塞,直到获取一个许可证;当线程不再需要共享资源时,将释放锁拥有的许可证,并将许可证的数量加1,如果有其他的线程正在等待许可证,那么该线程将立刻获取许可证。

另外,允许同时访问的资源的进程数量是在创建信号量时指定的,如果创建一个允许进程访问的信号量数目为1,则该信号量就和互斥锁的用法一样。

Semaphore常用的方法有两个WaitOne()和Release(),Release()的作用是退出信号量并返回前一个计数,而WaitOne()则是阻止当前线程,直到当前线程的WaitHandle 收到信号。这里我举一个例子让大家更容易理解:

当我们这样实例化Semaphore时候,如果写Semaphore sema = new Semaphore(x,y)这种表达式,就可以理解为这样一个场景

有一队人排队上洗手间,人就相当于线程,x为还剩余的位置数量,y为总的位置数量。

WaitOne()方法就相当于人在等待洗手间位置的行为,而Release()方法就相当于一个人从洗手间出来的行为,这里再假设x和y都为5,说明开始的时候洗手间有5个空位置,且总共只有5个位置,当一队超过5个人的队伍要上洗手间的就排队,首先WaitOne()方法等待,发现有空位就依次进去,每进去一个空位减一,直到进去5之后个没有空位,这时候后面的人就一直等待,直到进去的人从洗手间出来Release()方法,空位加一,在等待WaitOne()方法的人发现有空位又进去一个空位减一……如此循环往复。

2、代码举例

//创建一个可授权30个许可证的信号量,且初始值为20
//20为初始线程数,30为最大线程数
//重载可以添加 系统信号量 名称,这样子可以在多进程间进行访问了
private readonly static Semaphore _semaphore = new Semaphore(20, 30);
[HttpGet("GetValue")]
public async Task<string> GetValueAsync()
{ return await Task.Run(async () =>
{
try
{
//申请一个许可证
//Wait 有多个重载,加个时间 用于自动释放
_semaphore.WaitOne();
Thread.Sleep(100);
return await Task.FromResult("Value");
}
finally
{
//释放
//重载可释放多个信号量
_semaphore.Release();
}
}); }

3.原子操作Interlocked

使用 Interlocked 类,可以在不阻塞线程(lock、Monitor)的情况下,避免竞争条件。

在某个时刻,必须只有一个线程能够进行某个操作。而上面的操作,指的是读取、计算、写入这一过程。

当然,我们可以使用 lock 或者 Monitor 来解决,但是这样会带来比较大的性能损失。

这时 Interlocked 就起作用了,对于一些简单的操作运算, Interlocked 可以实现原子性的操作。

Interlocked 类是静态类,让我们先来看看 Interlocked 的常用方法:

方法 作用
CompareExchange() 比较两个数是否相等,如果相等,则替换第一个值。
Decrement() 以原子操作的形式递减指定变量的值并存储结果。
Exchange() 以原子操作的形式,设置为指定的值并返回原始值。
Increment() 以原子操作的形式递增指定变量的值并存储结果。
Add() 对两个数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成。
Read() 返回一个以原子操作形式加载的值。

全部方法请查看:https://docs.microsoft.com/zh-cn/dotnet/api/system.threading.interlocked?view=netcore-3.1#methods

class Program
{
static Semaphore semaphore;
//当前信号量中线程数量
static int count;
//用于生成随机数
static Random r; static void Main()
{
r = new Random();
//初始化信号量:初始请求数为1,最大请求数为3
semaphore = new Semaphore(1, 3);
//放出10个线程
for (int i = 0; i < 5; i++)
ThreadPool.QueueUserWorkItem(doo, i + 1);
Console.ReadKey(true);
} static void doo(object arg)
{
int id = (int)arg;
PrintStatus(id, "等待信号量");
//获取一个资源
semaphore.WaitOne();
PrintStatus(id, "获得信号量开始执行");
PrintCount(1);
Thread.Sleep(r.Next(1000));
PrintStatus(id, "退出");
PrintCount(-1);
//释放一个资源
semaphore.Release(); } //输出线程状态
static void PrintStatus(int id, string s)
{
Console.WriteLine("线程{0}:{1}", id, s);
} //修改并输出线程数量
static void PrintCount(int add)
{
//在多进程(线程)的操作系统中不能被其它进程(线程)打断的操作就叫原子操作,一个线程在执行其它线程无法抢占。
//对两个 32 位整数进行求和并用和替换第一个整数,上述操作作为一个原子操作完成。
Interlocked.Add(ref count, add);
//以原子操作的形式,将 32 位有符号整数设置为指定的值并返回原始值。
Console.WriteLine("=> 信号量值:{0}", Interlocked.Exchange(ref count, count));
}
}

二、JMeter

1.Java安装

JAVA环境变量配置:https://jingyan.baidu.com/article/fd8044fa2c22f15031137a2a.html

Java安装之前先查看下要安装的JMeter对Java SDK的版本要求,安装好后配置环境变量。安装完后cmd输入以下验证是否安装成功:

Java -version

2.JMeter安装

Jmter官方地址   https://jmeter.apache.org/

按提示下载JMeter,解压下载的二进制包,进入bin目录,使用jmeter.bat启动程序。当然前提你得先安装JAVA,或者直接运行 Bin/jmeter.bat,就可以启动JMeter

1 先配置中文

或者汉化:bin目录下找到jmeter.properties文件,找到#language=en,下面添加language=zh_CN,汉化就好了。

2 配置线程组(模拟用户)

先简单模拟50个用户,预热间1秒,Ramp-Up Period(in-seconds)代表隔多长时间执行,也就是每隔1秒生成一个线程,50个用户全部生成,一共需要50秒

3 添加取样器,线程组 --> 右键 --> 添加 --> 取样器 --> HTTP请求

JMeter不支持localhost请求,也可配置。

4 添加监听器,主要作用用于收集数据,了解接口的响应情况,先简单查看一下聚合报告吧

聚合报告内面有一个参数,吞吐量就是我们平常说的网站吞吐量,是一个重要的性能指示

5 最后一步,点中间绿色三角,“运行”,就可以进行一次负载测试了

从聚合报告的实时动态来看,这个接口的并发量高达 3W/秒

当然这只是一个简单接口,现实项目中复杂的接口,一般不会能承受这么高的并发量的,比如下订单接口,如果压测并发达3W/S,那项目架构应该达到了一线项目的水平了

参考地址https://www.cnblogs.com/stulzq/p/8971531.html

NET 5 原子操作、接口限流Semaphore以及性能测试JMeter的更多相关文章

  1. 库存秒杀问题-redis解决方案- 接口限流

    <?php/** * Created by PhpStorm. * redis 销量超卖秒杀解决方案 * redis 文档:http://doc.redisfans.com/ * ab -n 1 ...

  2. Spring Cloud Alibaba基础教程:使用Sentinel实现接口限流

    最近管点闲事浪费了不少时间,感谢网友libinwalan的留言提醒.及时纠正路线,继续跟大家一起学习Spring Cloud Alibaba. Nacos作为注册中心和配置中心的基础教程,到这里先告一 ...

  3. SpringCloud(8)---zuul权限校验、接口限流

    zuul权限校验.接口限流 一.权限校验搭建 正常项目开发时,权限校验可以考虑JWT和springSecurity结合进行权限校验,这个后期会总结,这里做个基于ZuulFilter过滤器进行一个简单的 ...

  4. 基于注解的接口限流+统一session认证

    代码心得: 一个基本的做法:对于用户身份认证做到拦截器里,针对HandlerMethod进行统一拦截认证,根据方法上的注解标识,判别是否需要身份验证,并将查找出来的User实体存入ThreadLoca ...

  5. 【Dnc.Api.Throttle】适用于.Net Core WebApi接口限流框架

    Dnc.Api.Throttle    适用于Dot Net Core的WebApi接口限流框架 使用Dnc.Api.Throttle可以使您轻松实现WebApi接口的限流管理.Dnc.Api.Thr ...

  6. Spring Cloud(7):Zuul自定义过滤器和接口限流

    上文讲到了Zuul的基本使用: https://www.cnblogs.com/xuyiqing/p/10884860.html 自定义Zuul过滤器: package org.dreamtech.a ...

  7. Guava的RateLimiter实现接口限流

    最近开发需求中有需要对后台接口进行限流处理,整理了一下基本使用方法. 首先添加guava依赖: <dependency> <groupId>com.google.guava&l ...

  8. SpringCloud之Zuul高并发情况下接口限流(十二)

    高并发下接口限流技术gauva(谷歌的框架) MySql最大连接数3000: 原理:框架每秒向桶里放100个令牌,接口请求来了先去拿令牌,拿到令牌后才能继续向后走,否则不允许向后执行:当接口请求太频繁 ...

  9. 使用google的guova开发高并发下的接口限流

    使用google的guova开发高并发下的接口限流 使用google的guova进行限流 1.guova的限流方式,在定时产生定量的令牌,令牌的数量限制了流量 2.增加一个订单接口限流类OrderRa ...

随机推荐

  1. java多线程--【Foam番茄】

    进程 是系统资源分配的单位 线程 通常在一个进程中可以包含若干个线程,当然一个进程中至少有一个线程,不然没有存在的意义.线程是cpu调度和执行的单位 注意:很多多线程是模拟出来的,真正的多线程是指有多 ...

  2. 基础篇:异步编程不会?我教你啊!CompeletableFuture

    前言 以前需要异步执行一个任务时,一般是用Thread或者线程池Executor去创建.如果需要返回值,则是调用Executor.submit获取Future.但是多个线程存在依赖组合,我们又能怎么办 ...

  3. moviepy音视频剪辑:使用VideoFileClip、AudioFileClip和write_videofile、write_audiofile进行音视频的加载和输出

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 在本地进行音视频处理时,首先要从视频文件 ...

  4. 第15.9节 PyQt学习入门:使用Qt Designer进行GUI设计的步骤

    在使用Qt Designer进行GUI设计时,一般常规的步骤都是差不多的,主要步骤包括新建显示窗口.在窗口上按照规划的布局放置组件.设置初始化组件的属性.定义信号和槽函数的连接,一般后三步是每增加一个 ...

  5. HTTP慢速拒绝服务攻击(Slow HTTP Dos)

    HTTP慢速拒绝服务攻击简介 HTTP慢速攻击是利用HTTP合法机制,以极低的速度往服务器发送HTTP请求,尽量长时间保持连接,不释放,若是达到了Web Server对于并发连接数的上限,同时恶意占用 ...

  6. 上传到github

    我是为了自己下次不用再找github上传的地方了,索性就复制了一篇 转载于 https://blog.csdn.net/m0_37725003/article/details/80904824 首先你 ...

  7. 软工团队作业--Scrum冲刺集合贴

    软工团队作业--Scrum冲刺集合贴 团队 团队名称:广东靓仔六强选手 团队成员: 黄清山 黄梓浩 钟俊豪 周立 邓富荣 郑焕 博客链接 Scrum 冲刺 第一篇 Scrum 冲刺 第二篇 Scrum ...

  8. Spring framework核心

    这一部分涵盖了Spring框架绝对不可或缺的所有技术. 1.IOC容器 1.1Spring IoC容器和beans介绍 org.springframework.beans和org.springfram ...

  9. ARM架构安装Kubernetes集群

    背景 类型 版本 操作系统 CentOS Linux release 7.6.1810 (AltArch) 内核 Linux master 4.18.0-80.7.2.el7.aarch64 硬件配置 ...

  10. 新挖个坑,准备学习一下databricks的spark博客

    挖坑 https://databricks.com/blog 一.spark3.0特性(Introducing Apache Spark 3.0) 1.通过通过自适应查询执行,动态分区修剪和其他优化使 ...