RabbitMQ入门

Neutron各组件之间的通信主要是通过RabbitMQ实现的,所以为了更好的学习Neutron,首先需要先熟悉RabbitMQ的常规用法。学习过Java或者写过Web应用的开发人员相信对MQ耳熟能详。在Web应用的世界中,MQ的使用实在太普遍了。常见的MQ系统有ActiveMQ,Kafka,Qpid,redis,ZeroMQ,RabbitMQ等等。在这些MQ实现中,有些严格遵守了AMQP标准,有些则自成一派。

接下来让我们认识一下RabbitMQ的特点。

  • 除了Qpid之外,RabbitMQ是唯一实现了AMQP标准的代理服务器。

  • RabbitMQ基于Erlang实现,所以RabbitMQ集群非常简单。

  • RabbitMQ相对更可靠,更能防止崩溃。

让我们使用RabbitMQ实现发送“hello world”消息,并使用服务端打印消息:

  • 安装RabbitMQ

    以centos 7系统为例,在线安装RabbitMQ

    yum install rabbitmq-server
  • 启动RabbitMQ

    systemctl start rabbitmq-server
  • 编写"hello world"生产者,并保存为producer.py

    import pika,sys
    credentials = pika.PlainCredentials('guest','guest')
    conn_params = pika.ConnectionParameters('192.168.90.26',credentials= credentials)
    conn_broker = pika.BlockingConnection(conn_params)
    channel = conn_broker.channel()
    channel.exchange_declare(exchange='hello-exchange',type='direct',passive=False,durable=True,auto_delete=False)
    msg = sys.argv[1]
    msg_props = pika.BasicProperties()
    msg_props.content_type = 'text/plain'
    channel.basic_publish(body=msg,exchange='hello-exchange',properties=msg_props,routing_key='hola')

    使用pika模块与RabbitMQ建立通信。第二到第四行用于获取RabbitMQ的信道channel,然后通过channel声明交换器,类型为direct,且可持久化,不能自动删除队列。最后一行调用channel的basic_publish方法发送消息msg到hello-exchange交换器和路由key是hola的队列中。

  • 编写“hello world”消费者,并保存为consumer.py

    import pika
    credentials = pika.PlainCredentials('guest','guest')
    conn_params = pika.ConnectionParameters('192.168.90.26',credentials= credentials)
    conn_broker = pika.BlockingConnection(conn_params)
    channel = conn_broker.channel()
    channel.exchange_declare(exchange='hello-exchange',type='direct',passive=False,durable=True,auto_delete=False)
    channel.queue_declare(queue='hello-queue')
    channel.queue_bind(queue='hello-queue',exchange='hello-exchange',routing_key='hola')
    
    def msg(channel,method,haeder,body):
    channel.basic_ack(delivery_tag=method.delivery_tag)
    if body == 'quit':
    channel.basic_cancel(consumer_tag='hello-consumer')
    channel.stop_consuming()
    else:
    print body
    channel.basic_consume(msg,queue='hello-queue',consumer_tag='hello-consumer')
    channel.start_consuming()

    前六行与生产者相同,第七行使用channel声明一个叫hello-queue的队列,并通过叫hola的路由key把hello-queue队列和hello-exchange交换器绑定。倒数第二行是订阅队列。

  • 启动消费者

    python consumer.py
  • 执行生产者

    python producer.py 'hello world'
  • 查看消费者进程打印结果

以上就是一个利用RabbitMQ实现的打印“hello world”的消息队列服务。

上述内容频频出现交换器和绑定等概念。其实,交换器和绑定这些概念都来自于AMQP规范。消息投递的流程是这样的:首先消息被发送到交换器,然后根据确切的规则RabbitMQ把消息投递到消息队列,最后消息队列中的消息被订阅的消费者消费。其中,这些规则被称为路由键(routing key)。当我们把消息发送到MQ时,消息将会拥有一个路由键--即便是空的--RabbitMQ也会将其和绑定的路由键进行匹配。如果相匹配,那么消息将会被投递到该队列。如果不匹配任何绑定模式,那么消息进入“黑洞”。

通过在交换器和队列之间添加绑定动作,AMQP可以适应更多的应用场景,例如发布/订阅或者多播等等。RabbitMQ可以根据路由键把消息从交换器路由到队列,也可以把消息投递到多个队列。这些功能可以通过不同的类型的交换器实现。AMQP规范定义了四种交换器类型:direct,fanout,topic和header。

  • direct类型

    direct类型是最简单的类型:如果路由键匹配,那么消息就被投递到对应的队列。

  • fanout类型

    fanout交换器会把消息投递到所有附加在此交换器上的队列,类似于消息广播。

  • topic类型

    topic交换器能够把不同路由键的消息投递到相同的队列。原因主要是因为topic类型的路由键能够使用正则表达式。凡是匹配该正则表达式的消息的路由键都会被路由到相同的队列。

  • header类型

    header交换器允许匹配AMQP消息的header而非路由键。除此之外和direct交换器完全一致。

另外,RabbitMQ还支持多租户模式。实现方式是采用虚拟主机vhost。每一个vhost本质上是一个mini版的RabbitMQ服务器,拥有自己的队列、交换器和绑定等等。更重要的是,它拥有自己的权限机制。因此,RabbitMQ服务器能够运行众多的应用程序,而不必担心应用之间相互干扰。

RabbitMQ默认vhost是/,查看方式如下:

[root@controller ~]# rabbitmqctl list_vhosts
Listing vhosts
/

添加vhost:

[root@controller ~]# rabbitmqctl add_vhost neutron
Creating vhost "neutron"
[root@controller ~]# rabbitmqctl list_vhosts
Listing vhosts
/
neutron

使用vhost:

conn_params = pika.ConnectionParameters('192.168.90.26',credentials= credentials, virtual_host='neutron')

RabbitMQ的虚拟机概念类似于Linux中的命名空间,对不同资源进行了隔离。

小结

RabbitMQ还有许多有用的特性,例如:可持久化,类似于访问控制列表(ACL)风格的权限系统,天然支持分布式系统调用等等。理解以上这些特性,能够帮助我们快速理清Neutron各组件之间的通信模式,对分析Neutron源码事半功倍。

如果对云计算感兴趣,可以关注我的微信公众号:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值