并发编程-25 高并发处理手段之消息队列思路 + 应用拆分思路 + 应用限流思路

简介: 并发编程-25 高并发处理手段之消息队列思路 + 应用拆分思路 + 应用限流思路

概述


20190309221027466.png


这里只是讲通用的思路,实际高并发的场景需要根据实际情况来决定方案。

20190306004616510.png


消息队列


消息队列特性

  • 业务无关: 只做消息分发
  • FIFO : 先投递先到达
  • 容灾:节点的动态增删和消息的持久化
  • 性能: 吞吐量提升,系统内部通信效率提高

为什么需要消息队列

  • 【生产】和【消费】的速度或稳定性等因素不一致


消息队列的好处


  • 业务解耦
  • 最终一致性(要么都成功,要么都失败)
  • 广播,接入新的系统,只要需要确保把消息推送到消息队列即可,新系统从消息队列订阅即可
  • 错峰与流控

消息队列举例

Kafka


20190309232320389.png


RabbitMQ


20190309232639243.png



应用拆分

应用拆分的原则

  • 业务优先
  • 循序渐进
  • 兼顾技术:重构、分层
  • 可靠测试


应用拆分的思考

  • 应用之间的通信: RPC(Dubbo等)、消息队列
  • 应用之间的数据库设计:每个应用应该有独立的数据库
  • 避免事务操作跨应用


应用拆分常用的组件

Dubbo


20190309233106679.png


Spring Cloud


2019030923320411.png


20190309233128262.png

应用限流


20190309233516834.png


如果有大量的数据,在同一时间内直接写入数据库,势必对系统造成很大的压力。如果通过特定的方式采用限流的方式以很定的速率来写入数据库,那数据库压力就会小很多。


以下算法是说的我们在业务代码中的逻辑限流


限流算法 – 计数器法 ,简单但是有临界问题


20190309233832965.png



假设有个接口A,规定1分钟的访问次数不能超过100次。通常的做法:设置一个计数器counter,每当一个请求过来的时候,counter就加1,


如果counter>100并且该请求与第一个请求的间隔时间还在1分钟之内,那么说明请求数过多,触发限流


如果该请求与第一个请求的间隔时间大于1分钟,且counter的值还在限流范围内,那么就重置counter


优点: 计数器法是限流算法里最简单也是最容易实现的一种算法。


缺点 :临界问题


假设有一个恶意用户,在0:59时,瞬间发送了100个请求,并且1:00又瞬间发送了100个请求,那么其实这个用户在1秒里面,瞬间发送了200个请求。我们刚才规定的是1分钟最多100个请求,也就是每秒钟最多1.7个请求,用户通过在时间窗口的重置节点处突发请求,可以瞬间超过我们的速率限制。用户有可能通过算法的这个漏洞,瞬间压垮我们的应用。


刚才的问题其实是因为我们统计的精度太低。那么如何很好地处理这个问题呢?或者说,如何将临界问题的影响降低呢?我们可以看下面的滑动窗口算法


限流算法 – 滑动窗口 (Rolling Window),划分多个时间窗口解决临界问题


20190309233822719.png


在上图中,整个红色的矩形框表示一个时间窗口,一个时间窗口就是一分钟。


然后我们将时间窗口进行划分,如上图中,我们就将滑动窗口划成了6格,所以每格代表的是10秒钟。


每过10秒钟,我们的时间窗口就会往右滑动一格。


每一个格子都有自己独立的计数器counter,比如当一个请求在0:35秒的时候到达,那么0:30~0:39对应的counter就会加1。


那么滑动窗口怎么解决刚才的临界问题的呢?我们可以看上图,0:59到达的100个请求会落在灰色的格子中,而1:00到达的请求会落在橘黄色的格子中。当时间到达1:00时,我们的窗口会往右移动一格,那么此时时间窗口内的总请求数量一共是200个,超过了限定的100个,所以此时能够检测出来触发了限流。


再来看一下刚才的计数器算法,我们可以发现,计数器算法其实就是滑动窗口算法。只是它没有对时间窗口做进一步地划分,所以只有1格。


由此可见,当滑动窗口的格子划分的越多,那么滑动窗口的滚动就越平滑,限流的统计就会越精确。


限流算法 – 漏桶(Leaky Bucket)


20190309233846637.png


首先,有一个固定容量的桶,有水流进来,也有水流出去。对于流进来的水来说,我们无法预计一共有多少水会流进来,也无法预计水流的速度。但是对于流出去的水来说,这个桶可以固定水流出的速率。而且,当桶满了之后,多余的水将会溢出。


我们将算法中的水换成实际应用中的请求,我们可以看到漏桶算法天生就限制了请求的速度。当使用了漏桶算法,我们可以保证接口会以一个常速速率来处理请求。所以漏桶算法天生不会出现临界问题


限流算法 – 令牌桶(Token Bucket)



20190309234119588.png

首先,我们有一个固定容量的桶,桶里存放着令牌(token)。桶一开始是空的,token以一个固定的速率r往桶里填充,直到达到桶的容量,多余的令牌将会被丢弃。每当一个请求过来时,就会尝试从桶里移除一个令牌,如果没有令牌的话,请求无法通过。


总结

计数器 VS 滑动窗口


计数器算法是最简单的算法,可以看成是滑动窗口的低精度实现。滑动窗口由于需要存储多份的计数器(每一个格子存一份),所以滑动窗口在实现上需要更多的存储空间。也就是说,如果滑动窗口的精度越高,需要的存储空间就越大。


漏桶算法 VS 令牌桶算法


漏桶算法和令牌桶算法最明显的区别是令牌桶算法允许流量一定程度的突发。因为默认的令牌桶算法,取走token是不需要耗费时间的,也就是说,假设桶内有100个token时,那么可以瞬间允许100个请求通过。


令牌桶算法由于实现简单,且允许某些流量的突发,对用户友好,所以被业界采用地较多。当然我们需要具体情况具体分析,只有最合适的算法,没有最优的算法。

相关文章
|
2月前
|
消息中间件 安全 大数据
Kafka多线程Consumer是实现高并发数据处理的有效手段之一
【9月更文挑战第2天】Kafka多线程Consumer是实现高并发数据处理的有效手段之一
232 4
|
3月前
|
存储 缓存 安全
.NET 在金融行业的应用:高并发交易系统的构建与优化之路
【8月更文挑战第28天】在金融行业,交易系统需具备高并发处理、低延迟及高稳定性和安全性。利用.NET构建此类系统时,可采用异步编程提升并发能力,优化数据库访问以降低延迟,使用缓存减少数据库访问频率,借助分布式事务确保数据一致性,并加强安全性措施。通过综合优化,满足金融行业的严苛要求。
48 1
|
3月前
|
应用服务中间件 Linux nginx
高并发下Nginx配置限流
【8月更文挑战第16天】
73 1
|
3月前
|
数据采集 资源调度 JavaScript
Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
【8月更文挑战第4天】Node.js 适合做高并发、I/O密集型项目、轻量级实时应用、前端构建工具、命令行工具以及网络爬虫和数据处理等项目
55 5
|
4月前
|
存储 缓存 分布式计算
高并发架构设计三大利器:缓存、限流和降级问题之缓存的应对策略问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之缓存的应对策略问题如何解决
|
4月前
|
存储 缓存 NoSQL
高并发架构设计三大利器:缓存、限流和降级问题之Redis用于搭建分布式缓存集群问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之Redis用于搭建分布式缓存集群问题如何解决
|
4月前
|
开发者 Sentinel 微服务
高并发架构设计三大利器:缓存、限流和降级问题之降级策略中的有限状态机的三种状态切换的问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之降级策略中的有限状态机的三种状态切换的问题如何解决
|
4月前
|
监控 应用服务中间件 nginx
高并发架构设计三大利器:缓存、限流和降级问题之Nginx的并发连接数计数的问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之Nginx的并发连接数计数的问题如何解决
|
4月前
|
应用服务中间件 nginx 缓存
高并发架构设计三大利器:缓存、限流和降级问题之Nginx作为前置网关进行限流问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之Nginx作为前置网关进行限流问题如何解决
|
4月前
|
监控 算法 Java
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决
高并发架构设计三大利器:缓存、限流和降级问题之配置Sentinel的流量控制规则问题如何解决

热门文章

最新文章

下一篇
无影云桌面