更多关注小姐姐味道公众号。

限流可以认为是一种降级,一般是根据后台的负载提前预估的一个阈值(也可以动态调整)。超过了这个值,就要进行一些旁路处理。根据业务形态,会有直接拒绝、延迟处理、保持等待、部分穿透、默认返回等响应方式。

concurrent包中的信号量,由于使用简单,易于理解,被广泛应用。但是,你要是直接用了网友们分享的简单代码而不经过认真测试,那可以送你一部电影观赏一下:《当故障来敲门》。

看下面简单的代码,acquire和release是一对同命鸳鸯,我们把release贴心的放在了finally块中,一切显得非常和谐。

1)模拟的业务请求,耗时大约是100毫秒

2)acquire的参数5代表同一时间允许5个线程进行处理

3)每次执行完毕,输出一下本次执行的具体耗时,加上等待时间

我们启动1000个线程去执行req方法。

SemaphoreLimiterBadChecker limiter = new SemaphoreLimiterBadChecker();ExecutorService executor = Executors.newCachedThreadPool();for (int i = 0; i < 1000; i++) {executor.submit(() -> {while (true) {System.out.println(limiter.req());}});}

下面是执行结果。

可以看到,虽然我们的接口耗时只有100ms,实际的执行时间,却长的多,而且并没有出现fail的情况。运行稍长一点时间,能够发现有大量的线程处于饿死的状态。改为公平锁并不能改善这一情况。


这就是故障。

原因就在于。web端(如tomcat)的资源也是有限的。当我们的限流器产生了作用,而实际并发请求比处理能力高的时候,这种线程阻塞情况就会逐级传递。服务器的响应可能会有以下过程:

1) 压力普通,正常服务,耗时正常 。

2) 压力上升,服务开始出现大面积超时,由于使用不公平锁竞争,偶尔会有正常耗时的需求。

3) 压力继续增大,服务器开始进入假死状态,几乎不能再接受新的请求。

表现在用户端,既不能出现服务不能处理的提示,也无法中断请求,所有的请求都在转圈。继续加大tomcat的连接数和线程数,并不会起到多大的作用。


acquire改成tryAcquire?依然不能解决问题。tryAcquire返回的是bool类型,失败的时候依然能够往下执行,包括finally块。有个毛用?

if(!tryAcquire()){return TOO_MANY_REQUESTS;}

上面多加了一个判断,这个才是正途。tryAcquire还可以加超时参数,不至于立马返回失败,也不至于让调用者无限等待,而是将成功的请求控制在一个合理的响应时间。

响应时间=超时时间+业务处理时间

具体做法,拿spring来说,你可以在preHandle中获取这个许可,然后在postHandle中释放它;也可以使用定时器以一定的频率去重制信号量。

当然你也要区别对待。

1、像上面提到的web服务,可以直接拒绝服务。快速响应才是重要的

2、像一些秒杀、下单等,可以通过排队或者等待解决(部分的)

3、像消息消费等,如果没有顺序需求,我觉得,无限等待还可能是个好的方式

4、对于大多数可有可无的业务结果,使用一些默认值直接返回,效果会好的多。虽然是限流,但干的是熔断的活

使用者一定要注意区分。

End

非常让人奇怪的是,java抽象了使用场景并不是很高(相对)的CyclicBarrier,但是并没有一个通用的限流方法。信号量虽然可以模拟实现这个过程,但它不太友好,太容易出错。限流还是使用guava的组件进行控制比较好(非分布式),我们会在后面的文章来探讨它。

更多:

没有预热,不叫高并发,叫并发高

这样的高可用,我不要!

余额,危险的操作,给996留点福报

JAVA多线程使用场景和注意事项简版

macosx 不允许无名信号量_信号量限流,高并发场景不得不说的秘密相关推荐

  1. 本地缓存需要高时效性怎么办_缓存在高并发场景下的常见问题

    缓存一致性问题 当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象.这就比较依赖缓存的过期和更新策略.一般会在数据发生更改 ...

  2. 读数据库遇到空就进行不下去_如何解决高并发场景下缓存+数据库双写不一致问题?...

    推荐阅读: 一只Tom猫:手撕分布式技术:限流.通讯.缓存,全部一锅端走送给你!​zhuanlan.zhihu.com 一只Tom猫:MySQL复习:20道常见面试题(含答案)+21条MySQL性能调 ...

  3. alios thing 信号量_信号量_AliOS Things内核_API参考文档_AliOS Things 文档_IoT物联网操作系统 - 阿里云...

    对于多任务,甚至多核的操作系统,需要访问共同的系统资源.共享资源包括软件资源和硬件资源,软件共享资源主要是共享内存,包括共享变量.共享队列等等,硬件共享资源包括一些硬件设备的访问,例如:输入/输出设备 ...

  4. vp操作 信号量_信号量P,V操作

    2013-07-22 20:20:30 信号量是最早出现的用来解决进程同步与互斥问题的机制(也可实现进程通信),包括一个称为信 号量的变量及对它进行的两个原语操作.信号量为一个整数,我们设这个信号量为 ...

  5. vb6 由于超出容量限制 不能创建新事务_分布式限流?你也能轻松玩转(没啥新技术)...

    点击蓝色「日拱一兵」关注,持续侦破 Java 技术案件 一.什么是限流?为什么要限流? 不知道大家有没有做过帝都的地铁,就是进地铁站都要排队的那种,为什么要这样摆长龙转圈圈?答案就是为了限流!因为一趟 ...

  6. java网关限流_网关限流使用

    ### POM 依赖 这里一定要注意,是网关引入的redis-reactive,背压模式的redis. ``` org.springframework.boot spring-boot-starter ...

  7. 使用Redis和对象锁实现限流。(高并发场景下订购)

    1.订购调用下游的Dubbo请求,为了防止击溃下游的服务,需要在上游设置订购限流.防止下游服务崩溃. 直接上代码: private void sendFluxLimitingCtrl() {Integ ...

  8. 高并发场景下的限流策略

    点击上方"方志朋",选择"置顶公众号" 技术文章第一时间送达! 在高并发的场景下,我们的优化和保护系统的方式通常有:多级缓存.资源隔离.熔断降级.限流等等. 今 ...

  9. 电商项目的并发量一般是多少_掌握这些,高并发秒杀系统就不用担心了!

    很多小伙伴反馈说,高并发专题学了那么久,但是,在真正做项目时,仍然不知道如何下手处理高并发业务场景! 图片来自 Pexels 甚至很多小伙伴仍然停留在只是简单的提供接口(CRUD)阶段,不知道学习的并 ...

最新文章

  1. 零起点学算法07——复杂一点的表达式计算
  2. bzoj1927: [Sdoi2010]星际竞速
  3. 网络报错:“The connection is not for this device.”
  4. javascript常用的事件
  5. (4) ebj学习:ejb发布web service
  6. OPC通信原理在数采中的应用
  7. js 通过jquery插件获取url参数 其中的一个小问题,或许不算Bug。
  8. wangeditor修改图片上传和视频上传
  9. asp.net ftp上传文件到服务器,.net 文件上传到服务器上
  10. (一)问候 Log4j 你好
  11. c语言实验报告7,C语言实验报告7.doc
  12. 【渝粤题库】陕西师范大学200561 英语写作(一) 作业
  13. 拓端tecdat|R语言异方差回归模型建模:用误差方差解释异方差
  14. 维控触摸屏编程手册_维控触摸屏AB PLC地址编辑说明
  15. cisco2811(Cisco2811 DHCP)
  16. 【数据挖掘案例】财政收入影响因素分析及预测模型
  17. 用css 添加手状样式,鼠标移上去变小手
  18. Composer中的ThingWorx模型定义—可视化
  19. 全国结婚率连续5年下降,这届年轻人,为什么不敢结婚?
  20. 汉澳sinox不受openssl心血漏洞影响并分析修复其漏洞代码

热门文章

  1. ajax ssm 页面跳转_Shiro 教程,Ajax请求拦截跳转页面方案
  2. 大学 C语言程序设计第一讲,c语言程序设计1第一讲(第一章上).ppt
  3. php将数组值用 分开,PHP将数组分成基于相等值的组
  4. tp5.0计划任务删除日志方法
  5. 函数指针数组指针+结构体数组
  6. 0424-学习进度条
  7. ios进度条Demo一个
  8. Android 音频均衡器,可通过拖动调节音频EQ
  9. 全奖博士招生,伦敦大学学院盖茨比计算神经科学研究组
  10. ICCV 2019丨微软亚研院精选论文解读