美文网首页java面试
RabbitMq五种模式

RabbitMq五种模式

作者: Helloword_Cc | 来源:发表于2023-05-28 14:55 被阅读0次

    1)Simple-简单模型

    RabbitMQ是一个消息代理:它接受和转发消息。 你可以把它想象成一个邮政信箱
    RabbitMQ与邮局的主要区别是它不处理纸张,而是接受,存储和转发数据消息的二进制数据块。

    image.png

    P(producer/ publisher):生产者,一个发送消息的用户应用程序。
    C(consumer):消费者,消费和接收有类似的意思,消费者是一个主要用来等待接收消息的用户应用程序
    队列(红色区域):rabbitmq内部类似于邮箱的一个概念。虽然消息流经rabbitmq和你的应用程序,但是它们只能存储在队列中。队列只受主机的内存和磁盘限制,实质上是一个大的消息缓冲区。许多生产者可以发送消息到一个队列,许多消费者可以尝试从一个队列接收数据。

    2)消息确认机制(ACK)非模型

    RabbitMQ有一个ACK机制。当消费者获取消息后,会向RabbitMQ发送回执ACK,告知消息已经被接收。

    不过这种回执ACK分两种情况:
    (1)自动ACK:消息一旦被接收,消费者自动发送ACK
    (2)手动ACK:消息接收后,不会发送ACK,需要手动调用

    需要用到哪种,根据消息的重要性来看:
    如果消息不太重要,丢失也没关系的话就用自动ACK
    如果消息非常重要,不容丢失,使用手动ACK

    注重消息丢失,使用自动ACK
    注重业务逻辑失败回滚消息,使用手动ACK

    如果第二个参数为true,则会自动进行ACK;如果为false,则需要手动ACK。

    channel.basicConsume(QUEUE_NAME, false, consumer);
    
    自动ACK存在的问题 ---- 出现异常后消息人会被消费

    修改消费者,添加异常,如下:


    image.png

    生产者不做任何修改,直接运行,消息发送成功:


    image.png

    运行消费者,程序抛出异常。但是消息依然被消费:


    image.png
    演示手动ACK

    修改消费者,把自动改成手动(去掉之前制造的异常)


    image.png

    运行消费者


    image.png

    停掉消费者的程序,发现:


    image.png

    这是因为虽然我们设置了手动ACK,但是代码中并没有进行消息确认!所以消息并未被真正消费掉。

    当我们关掉这个消费者,消息的状态再次称为Ready

    修改代码手动ACK:


    image.png

    Work-工作模型

    image.png

    创建一个工作队列,在多个工作者之间分配耗时任务---平均分发

    工作队列,又称任务队列。主要思想就是避免执行资源密集型任务时,必须等待它执行完成。相反我们稍后完成任务,我们将任务封装为消息并将其发送到队列。 在后台运行的工作进程将获取任务并最终执行作业。当你运行许多消费者时,任务将在他们之间共享,但是一个消息只能被一个消费者获取。

    接下来我们来模拟这个流程:

    P:生产者:任务的发布者

    C1:消费者,领取任务并且完成任务,假设完成速度较快

    C2:消费者2:领取任务并完成任务,假设完成速度慢

    避免消息堆积?

    采用workqueue,多个消费者监听同一队列。
    接收到消息以后,而是通过线程池,异步消费。

    Fanout-广播模型

    image.png

    在广播模式下,消息发送流程是这样的:

    可以有多个消费者
    每个消费者有自己的queue(队列)
    每个队列都要绑定到Exchange(交换机)
    生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定。
    交换机把消息发送给绑定过的所有队列
    队列的消费者都能拿到消息。实现一条消息被多个消费者消费

    Direct-定向模型

    选择性的接收消息
    队列上的全部消息绑定在一个交换机上,通过路由key,路由分配到对应的消费者上
    使用场景:电商系统有“南区”,“北区”,“华南区”仓库,下单的时候将发货请求发到发货队列上,通过路由key,分发到对应仓库进行消费发货。

    1.在订阅模式中,生产者发布消息,所有消费者都可以获取所有消息。
    在路由模式中,我们将添加一个功能 - 我们将只能订阅一部分消息。 例如,我们只能将重要的错误消息引导到日志文件(以节省磁盘空间),同时仍然能够在控制台上打印所有日志消息。
    2.但是,在某些场景下,我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。
    在Direct模型下,队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key)
    消息的发送方在向Exchange发送消息时,也必须指定消息的routing key

    image.png

    P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。

    X:Exchange(交换机),接收生产者的消息,然后把消息递交给 与routing key完全匹配的队列

    C1:消费者,其所在队列指定了需要routing key 为 error 的消息

    C2:消费者,其所在队列指定了需要routing key 为 info、error、warning 的消息

    Topic-主题模型

    Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。
    只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符!

    Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert

    通配符规则:

    #:匹配一个或多个词
    *:匹配不多不少恰好1个词
    audit.#:能够匹配audit.irs.corporate 或者 audit.irs
    audit.*:只能匹配audit.irs

    image.png

    在这个例子中,我们将发送所有描述动物的消息。消息将使用由三个字(两个点)组成的routing key发送。路由关键字中的第一个单词将描述速度,第二个颜色和第三个种类:“<speed>.<color>.<species>”。

    我们创建了三个绑定:Q1绑定了绑定键“.orange.”,Q2绑定了“..rabbit”和“lazy.#”。

    Q1匹配所有的橙色动物。

    Q2匹配关于兔子以及懒惰动物的消息。

    相关文章

      网友评论

        本文标题:RabbitMq五种模式

        本文链接:https://www.haomeiwen.com/subject/jafdedtx.html