热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Rabbitmqpython连接rabbitmq

目录创建用户简单示例一个生产者,两个消费者轮询消费exchange类型fanout发布和订阅directtopic创建用户sriptrabbitmqctladd_u

目录

  • 创建用户
  • 简单示例
  • 一个生产者,两个消费者轮询消费
  • exchange类型
  • fanout发布和订阅
  • direct
  • topic

创建用户

```sript
rabbitmqctl add_user admin 123123
rabbitmqctl set_user_tags admin administrator
rabbitmqctl set_permissions -p '/' admin '.' '.' '.'
```

简单示例

python-one-overall.png

send.py

#!/usr/bin/env python
import pikacredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.queue_declare(queue='hello')channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()

receive.py

#!/usr/bin/env python
import pikacredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.queue_declare(queue='hello')def callback(ch, method, properties, body):print(" [x] Received %r" % body)channel.basic_consume(queue='hello', on_message_callback=callback, auto_ack=True)print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()


一个生产者,两个消费者轮询消费

python-two.png

send.py

#!/usr/bin/env python
import pika
import syscredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.queue_declare(queue='hello')message = ' '.join(sys.argv[1:]) or "Hello World!"channel.basic_publish(exchange='',routing_key='hello',body=message)
print(" [x] Sent %r" % message)
connection.close()

receive.py 两个消费端相同

#!/usr/bin/env python
import pika
import timecredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.queue_declare(queue='hello')def callback(ch, method, properties, body):print(" [x] Received %r" % body)time.sleep(body.count(b'.'))print(" [x] Done")channel.basic_consume(queue='hello', on_message_callback=callback, auto_ack=True)print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

结果

发送:
[root@node1 3]# python send.py 1[x] Sent '1'
[root@node1 3]# python send.py 2[x] Sent '2'
[root@node1 3]# python send.py 3[x] Sent '3'
[root@node1 3]# python send.py 4[x] Sent '4'receive1:[x] Received '2'[x] Done[x] Received '4'[x] Donereceive2:[x] Received '1'[x] Done[x] Received '3'[x] Done


消息确认

确认消息必须在接收方的channel上回复,使用不同的channel将导致异常

send.py

#!/usr/bin/env python
import pika
import syscredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.queue_declare(queue='hello')message = ' '.join(sys.argv[1:]) or "Hello World!"channel.basic_publish(exchange='',routing_key='hello',body=message)
print(" [x] Sent %r" % message)
connection.close()

receive.py

#coding: utf-8
#!/usr/bin/env python
import pika
import timecredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.queue_declare(queue='hello')def callback(ch, method, properties, body):print(" [x] Received %r" % body)time.sleep(10) #模拟处理消息print(" [x] Done")ch.basic_ack(delivery_tag = method.delivery_tag) #手动确认消息处理完毕channel.basic_consume(queue='hello', on_message_callback=callback)#queue='hello', on_message_callback=callback, auto_ack=True) #auto_ack=True 表示消费完以后主动把状态通知rabbitmq 默认是Falseprint(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()

查看当前未被确认的消息rabbitmqctl list_queues name messages_ready messages_unacknowledged


消息持久化

虽然,已经做到了消费端挂掉后消息不丢失,但当rabbitmq重启后,会丢失队列和消息,导致消息丢失。除非显示声明。
确保消息不丢失需要做两件事:

  • 队列持久化

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

  • 消息持久化
    python channel.basic_publish(exchange='', routing_key="task_queue", body=message, properties=pika.BasicProperties( delivery_mode = 2, # make message persistent ))

将消息持久化也并不能完全保证消息不丢失。(消息有可能保存到系统缓存,但还未同步到磁盘)
如果需要更强的保证可以使用publisher confirm

rabbitmq 对于已经存在的队列可以重复声明,但需要确保参数相同


公平调度

公平调度。在一个消费者未处理完一个消息之前不要分发新的消息给它,而是将这个新消息分发给另一个不是很忙的消费者进行处理。为了解决这个问题我们可以在消费者代码中使用 channel.basic.qos ( prefetch_count = 1 ),将消费者设置为公平调度。

通过 BasicQos 方法设置prefetchCount = 3。这样RabbitMQ就会使得每个Consumer在同一个时间点最多处理3个Message。换句话说,在接收到该Consumer的ack前,他它不会将新的Message分发给它。

send.py

#!/usr/bin/env python
import pika
import sysconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()channel.queue_declare(queue='task_queue', durable=True)message = ' '.join(sys.argv[1:]) or "Hello World!"
channel.basic_publish(exchange='',routing_key='task_queue',body=message,properties=pika.BasicProperties(delivery_mode=2, # make message persistent))
print(" [x] Sent %r" % message)
connection.close()

receive.py

#!/usr/bin/env python
import pika
import timeconnection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = connection.channel()channel.queue_declare(queue='task_queue', durable=True)
print(' [*] Waiting for messages. To exit press CTRL+C')def callback(ch, method, properties, body):print(" [x] Received %r" % body)time.sleep(body.count(b'.'))print(" [x] Done")ch.basic_ack(delivery_tag=method.delivery_tag)channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='task_queue', on_message_callback=callback)channel.start_consuming()


exchange类型

  • fanout
    • 把发送到该交换器的消息路由到所有与该交换器绑定的队列中
  • direct
    • 把消息路由到RoutingKey与BindingKey完全匹配的队列中
  • topic
    • 与direct相似,不过topic类型可以进行类似正则匹配
  • headers
    • 不依赖于路由键的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配(性能差,用的少)

fanout发布和订阅

发布/订阅:向多个消费者传递同一条消息

exchanges.png

send.py

#coding: utf-8
#!/usr/bin/env python
import pika
import syscredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
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)
print(" [x] Sent %r" % message)
connection.close()

receive.py

#coding: utf-8
#!/usr/bin/env python
import pikacredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.exchange_declare(exchange='logs', exchange_type='fanout')result = channel.queue_declare('', exclusive=True) #创建临时队列,消费者关闭后队列将被删除
queue_name = result.method.queuechannel.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(queue=queue_name, on_message_callback=callback, auto_ack=True)channel.start_consuming()


direct

python-four.png

send.py

#!/usr/bin/env python
import pika
import syscredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.exchange_declare(exchange='direct_logs', exchange_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()

receive.py

#!/usr/bin/env python
import pika
import syscredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.exchange_declare(exchange='direct_logs', exchange_type='direct')result = channel.queue_declare('', exclusive=True)
queue_name = result.method.queueseverities = sys.argv[1:]
if not severities:sys.stderr.write("Usage: %s [info] [warning] [error]\n" % 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(queue=queue_name, on_message_callback=callback, auto_ack=True)channel.start_consuming()

使用

[root@node1 5]# python send.py error "Run. Run. Or it will explode."[root@node1 5]# python receive.py warning error
[root@node1 5]# python receive.py error


topic

send.py

#!/usr/bin/env python
import pika
import syscredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.exchange_declare(exchange='topic_logs', exchange_type='topic')routing_key = sys.argv[1] if len(sys.argv) > 2 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()

receive.py

#!/usr/bin/env python
import pika
import syscredentials = pika.PlainCredentials('admin','123123')
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.49.135',5673,'/',credentials))
channel = connection.channel()channel.exchange_declare(exchange='topic_logs', exchange_type='topic')result = channel.queue_declare('', exclusive=True)
queue_name = result.method.queuebinding_keys = sys.argv[1:]
if not binding_keys:sys.stderr.write("Usage: %s [binding_key]...\n" % 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(queue=queue_name, on_message_callback=callback, auto_ack=True)channel.start_consuming()

参考
https://www.itsvse.com/thread-4667-1-1.html RabbitMQ BasicQos消费者并行处理限制
https://www.cnblogs.com/ccorz/p/5710098.html Python之操作RabbitMQ
https://www.cnblogs.com/wt11/p/5970297.html Python操作rabbitmq 实践笔记
https://www.cnblogs.com/kerwinC/p/5967584.html python RabbitMQ队列使用
https://www.rabbitmq.com/documentation.html 官网


转:https://www.cnblogs.com/mldblue/articles/10956369.html



推荐阅读
  • 多进程程序异常退出问题分析与解决 ... [详细]
  • 在Tableau中进行多表关联后统计时遇到的常见问题及解决方法
    在使用Tableau进行多表关联统计时,常遇到数据不匹配、重复记录等问题。例如,在处理员工信息表时,若员工ID未正确关联,可能导致薪资统计错误。本文将详细探讨这些问题的成因,并提供有效的解决方案,如利用Tableau的数据清理工具和高级连接功能,确保数据准确性和完整性。 ... [详细]
  • 本文深入探讨了 Python Watchdog 库的使用方法和应用场景。通过详细的代码示例,展示了如何利用 Watchdog 监控文件系统的变化,包括文件的创建、修改和删除等操作。文章不仅介绍了 Watchdog 的基本功能,还探讨了其在实际项目中的高级应用,如日志监控和自动化任务触发。读者将能够全面了解 Watchdog 的工作原理及其在不同场景下的应用技巧。 ... [详细]
  • Java 8 引入了 Stream API,这一新特性极大地增强了集合数据的处理能力。通过 Stream API,开发者可以更加高效、简洁地进行集合数据的遍历、过滤和转换操作。本文将详细解析 Stream API 的核心概念和常见用法,帮助读者更好地理解和应用这一强大的工具。 ... [详细]
  • Java队列机制深度解析与应用指南
    Java队列机制在并发编程中扮演着重要角色。本文深入解析了Java队列的各种实现类及其应用场景,包括`LinkedList`、`ArrayBlockingQueue`和`PriorityQueue`等,并探讨了它们在高并发环境下的性能表现和适用场景。通过详细分析这些队列的内部机制和使用技巧,帮助开发者更好地理解和应用Java队列,提升系统的设计和架构能力。 ... [详细]
  • voc生成xml 代码
    目录 lxmlwindows安装 读取示例 可视化 生成示例 上面是代码,下面有调用示例 api调用代码,其实只有几行:这个生成代码也很简 ... [详细]
  • 本文提供了 RabbitMQ 3.7 的快速上手指南,详细介绍了环境搭建、生产者和消费者的配置与使用。通过官方教程的指引,读者可以轻松完成初步测试和实践,快速掌握 RabbitMQ 的核心功能和基本操作。 ... [详细]
  • 利用ViewComponents在Asp.Net Core中构建高效分页组件
    通过运用 ViewComponents 技术,在 Asp.Net Core 中实现了高效的分页组件开发。本文详细介绍了如何通过创建 `PaginationViewComponent` 类并利用 `HelloWorld.DataContext` 上下文,实现对分页参数的定义与管理,从而提升 Web 应用程序的性能和用户体验。 ... [详细]
  • 【Python爬虫实操】 不创作小说,专精网站内容迁移,超高效!(含源代码)
    本文详细介绍了如何利用Python爬虫技术实现高效网站内容迁移,涵盖前端、后端及Android相关知识点。通过具体实例和源代码,展示了如何精准抓取并迁移网站内容,适合对Python爬虫实战感兴趣的开发者参考。 ... [详细]
  • 深入解析MyBatis的高级映射技术
    在前一章节中,我们探讨了MyBatis的基本对象映射方法,其中对象属性与数据库表字段之间实现了直接的一对一映射。然而,在实际开发中,这种简单的映射方式往往难以满足复杂业务需求。本文将深入分析MyBatis的高级映射技术,介绍如何通过配置和注解实现更为灵活的对象与数据库表之间的映射关系,包括嵌套结果、联合查询和动态SQL等高级功能,以提高开发效率和代码可维护性。 ... [详细]
  • 深入解析 org.hibernate.event.spi.EventSource.getFactory() 方法及其应用实例 ... [详细]
  • 字符串对比竟也暗藏玄机,你是否认同?
    在探讨字符串对比技术时,本文通过两个具体案例深入剖析了其背后的复杂性与技巧。首先,案例一部分详细介绍了需求背景、分析过程及两种不同的代码实现方法,并进行了总结。接着,案例二同样从需求描述出发,逐步解析问题并提供解决方案,旨在揭示字符串处理中容易被忽视的关键细节和技术挑战。 ... [详细]
  • AngularJS uirouter模块下的状态管理机制深入解析
    本文深入探讨了 AngularJS 中 ui-router 模块的状态管理机制。通过详细分析状态配置、状态转换和嵌套状态等核心概念,结合实际案例,帮助开发者更好地理解和应用这一强大工具,提升单页面应用的开发效率和用户体验。 ... [详细]
  • 本讲深入探讨了 Python 中集合的基本概念及其符号表示方法,通过实例代码详细解析了如何将列表转换为集合,并展示了集合在数据处理中的独特优势。 ... [详细]
  • 一文了解消息中间件RabbitMQ
    消息中间件---RabbitMQ1消息中间件的作用2.常用的消息中间件3消息中间件RabbitMQ3.1RabbitMQ介绍3.3RabbitMQ的队列模式3.3RabbitMQ的 ... [详细]
author-avatar
军军CJJ_317
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有