消息队列有哪些 消息队列( 四 )


简而言之就是:生产者生成消息发送给Exchange ,  Exchange根据Exchange类型和basic_publish中的routing_key进行消息发送 消费者:订阅Exchange并根据Exchange类型和binding key(bindings 中的routing key)  , 如果生产者和订阅者的routing_key相同 , Exchange就会路由到那个队列 。
topic 模式
前面讲到direct类型的Exchange路由规则是完全匹配binding key与routing key , 但这种严格的匹配方式在很多情况下不能满足实际业务需求 。
topic类型的Exchange在匹配规则上进行了扩展 , 它与direct类型的Exchage相似 , 也是将消息路由到binding key与routing key相匹配的Queue中 , 但这里的匹配规则有些不同 。
它约定:
以上图中的配置为例 , routingKey=”quick.orange.rabbit”的消息会同时路由到Q1与Q2 , routingKey=”lazy.orange.fox”的消息会路由到Q1 , routingKey=”lazy.brown.fox”的消息会路由到Q2 , routingKey=”lazy.pink.rabbit”的消息会路由到Q2(只会投递给Q2一次 , 虽然这个routingKey与Q2的两个bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、routingKey=”quick.orange.male.rabbit”的消息将会被丢弃 , 因为它们没有匹配任何bindingKey 。
RabbitMQ , 部署分三种模式:单机模式 , 普通集群模式 , 镜像集群模式 。
普通集群模式
多台机器部署 , 每个机器放一个rabbitmq实例 , 但是创建的queue只会放在一个rabbitmq实例上 , 每个实例同步queue的元数据 。
如果消费时连的是其他实例 , 那个实例会从queue所在实例拉取数据 。这就会导致拉取数据的开销 , 如果那个放queue的实例宕机了 , 那么其他实例就无法从那个实例拉取 , 即便开启了消息持久化 , 让rabbitmq落地存储消息的话 , 消息不一定会丢 , 但得等这个实例恢复了 , 然后才可以继续从这个queue拉取数据 ,  这就没什么高可用可言 , 主要是提供吞吐量  , 让集群中多个节点来服务某个queue的读写操作 。
镜像集群模式
queue的元数据和消息都会存放在多个实例 , 每次写消息就自动同步到多个queue实例里 。这样任何一个机器宕机 , 其他机器都可以顶上 , 但是性能开销太大 , 消息同步导致网络带宽压力和消耗很重 , 另外 , 没有扩展性可言 , 如果queue负载很重 , 加机器 , 新增的机器也包含了这个queue的所有数据 , 并没有办法线性扩展你的queue 。此时 , 需要开启镜像集群模式 , 在rabbitmq管理控制台新增一个策略 , 将数据同步到指定数量的节点 , 然后你再次创建queue的时候 , 应用这个策略 , 就会自动将数据同步到其他的节点上去了 。
Kafka 是 Apache 的子项目 , 是一个高性能跨语言的分布式发布/订阅消息队列系统(没有严格实现 JMS 规范的点对点模型 , 但可以实现其效果) , 在企业开发中有广泛的应用 。高性能是其最大优势 , 劣势是消息的可靠性(丢失或重复) , 这个劣势是为了换取高性能 , 开发者可以以稍降低性能 , 来换取消息的可靠性 。
一个Topic可以认为是一类消息 , 每个topic将被分成多个partition(区) , 每个partition在存储层面是append log文件 。任何发布到此partition的消息都会被直接追加到log文件的尾部 , 每条消息在文件中的位置称为offset(偏移量) , offset为一个long型数字 , 它是唯一标记一条消息 。它唯一的标记一条消息 。kafka并没有提供其他额外的索引机制来存储offset , 因为在kafka中几乎不允许对消息进行“随机读写” 。
Kafka和JMS(Java Message Service)实现(activeMQ)不同的是:即使消息被消费 , 消息仍然不会被立即删除 。日志文件将会根据broker中的配置要求 , 保留一定的时间之后删除;比如log文件保留2天 , 那么两天后 , 文件会被清除 , 无论其中的消息是否被消费 。kafka通过这种简单的手段 , 来释放磁盘空间 , 以及减少消息消费之后对文件内容改动的磁盘IO开支 。
对于consumer而言 , 它需要保存消费消息的offset , 对于offset的保存和使用 , 有consumer来控制;当consumer正常消费消息时 , offset将会"线性"的向前驱动 , 即消息将依次顺序被消费 。事实上consumer可以使用任意顺序消费消息 , 它只需要将offset重置为任意值 。(offset将会保存在zookeeper中 , 参见下文)

秒懂生活扩展阅读