• Home
  • About
    • wanziの遇笺 photo

      wanziの遇笺

      一点随笔,一丝感悟,一些记录,一种成长。

    • Learn More
    • Instagram
    • Github
  • Archive
  • Category
  • Tag

基于RabbitMQ topic的消息发送与接收

14 Jan 2017

Reading time ~1 minute

一、前言

1.项目结构:

  A是消息的生产者,B、C则是消息的consumer。A会通过queue(不关心其产品类型)发送消息给B、C。

2.需求

  近期项目上,新增的D应用程序需要监听原有A应用程序的消息。按照以往的做法,我需要做如下两件事:

  • 向某个团队,给每该D应用的每个region(dev、intg、sys、prod等),申请新的queue A.D。(这中间可能需要两个星期时间)
  • 改变应用A的代码,让其每次发消息时候还需要再给D发消息。
  • 给应用A准备一次deploymen plan,并做相应的回归测试。
  • 改变应用D的代码,让其从新建的queue里面接收处理消息。

3.痛点

  这一做法,主要有两大痛点:

  • 每增加一个新应用,都需要申请queue
  • 每增加一个新应用,都需要改动应用A的代码,还需要单独安排一次上线。生产者和消费者之间的耦合非常大。

4.解决方案

  因此,在兼容以前的基础上,我试图用下面的结构图解决上述痛点: 保持原有应用程序B和C的接收消息方式不变,新的应用程序开始改用topic的方法,这样可以兼容既有的应用程序,也可以将新应用程序的生产者和消费者解耦。但是还是存在一些问题:

  • A的消息那么多,全部放在一个topic可能负载过大,那么应该采取分布式的方法?
  • 如果消费者之一中途down了一段时间,该消息的等待时间又如何处理?是一直停留在topic中进行等待吗?

  最后,考虑到上述因素以及实际项目的其他因素,我将结构变成了如下:

  虽然把最开始的痛点1又引入了,但是解耦的好处还是非常有意义的。

  本文旨在spike上述想法,证明该想法的可能性。

二、搭建外部环境

  笔者采用vagrant + VirtualBox搭建一个含有rabbitmq server的虚拟机: 总体说来,所有的命令如下:

1.创建虚拟机

$ mkdir rabbit
$ cd rabbit
$ vagrant box list
$ vagrant init yungsang/coreos

然后注意取消注释config.vm.network "private_network", ip: "192.168.33.10"

2.登陆到虚拟机

vagrant ssh

3.外部访问rabbitmq的管理页面

  • URL:http://192.168.33.10:15672/#/
  • 用户名:guest
  • 密码:guest

三、Spike

  在编写本文时候,笔者顺便了解了一下Rabbit MQ的相关基础模式与用法,可以参见上一篇文章RabbitMQ初探

  再回过头来看这个spike,发现其实本文要实现的就是RabbitMQ初探中的Topic Exchange模式。

  其实说起来,就是JMS和AMQP的一个较大的区别:

  • JMS有队列(Queues)和主题(Topics)两种形式,发送到JMS队列的消息最多只能被一个Client消费,发送到JMS主题的消息可能会被多个Clients消费;
  • AMQP只有队列(Queues),队列的消息只能被单个接受者消费,发送者并不直接把消息发送到队列中,而是发送到Exchange中,该Exchage会与一个或多个队列绑定,能够实现与JMS队列和主题同样的功能。

四、结语

  本文只是针对其中的一点,进行了可行性的spike,但是实际应用中往往还涉及到很多复杂因素,比如技术上消息的事务处理和消息负载,另外还有项目进度、人员安排以及后续维护等问题。笔者不再过多阐述,谨以此文的小demo探究一些不一样的架构。



rabbitmq Share Tweet +1