MQ处理高并发能支撑多大的量?

2021-02-20 18:37发布

4条回答
杨晓春
2楼 · 2021-02-22 14:46

高并发系统:消息队列MQ

注:前提是知道什么是消息队列。不懂的去搜索各种消息队列入门(activeMQ、rabbitMQ、rocketMQ、kafka)

 

1、为什么要使用MQ?(MQ的好处:解耦、异步、削峰)

(1)解耦:主要解决系统间的耦合度

场景是系统A会产生用户ID:userId,要把userId通过调用系统B\C\D的接口传给他们做业务处理。若添加新系统,也需要此userId,则要再加一个接口调用。耦合严重。

解耦的做法就是:在系统A与系统BCD之间,增加消息队列MQ,系统A产生userId后,将其放入MQ,系统BCD通过监听MQ,来消费userId。

以上,通过MQ,发布和订阅消息的pub/sub模型。

原耦合模型:用户请求--->A---->BCD;               现解耦模型:用户请求---->A--->MQ---->BCD;

(2)异步:主要解决请求的耗时

场景是用户发送请求到系统A,系统A执行完本地SQL(耗时100ms)后,还要调用BCD三个系统的接口,假设三次调用都耗时200ms。那么,总共一次请求耗时700ms。一旦调用接口变多,耗时会变得更长。

使用MQ解决耗时长的办法就是,在系统A与系统BCD之间分别增加MQ,系统A将数据消息写入MQ(耗时5ms),成功就返回并提示用户,剩余的BCD系统自己监听MQ并做相应业务操作。那么,这个请求耗时也就是100+5 = 105ms。

模型跟解耦一样。

(3)削峰:主要解决并发请求百万级时系统挂了

MYSQL处理能力有限,大概最高2000/秒

场景:某秒杀活动,同一时间大量用请求全怼过来了(100万请求),不用MQ的话系统就被打死了(数据库处理不过来了)

模型是:   用户同时的100万请求--->系统A----每秒5000个请求--->  mysql

使用MQ:将用户请求先放入MQ,有多少放多少,系统A每次去拿2000个,并请求MySQL资源,系统不会被打死

模型是:用户100万请求--->全写入MQ---> 系统A每次去MQ消费2000条 --->mysql

2、MQ的缺点

(1)系统可用性降低:ABCD四个系统,忽然加一个MQ进来,维护变多,万一忽然挂了,影响下游多系统

(2)系统复杂性升高:怎么保证MQ里的消息没有被重复消费?消息丢失了怎么处理?消息传递的顺序性怎么保证?

(3)一致性问题:异步里面,A处理完直接返回成功了,但是最后一个系统D写入失败了,咋整

3、activeMQ、rabbitMQ、rocketMQ、kafka的区别

 

 

4、如何设计一个MQ,架构如何设计?

汇总几个解决的MQ的线上问题来回答

(1)支持可伸缩性。即需要的时候快速扩容,增加吞吐量和容量,参考kafka的分布式系统

(2)MQ的数据要不要落磁盘?肯定要,保证数据在异常情况下不丢。落的时候顺序写入(kafka的思路)

(3)MQ的高可用性。参考kafka,多副本及leader--follower挂了重新选举的机制

(4)支持数据0丢失。参考kafka数据丢失的解决方案,消费端手动提交offset,kafka端设置参数保证副本个数、及ack要全返回才算写入成功。

你接受吗


MQ的处理和你的多少并发没什么关系,和你的数据输入吞叶量有关系。此前做过压测,SSD 300mb/s的速度,可以轻松打满。

猫的想法不敢猜
4楼 · 2021-02-28 13:00

这取决于你的服务器性能

路小雨xiaoyu
5楼 · 2021-04-21 15:55

高可用

rabbitMQ对于高可用是基于主从的方式进行实现. 其有三种工作模式: 单机模式、普通集群模式、镜像集群模式


单机模式

单机模式,就是我们平常玩的demo,生产上肯定不能用。:


普通集群模式

即在多个服务器上部署多个MQ实例, 每台机器一个实例. 创建的每一个queue,只会存在一个MQ实例上. 但是每一个实例都会同步queue的元数据(即queue的标识信息). 当在进行消费的时候, 就算 连接到了其他的MQ实例上, 其也会根据内部的queue的元数据,从该queue所在实例上拉取数据过来.

1.png


这种方式只是一个简单的集群,并没有考虑高可用. 并且性能开销巨大.容易造成单实例的性能瓶颈. 并且如果真正有数据的那个queue的实例宕机了. 那么其他的实例就无法进行数据的拉取.


这种方式只是通过集群部署的方式提高了消息的吞吐量,但是并没有考虑到高可用.


镜像集群模式

这种模式才是高可用模式. 与普通集群模式的主要区别在于. 无论queue的元数据还是queue中的消息都会同时存在与多个实例上.

2.png


要开启镜像集群模式,需要在后台新增镜像集群模式策略. 即要求数据同步到所有的节点.也可以指定同步到指定数量的节点.


这种方式的好处就在于, 任何一个服务宕机了,都不会影响整个集群数据的完整性, 因为其他服务中都有queue的完整数据, 当进行消息消费的时候,连接其他的服务器节点一样也能获取到数据.


缺点:


1: 性能开销大: 因为需要进行整个集群内部所有实例的数据同步


2:无法线性扩容: 因为每一个服务器中都包含整个集群服务节点中的所有数据。

 


高吞吐

与其他中间件产品类似,RabbitMQ也是通过集群的方式来解决单节点在处理海量消息时的性能瓶颈,通过集群的方式来实现高吞吐量,如单个RabbitMQ节点每秒只能处理1000个消息,而通过集群方式拓展,则可以进一步达到每秒10万个消息的处理或者更高的吞吐量。


不过RabbitMQ的集群在处理海量消息时,是通过在集群的多个节点建立多个不同的队列来分散消息到多个不同节点的,所以在业务层需要对消息进行细分类别来放到不同队列中。


RabbitMQ的集群不是一个主从模式的集群,而是一个对等集群,即节点之间是对等,不存在主从关系,每个节点存放的是不同的队列,所以存放的是不同的消息,由集群内所有节点的所有队列的消息共同组成该集群的所有消息。


不过如果使用了镜像队列,则集群中的某些节点作为该队列的主master节点的mirror节点或者说是slave节,存在主从关系,这个主从主要用于实现队列消息的冗余存储,实现队列和队列内部消息的高可用,不是用于读写分离实现高并发。

 


高并发

与大部分中间件的集群,如Redis,MySQL,zookeeper等,采用读写分离的方式来应对高并发数据请求不同的是,RabbitMQ集群是一个对等集群,集群内部每个节点存放不同队列(所以也就存放着不同的数据),集群内部每个节点在应对客户端的数据请求方面不存在主从关系,对于某个消息的请求,如生产者写入该消息或者消费者消费该消息,都需要首先定位到该消息所在队列的节点,然后交给该节点来处理,其他节点由于不存在这个队列,或者是镜像队列的mirror节点,故不能处理这个消息的请求。


不过从客户端的角度来看,RabbitMQ集群其实就是一个逻辑上的单节点,即客户端可以连接RabbitMQ集群的任何一个节点,而不需要约束为只能连接该客户端所要请求的消息对应的队列所在的节点。任何一个节点接收到客户端的请求后,如果该请求对应的消息属于自身节点的队列,则由该节点处理,否则将该请求转发给该消息所属队列所在的节点处理,这个过程对客户端来说是透明的。所以通过这种方式RabbitMQ集群可以通过增加节点个数来应对高并发请求,因为客户端可以连接任意一个节点。


所以出于性能考虑,RabbitMQ集群一般需要部署在一个局域网LAN内部,这样才能保证不同节点之间的请求转发的高性能。

相关问题推荐

  • 回答 156

    对于每一位才开始接触JAVA的新手来说,先不要管算法和数据结构,大多数简单的程序不需要用到算法和数据结构,所以当你真正需要时再去学习。编程一段时间以后,你就会知道在哪些地方用到他们。这时知道算法的名字并了解它们的功能,然后动手去实践。当我们在去...

  • 回答 93

    2个都很好就业,更关键的是要学得到东西

  • 回答 12
    已采纳

    获取Map集合中所有的key可以通过map集合的keySet()方法获取例如:    Map map = new HashMap();    map.put(xx,xx); //存放数据    //.... 省略    Set set = map.keySet();    //可以通过迭代器进行测试    Iterator iter = set.iter...

  • 回答 56
    已采纳

    不同年龄,不同掌握程度,学历,找工作城市,面试能力这是一个多方面影响的结果,如果是平均值的话,全国平均薪资14k左右

  • 回答 38

    具体学多久,根据自己的学习力,自律性、解决问题能力来决定若系统性学习,跟着讲师的节奏走,大概半年左右,有专业的讲师把课程进行规划,尽心系统学习,有问题,讲师会帮忙解决,学习的效率很高,避免了自学中出现各种问题解决不了,而耽误很多时间,可能会...

  • BIO与NIO、AIO的区别2020-05-19 15:59
    回答 4
    已采纳

    IO的方式通常分为几种,同步阻塞的BIO、同步非阻塞的NIO、异步非阻塞的AIO。一、BIO     在JDK1.4出来之前,我们建立网络连接的时候采用BIO模式,需要先在服务端启动一个ServerSocket,然后在客户端启动Socket来对服务端进行通信,默认情况下服务端需要...

  • 回答 23
    已采纳

    (1)idea启动时会有两个快捷方式,安装完后默认生成在桌面的是32位的idea的快捷方式,如果我们使用这个快捷方式运行大项目,一般都会很卡。解决方法是找到idea的安装目录,然后进入bin文件夹,找到名称为idea64的应用程序,右键他生成桌面快捷方式。以后每次...

  • Java方法的命名规则2021-04-06 19:07
    回答 31

    ava是一种区分字母的大小写的语言,所以我们在定义变量名的时候应该注意区分大小写的使用和一些规范,接下来我们简单的来讲讲Java语言中包、类、变量等的命名规范。(一)Package(包)的命名Package的名字应该都是由一个小写单词组成,例如com、xuetang9、compan...

  • 回答 2

    public class Point {    private int x;    private int y;    public int getX() {        return x;    }    public void setX(int x) {        this.x = x;    }    public int getY() {        return y;    } ...

  • 回答 6

    经典版单例模式public class Singleton {        private static Singleton uniqueInstance;//利用一个静态常量来记录singleton类的唯一实例。     private Singleton() {     }     public static  Singleton getInstance()...

  • 回答 3

    哈希表的长度一般是定长的,在存储数据之前我们应该知道我们存储的数据规模是多大,应该尽可能地避免频繁地让哈希表扩容。但是如果设计的太大,那么就会浪费空间,因为我们跟不用不到那么大的空间来存储我们当前的数据规模;如果设计的太小,那么就会很容易发...

  • 回答 14

    1. DOM(Document Object Model)        DOM是用与平台和语言无关的方式表示XML文档的官方W3C标准。DOM是以层次结构组织的节点或信息片断的集合。这个层次结构允许开发人员在树中寻找特定信息。分析该结构通常需要加载整个文档和构造层次结构,然后才...

  • 回答 19

    1)作用不同: throw用于程序员自行产生并抛出异常; throws用于声明在该方法内抛出了异常2) 使用的位置不同: throw位于方法体内部,可以作为单独语句使用; throws必须跟在方法参数列表的后面,不能单独使用。3)内容不同: throw抛出一个异常对象,且只能是...

  • 回答 11

    基本执行过程如下:1)程序首先执行可能发生异常的try语句块。2)如果try语句没有出现异常则执行完后跳至finally语句块执行;3)如果try语句出现异常,则中断执行并根据发生的异常类型跳至相应的catch语句块执行处理。4)catch语句块可以有多个,分别捕获不同类型...

  • 回答 20

    100-199 用于指定客户端应相应的某些动作。 200-299 用于表示请求成功。 300-399 用于已经移动的文件并且常被包含在定位头信息中指定新的地址信息。 400-499 用于指出客户端的错误。 400 语义有误,当前请求无法被服务器理解。 401 当前请求需要用户验证...

  • 回答 16

    异常表示程序运行过程中可能出现的非正常状态,运行时异常表示虚拟机的通常操作中可能遇到的异常,是一种常见运行错误,只要程序设计得没有问题通常就不会发生。受检异常跟程序运行的上下文环境有关,即使程序设计无误,仍然可能因使用的问题而引发。Java编译...

没有解决我的问题,去提问