python使用pika操作rabbitmq编程入门(二)

使用皮卡(pika)操作RabbitMQ 简介   众所周知,RabbitMQ是一个开源的高性能的消息队列,支持多种开发语言:Java,Python,.Net,C,C++,PHP等多种语言,那么如何通过Python语言调用RabbitMQ呢?Pythonpika这个模块提供了完整的调用方法,通过这个包我们可以实现Rabbit的简单模式,交换机模式以及一些特殊的参数。那么我们如何使用pika模块呢,接下来,请看听我慢慢道来。 一、简单模式 生产者 简单模式下,有多个消费者时,采用轮询方式处理消息。 import pika if __name_ 阅读详情
pika生产者程序大致步骤:
1. 建立连接connection , 需要认证的调用认证参数
2. 创建通道channel  当然 channel可以池化,这样可以重复使用
3. 声明队列   指定队列属性, 一旦指定属性不能修改, 例如是否持久化,名称
4. 声明交换机  交换机类型,名称等, 也可以不用声明,直接使用 “” 空字符串,默认交换机也可以
5. 将队列与交换机绑定   queue_bind 
6. basic_publish 发送到交换机 指定路由键
pika消费者程序大致步骤:
1. 建立连接connection , 需要认证的调用认证参数
2. 创建通道channel  当然 channel可以池化,这样可以重复使用
3. 声明队列   指定队列属性, 一旦指定属性不能修改, 例如是否持久化,名称
4. 声明交换机  交换机类型,名称等, 也可以不用声明,直接使用 “” 空字符串,默认交换机也可以
5. 将队列与交换机绑定   queue_bind 
6. basic_consume 消费消息
1. 轮询接收消息

使用消息队列的一个好处就是, 可以将任务消息发送到队列中,由消费者异步进行处理, 同时对于后端消费者可以很容易地增加减少,只需要运行多个进程即可, 方便扩展, 之前的示例中消费端程序就可以开启多个,然后可以看到消费被轮询得分配给每个消费者

将之前的消费者略作更改, 加入客户端编号,启动三个消费者, 通过生产者发送4个消息, 依次收到消息, 即是 轮询(round-robin):

 [*] Waiting for messages. To exit press CTRL+C
1. [x] Received 'Hello World!'
1. [x] Received 'Hello World!'
 [*] Waiting for messages. To exit press CTRL+C
2. [x] Received 'Hello World!'
 [*] Waiting for messages. To exit press CTRL+C
3. [x] Received 'Hello World!'
2. 消息确认:

为了防止消息丢失,RabbitMQ提供了消息响应(acknowledgments)。消费者会通过一个ack(响应),告诉RabbitMQ已经收到并处理了某条消息,然后RabbitMQ就会释放并删除这条消息。 如果消费者(consumer)挂掉了,没有发送响应,RabbitMQ就会认为消息没有被完全处理,然后重新发送给其他消费者(consumer)。这样,及时工作者(workers)偶尔的挂掉,也不会丢失消息。

消息响应默认auto_ack=False, 不自动确认消息, 即是需要我们处理并确认消息的

确认需要发送确认消息:

在回调callback中加入basic_ack

channel.basic_ack(delivery_tag = method.delivery_tag)

如果auto_ack设置为True,而忘记basic_ack消息确认,消息在程序退出之后就会重新发送,如果不及时释放没响应的消息,RabbitMQ就会占用越来越多的内存。

为了排除这种错误,可以使用rabbitmqctl命令,输出messages_unacknowledged字段:

# rabbitmqctl list_queues name messages_ready messages_unacknowledged
Timeout: 60.0 seconds ...
Listing queues for vhost / ...
name    messages_ready  messages_unacknowledged
hello   0       0
TEST01  0       0
3. 消息持久化

如果没有向rabbitmq指定消息持久化, 则退出或者崩溃的时候,将会丢失所有队列和消息, 消息持久化必须把“队列”和“消息”设为持久化

  1. 队列声明持久化:
channel.queue_declare(queue='hello', durable=True)

注意一个消息队列被声明过一次后,rabbitmq不允许使用不同的参数重新定义队列, 因此如果存在hello队列,上面会提示错误

  1. 消息声明持久化

将publish生产者发送消息时候消息属性, delivery_mode的属性设为2

 properties=pika.BasicProperties(delivery_mode=2)

生产者代码:

channel.queue_declare(queue='TEST02', durable=True)

channel.basic_publish(exchange='',
                      routing_key='TEST02',
                      body='Hello World!',
                      properties=pika.BasicProperties(delivery_mode=2)
                      )

客户端代码:

channel.queue_declare(queue='TEST02', durable=True)

def callback(ch, method, properties, body):
    print(". [x] Received %r" % body)
    ch.basic_ack(delivery_tag=method.delivery_tag)


channel.basic_consume(on_message_callback=callback,
                      queue='TEST02',
                      auto_ack=False,
                      )
4. 设置客户端QOS

开启客户端最大的未处理消息队列大小:

channel.basic_qos(prefetch_count=1)

代码示例:

channel.queue_declare(queue='TEST02', durable=True)
channel.basic_qos(prefetch_count=1)

def callback(ch, method, properties, body):
    print(". [x] Received %r" % body)
    ch.basic_ack(delivery_tag=method.delivery_tag)


channel.basic_consume(on_message_callback=callback,
                      queue='TEST02',
                      auto_ack=False,
                      )
5. 发布订阅模式:

rabbitmq在之前介绍的时候可以看到,消息是被依次发送给消费者,即是消息只会被发送给一个消费者,除非开启确认机制时处理失败了, 一个消息发送给多个消费者, 这个是rabbitmq提供的发布订阅模式

发布者(producer)只需要把消息发送给一个交换机(exchange)。交换机非常简单,它一边从发布者方接收消息,一边把消息推送到队列。交换机必须知道如何处理它接收到的消息,是应该推送到指定的队列还是是多个队列,或者是直接忽略消息。这些规则是通过交换机类型(exchange type)来定义的

交换机类型:直连交换机(direct)-- 一对一, 之前使用的就是这个;主题交换机(topic)-- 模糊匹配,需要符合匹配规则; headers(头交换机)和 扇型交换机(fanout)-- 进行消息广播

fanout会发送消息到交换机所有的消息队列

消息将会根据指定的routing_key分发到指定的队列

rabbitmq拥有一个默认交换机 即是 空字符串(""),

channel.basic_publish(exchange='',
                      routing_key='hello',
                      body=message)

在pika编程中,可以不用指定队列名称,系统会随机生成一个名称, 在重启都该队列丢失

只需在声明时不提供参数就可以了

result = channel.queue_declare()

队列需要绑定到交换, 才能通过交换机发送消息到该队列

channel.queue_bind(exchange='logs',
                   queue=result.method.queue)

代码:

生产者:

channel = connection.channel()

channel.exchange_declare(exchange='logs',
                         exchange_type='fanout')

message = ' '.join(sys.argv[1:]) or "info: Hello World!"
channel.basic_publish(exchange='logs',
                      routing_key='',
                      body=message)
connection.close()

消费者:

channel = connection.channel()

channel.exchange_declare(exchange='logs',
                         exchange_type='fanout')

result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue

channel.queue_bind(exchange='logs',
                   queue=queue_name)

print ' [*] Waiting for logs. To exit press CTRL+C'

def callback(ch, method, properties, body):
    print " [x] %r" % (body,)

channel.basic_consume(callback,
                      queue=queue_name,
                      auto_ack=True)

channel.start_consuming()
6. 几个重要概念的程序实现
  1. 路由 routing

路由键在发送消息的时候进行指定

channel.basic_publish(exchange='logs',
                      routing_key='',
                      body=message)
  1. 队列绑定 binding
channel.queue_bind(exchange=exchange_name,
                   queue=queue_name)
  1. 交换机类型

交换机声明的时候进行指定, 一般常用direct, fanout, topic三种类型

channel.exchange_declare(exchange='logs',
                         exchange_type='fanout')
  1. 路由键

一般路由键不等于绑定键, 但是我们通常在direct的时候可以近似的认为这两个等价的

在队列绑定的时候,通过指定routing_key 指定

channel.queue_bind(exchange=exchange_name,
                   queue=queue_name,
                   routing_key='tologs')
  1. 一个路由键多个队列

也就是多个队列使用相同的绑定键, 这个是合法 的, 这样就可以将消息发生到不同的队列中

例如:

channel.queue_bind(exchange="logs",queue="info",routing_key='tologs')
channel.queue_bind(exchange="logs",queue="warn",routing_key='tologs')
channel.queue_bind(exchange="logs",queue="debug",routing_key='tologs')
  1. 排他队列:

一个只有自己可见的队列,即不允许其它用户访问,RabbitMQ允许你将一个Queue声明成为排他性的

channel.queue_declare(exclusive=True)

示例代码:

生产者:

channel = connection.channel()

channel.exchange_declare(exchange='direct_logs',
                         type='direct')

severity = sys.argv[1] if len(sys.argv) > 1 else 'info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='direct_logs',
                      routing_key=severity,
                      body=message)
print " [x] Sent %r:%r" % (severity, message)
connection.close()

消费者:

channel = connection.channel()

channel.exchange_declare(exchange='direct_logs',
                         type='direct')

result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue

severities = sys.argv[1:]
if not severities:
    print >> sys.stderr, "Usage: %s [info] [warning] [error]" % \
                         (sys.argv[0],)
    sys.exit(1)

for severity in severities:
    channel.queue_bind(exchange='direct_logs',
                       queue=queue_name,
                       routing_key=severity)

print ' [*] Waiting for logs. To exit press CTRL+C'

def callback(ch, method, properties, body):
    print " [x] %r:%r" % (method.routing_key, body,)

channel.basic_consume(callback,
                      queue=queue_name,
                      auto_ack=True)

channel.start_consuming()
7. 主题交换机 (topic)

发送到主题交换机(topic exchange)的消息不可以携带随意什么样子的路由键(routing_key),它的路由键必须是一个由.分隔开的词语列表, 例如: “stock.usd.nyse”, “nyse.vmw”, “quick.orange.rabbit”

绑定键也必须拥有同样的格式。主题交换机背后的逻辑跟直连交换机很相似, 携带着特定路由键的消息会被主题交换机投递给绑定键与之想匹配的队列

它的绑定键和路由键有两个特殊应用方式, 即是支持模糊匹配:

  • * (星号) 用来表示一个单词.
  • # (井号) 用来表示任意数量(零个或多个)单词。

例如路由键: *.*.rabbitlazy.#

lazy.pink.rabbit 会匹配 *.*.rabbitlazy.#

lazy.x 匹配 lazy.#

注特殊情况:

当一个队列的绑定键为 “#”(井号) 的时候,这个队列将会无视消息的路由键,接收所有的消息。

* (星号) 和 # (井号) 这两个特殊字符都未在绑定键中出现的时候,此时主题交换机就拥有的直连交换机的行为。

示例代码:

生产者:

channel = connection.channel()

channel.exchange_declare(exchange='topic_logs',
                         type='topic')

routing_key = sys.argv[1] if len(sys.argv) > 1 else 'anonymous.info'
message = ' '.join(sys.argv[2:]) or 'Hello World!'
channel.basic_publish(exchange='topic_logs',
                      routing_key=routing_key,
                      body=message)
print " [x] Sent %r:%r" % (routing_key, message)
connection.close()

消费者:

channel = connection.channel()

channel.exchange_declare(exchange='topic_logs',
                         type='topic')

result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue

binding_keys = sys.argv[1:]
if not binding_keys:
    print >> sys.stderr, "Usage: %s [binding_key]..." % (sys.argv[0],)
    sys.exit(1)

for binding_key in binding_keys:
    channel.queue_bind(exchange='topic_logs',
                       queue=queue_name,
                       routing_key=binding_key)

print ' [*] Waiting for logs. To exit press CTRL+C'

def callback(ch, method, properties, body):
    print " [x] %r:%r" % (method.routing_key, body,)

channel.basic_consume(callback,
                      queue=queue_name,
                      auto_ack=True)

channel.start_consuming()
Python使用pika简单实现RabbitMQ通信 MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。 现在介绍一下基本的RabbitMQ的通信过程: RabbitMQ基本的通信模型是这样的,它类似于C-S通信模型,它包含一个producer (生产者),queue(消息队列)和一个consumer(消费者),生产者发送的消息只会存储在中间的消息队列中: 阅读详情

相关推荐

使用Python Pika操作RabbitMQ

在此示例中,我们连接到本地RabbitMQ服务器并创建一个名为“hello”的队列。在本文中,我们介绍了如何使用Python Pika库连接到RabbitMQ服务器、创建队列、发送消息和接收消息。在此示例中,我们将其设置为“hello”,这意味着我们将消息发送到名为“hello”的队列中。在此示例中,我们将其设置为空字符串,这意味着我们将消息直接发送到队列中,而不是通过交换机。一旦我们可以发送消息到队列中,我们就可以使用Python Pika从队列中接收消息了。在我们的回调函数中,我们打印接收到的消息。

EvktJava的博客 480

python使用pika库调用rabbitmq的参数使用

python使用pika库调用rabbitmq的参数使用

IT之一小佬的博客 2336

Unity零基础到入门 ☀️| 【UI系统学习】轻松学会 Unity 的 UGUI基础控件的使用(包括一个简易血条、蓝条设计)

Unity,UGUI。本篇博客来挑几种Unity中最常用的UI控件如何使用使用技巧,包括一个简易血条蓝条的小实例

努力前行,总会成为自己心中的那道光 2万+

python使用pika库调用rabbitmq的交换机模式

python使用pika库调用rabbitmq的交换机模式

IT之一小佬的博客 1658

python框架pika的基本使用

Python操作RabbitMqpika--队列)安装使用其他读取方法 安装 pip install pika 使用 import pika # 建立连接 # user:账号 pwd:密码 userx = pika.PlainCredentials(user, pwd) # hosh:rabbitmq所在的ip port: 端口号 parameters = pika.ConnectionParameters(host, int(port), '/', credentials=userx) conn = p

qq_44985692的博客 4904

python -rabbitmq操作

RabbitMq 是实现了高级消息队列协议(AMQP)的开源消息代理中间件。消息队列是一种应用程序对应用程序的通行方式,应用程序通过写消息,将消息传递于队列,由另一应用程序读取 完成通信。而作为中间件的 RabbitMq 无疑是目前最流行的消息队列之一。系统的高可用:日常生活当中各种商城秒杀,高流量,高并发的场景。当服务器接收到如此大量请求处理业务时,有宕机的风险。......

zxj19930410jy的博客 1778

python使用pika操作rabbitmq总结()

python 连接操作rabbitMQ 主要是使用pika库 安装: pip install pika==1.0.1 注意: pika 1.x 与 pika 0.x 有一些不同,使用的时候需要看清版本使用,避免踩坑 Pika是用于PythonRabbitMQ(AMQP 0-9-1)客户端库 注: 官方对于pika有如下介绍: Since threads aren’t appropriate t...

comprel的博客 3万+

python使用pika操作rabbitmq总结

python 连接操作rabbitMQ 主要是使用pika库 安装: pip install pika==1.0.1 注意: pika 1.x 与 pika 0.x 有一些不同,使用的时候需要看清版本使用,避免踩坑 Pika是用于PythonRabbitMQ(AMQP 0-9-1)客户端库 注: 官方对于pika有如下介绍: Since threads aren’t appropriate to every situation, it doesn’t require threads..

Jason_WangYing的博客 4087

python使用pika操作rabbitmq

一、概述 python 连接操作rabbitMQ 主要是使用pika库 pip3 install pika==1.1.0 官方对于pika有如下介绍 Since threads aren’t appropriate to every situation, it doesn’t require threads. Pika core takes care not...

shykevin的博客 2277

python--使用pika操作rabbitmq实现需求

有这样业务场景,算法部的同事有一个算法需要集成,有国内和国外两条链路,使用rabbitmq对应的试两个队列,但是他的算法只能开启一个实例,不能开两个进程,否则计算资源不足会崩溃(此处我想吐槽,做算法这帮人,工资又高,结果工程能力太差啦,所谓的算法也不过把github的开源库拿来改改参数,怎么好意思叫算法,搞不懂现在的中国互联网环境了),基于以上原因,需求则是需要在只开一个实力的情况下,消费两个队列里的任务。前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。

WenCoo的博客 2107

Python操作RabbitMQPika

安装RabbitMQ(MAC平台) 安装 brew install rabbitmq 启动 /usr/local/sbin rabbitmq-server 访问: http://localhost:15672 使用guest/guest 登陆 基本概念RabbitMQ发送消息时,都是先把消息发送给ExChange(交换机),然后再分发给有相应RoutingKey关系的Queue。ExCha

QuantumEnergy's blog 1341

pythonRabbitMQ的简单使用

pythonRabbitMQ的简单使用(一)RabbitMQ的简介(RabbitMQ的安装(五)结语 (一)RabbitMQ的简介 RabbitMq 是实现了高级消息队列协议(AMQP)的开源消息代理中间件。消息队列是一种应用程序对应用程序的通行方式,应用程序通过写消息,将消息传递于队列,由另一应用程序读取 完成通信。而作为中间件的 RabbitMq 无疑是目前最流行的消息队列之一。目前使用较多的消息队列有ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ。

????爱好者的博客 1万+

RabbitMQ python第三方库pika应用入门实践

RabbitMQ python第三方库pika应用入门实践

肖永威的专栏 2339

RabbitMQ 入门系列(9)— Pythonpika 库常用函数及参数说明

1. pika.PlainCredentials(username, password, erase_on_connect) 功能:创建连接时的登录凭证 参数: username: MQ 账号 password: MQ 密码 erase_on_connect: 删除连接上的凭据, 默认为 False credentials = pika.PlainCredentials(username...

wohu1104的专栏 6008

使用python构建httpserver,python+tornado+pika+rabbitmq

一、搭建环境 1.1安装Erlang      RabbitMQ是基于Erlang的,所以首先必须配置Erlang环境。从Erlang的官网 http://www.erlang.org/download.html 下载最新的erlang安装包,我下载的是otp_src_17.4.tar.gz 然后: $ tar xvzf otp_src_17.4.tar.gz $ cd otp_

u011299686的专栏 2376

「消息队列」Python使用pika操作RabbitMQ

前面几篇文章分别介绍了消息队列, AMQP协议以及RabbitMQ, 本篇文章开始尝试用具体语言操作RabbitMQ来搭建"生产者-消费者"模型. 本篇文章将使用Python语言, 而Python操作RabbitMQ库有很多, 比如pika, amqp以及Celery等, 下面就使用pika库来完成这个任务. 调用方法和参数的含义大多已通过注释给出. 针对消费者的实现, 我提供了两种方式: MQReceiver1通过回调来处理消息, MQReceiver2通过迭代来处理消息. 当Rab

Nxin的小抄本 3986

Python操作RabbitMQ

来源:http://www.cnblogs.com/phennry/p/5713274.html 本篇博客主要介绍如何通过Python操作管理RabbitMQ消息队列,大家在工作中可能遇到很多类似RabbitMQ这种消息队列的中间件,如:ZeroMQ、ActiveMQ、MetaMQ等,我们学会了如何操作RabbitMQ的话基本上操作其他的队列都是一...

墨鱼菜鸡 1910

pythonrabbitmqpika、消息发送和接收实例

1. 下载Pika #mkdir -p /data/soft #cd /data/soft #wget https://pypi.python.org/packages/source/p/pip/pip-1.5.6.tar.gz#md5=01026f87978932060cc86c1dc527903e #python setup.py install Traceback (most recent

momon的专栏 2万+

使用Python Pika 操作 Rabbitmq 完成(延时队列,死信队列)

自己封装的RabbitmqClient对象 #!/usr/bin/env python import pika import logging class RabbitMQClient: def __init__(self, conn_str='amqp://guest:guest@0.0.0.0:5672/Authorization/'): self.exchan...

qq_41572228的博客 2984

SpringBoot + MyBatis-Plus 高效实现数据变更记录:从注解到通用审计方案(附源码)

*** 数据变更审计插件* 拦截增删改操作,自动记录变更日志*/@Component@Resource/*** 拦截SQL执行*/@Override/*** 数据变更审计插件* 拦截增删改操作,自动记录变更日志/*** 拦截SQL执行。

2601_94871597的博客 539

ffmpeg(Windows版).zip

ffmpeg Windows版本

上一篇: rabbitmq管理
下一篇: git clone fatal unsupported protocol version异常处理办法
comprel
博客等级 码龄10年 70粉丝 132原创
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值