zoukankan      html  css  js  c++  java
  • rabbitmq2-这可能是最全的rabbitmq概览了

    在学习一个技术的时候,首先想到的应该是应用场景,然后在对比技术和技术选型的时候应该结合自己的业务,再结合每一个技术的特点进行技术的选择,这篇博文就详细的描述一下rabbitmq的特性

    一、rabbitmq的总体模型图

    image.png

    1、一些名词解释:
    • 生产者(P):提供消息的一方的称谓
    • 消费者(C):接受消息的一方的称谓
    • 队列(Q):存储消息的一种数据结构
    • exchange (交换机|路由器):提供P到Q之间的匹配
    • routing key:当前的消息将会被路由到那个Q中
    • binding key:联系Exchange和Q,Binding Key由Consumer在Binding Exchange与Message Queue时指定,而Routing Key由Producer发送Message时指定,两者的匹配方式由Exchange Type决定。
    • Connection:tcp连接
    • Channel:复用tcp连接的通道(埋下一个知识点,我们一会会继续
      聊)
    • ExchangeType
      • direct :默认的模式,当routing key和binding key完全匹配的时候,才可以获取消息
      • topic:与上面的模式相同,但是routing key可以和binding key进行模糊匹配
      • header:忽略ExchangeType,header本来就是键值对结构,依据header属性进行匹配
      • fanout:和上面一样忽略ExchangeType的设置,把消息广播到它所知道的所有的队列
    2、聊聊设计思想:
    • Connection:
      看到这个东西你是不是想到了数据库Connection,其实它们的本质都是tcp连接,你是否还想到了数据库连接池(c3p0、druid……),其实用在这里都是一样的效果,有兴趣你可以看看spring在整合rabbitmq的时候是如何来写的只需要debug进去即可
    • Channel:对于一个连接来说想要保持资源的隔离和快速的通过exchange匹配到queue,这个机制是非常棒的,这么优秀的设计思想,的确是值得我们去学习的,其实把这个点想通,然后套在多线程里面也是通用的。

    二、rabbitmq如何确保消息的可靠性

    这个点是我在群里面经常被问到的问题,很多博客也差不多是复制文档上面的下来,今天希望我能把这个问题给讲解清楚。话还是回到前面当初是怎么想到学习这个技术的呢??

    1、生产者端的可靠性的保障
    1.1 事务机制

    image.png
    是不是基本和jdbc的一致。事务的机制保障的是消息能够投递出去,

    1.2 confirm机制的保障:

    相比于事务机制,confirm的性能要提高200倍,confirm和事务机制是互斥的,即不能同时使用
    rabbitmq提供下列几个方法来实现:
    开启channel.confirmSelect()
    ①同步普通模式(阻塞)waitForConfirms(),发送一条等待服务端confirm后在发送第二条,这实际上一种串行的模式效率不高
    ②同步批量模式:每发送一批消息之后,调用waitForConfirms()方法,等待服务端confirm,但假如一旦出现confirm返回false的话,那么客户端要将这批消息重发会带来重复消息
    ③异步监听模式:confirmListener

    2、消费者的保障

    消费者端的消息重试机制:
    ①:当消费者端挂掉了即当前的channel断开了连接,那么消息会自动重回队列,重新分发给下一个消费者
    ②:当前消费者拒收这个消息,那么rabbitmq提供参数可以使得此消息重回队列,那么此条消息便可以继续分发给下一个消费者处理,确保这个消息一定会有消费者去处理
    以上的两个机制便确保了消息只要发出一定会被消费,下面我们在说如何利用这一机制来实现分布式事务。

    问题: 当消费者消费完消息,发送应答的时候挂掉了会出现什么情况?

    这种情况会造成消息的重复消费,A已经消费了消息,但是应答发送的时候网络中断,这个时候channel已经断开了,就需要重如队列,下一个消费者B就会继续消费这个消息,就会造成消息的重复消息,所以在消费者端一定要有一个状态表保存消息的状态,防止被重复消费。

    3、服务器端的保障:

    ①:提供持久化模式,开启这种模式即使服务器宕机,也能在重启的情况下保证消息的不丢失
    ②:提供集群的方式

    三、rabbitmq的几种工作模式和应用场景:

    1、简单模式:
    image.png
    一个生产者一个消费者一个队列非常简单的结构,基本上这个结构没有什么用
    2、work模式:
    image.png
    一个生产一个队列,多个消费者,每个消费者获取的消息唯一,ExchangeType的模式为默认的direct
    3、订阅模式:
    image.png
    Exchange将会把消息投递到所有它已知的Q,然后连接Q 的所有的C都能获取到消息。此时ExchangeType的模式为fanout
    4、路由模式:
    image.png
    由routing key决定把消息往哪个队列里面投递,有binding 匹配routing key的结果来决定C是否可以获取此Q中的消息,这种模式下ExchangeType必须为direct
    5、统配符模式:
    image.png
    在这种模式下可以模糊匹配

    2、应用场景:

    1、简单模式:这种模式几乎没有什么应用场景
    2、work模式:这种应用的也比较少
    3、发布订阅模式:这种模式适用于通知,例如通知所有的商户周五晚上服务器更新
    4、路由模式:在集群的环境下,我们会将一个系统的所有消息都交由这个集群来处理,所以所有的消息必须要归类,那么这个模式就在这种情况下可以高效的处理消息
    5、统配符模式:基本和上面的类似,可以接受一类的消息

    四、消息的公平分发:

    场景:现在有两个消费者,A的吞吐量为10,B的吞吐量为5。
    在默认的模式下面,消息队列不管消费者是否处理完毕,都会继续下发下一条消息,造成的结果就是A 获取10条消息,B也获取10条消息,显然这样会拖慢整体的处理速度,本着能者多劳的原则。我们会尽量的让A、B都能有一个合理的负荷来提高系统的整理的处理速度

    channel.basicQos(int prefetchCount);

    这个语句就会使得一次性下发prefetchCount个消息,等待处理完成后在下发同样的数量的消息,这样会提升系统的整体的吞吐量。

    五、再聊分布式事务

    在分布式的场景中,已经无法在做到ACID了,这个时候我们追求最终的一致性,那么现在实现最终一致性的方法还没有成熟的方案,据说阿里搞了一个GTS但是目前还没有开源。本篇在这个大环境下肯定是将使用rabbitmq来实现分布式事务的最终一致性 。
    - 消息的可靠性,rabbitmq借助于生产者端的确认机制、消费者的重试机制、服务器端的持久化机制及集群机制,可以确保消息不丢失,只要消息发送出去就一定会被消费,如果出现大量的消息堆积,那这个时候就可以考虑在架设缓存或者增加节点了
    - 消息延迟是目前mq中最低的以微妙来计
    - 借助于消费者端的事务状态表来保证消息的重复消费

    目前就聊到这里,实践出真知,下面的系列文章将会进入实战环节。

  • 相关阅读:
    [转]linux下的fms2流媒体服务器搭建六部曲之四格式转换篇
    Linux 信号signal处理函数
    FMS在linux下安装时的问题处理
    Linux 下让你的C程序在后台运行
    Linux 信号signal处理机制
    Flash Media Server 2 无限制许可文件
    JavaScript动态控制网页元素事件
    自定义MessageBox的窗口颜色,字体等属性
    [转]linux下的fms2流媒体服务器搭建六部曲之一ffmpeg安装篇
    [转]linux下的fms2流媒体服务器搭建六部曲之三FlashMediaServer安装篇
  • 原文地址:https://www.cnblogs.com/fkxuexi/p/9574975.html
Copyright © 2011-2022 走看看