rabbitmq
send端
import pika
credentials = pika.PlainCredentials('zhou', '')
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials))
channel = connection.channel()
#声明queue
channel.queue_declare(queue='hello')
#n RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange.
channel.basic_publish(exchange='',
routing_key='hello',
body='Hello World!')
print(" [x] Sent 'Hello World!'")
connection.close()
receive端
import pika connection = pika.BlockingConnection(pika.ConnectionParameters(
'localhost'))
channel = connection.channel() #You may ask why we declare the queue again ‒ we have already declared it in our previous code.
# We could avoid that if we were sure that the queue already exists. For example if send.py program
#was run before. But we're not yet sure which program to run first. In such cases it's a good
# practice to repeat declaring the queue in both programs.
channel.queue_declare(queue='hello') def callback(ch, method, properties, body):
print(" [x] Received %r" % body) channel.basic_consume(callback,
queue='hello',
no_ack=True) print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
消费一个消息可能会花好几秒。你可能会问,如果如果一个消费者启动了一个长的任务,消息发了一半然后死了。按我们现在的代码,一旦rabbitmq传递了一个消息到给消费者,然后rabbitmq就迅速的将这个消息从内存里删除。在这种情况下,如果你kill了一个消费者,我们就会失去了这个正在传递的消息。
但是我们不想失去这个消息。如果一个消费者死了,我想把这个任务传给另一个消费者。
为了确保一个消息从不丢失,rabbitmq支持消息确认。消费者处理完信息后会向rabbitmq发送一个消息确认,这样rabbitmq就可以从内存里删除这个消息了。
如果一个消费者死掉了,没有发ack,rabbitmq就会知道这个消息没有传递成功,就会把这个消息重新存到queue里。
如果此时有其它的消费者在线,rabbitmq就会迅速的将这个消息传递给其它的的消费者。这样就确保了消息没有丢失,即使这个消费者是偶尔挂了。
根本就没有超时时间一说,当那个消费者挂了,rabbitmq会重新转发那条消息。即使这个消息处理了很长时间都没关系。
rabbitmq消息确认默认是开启的(no_ack=Fault)。在之前的例子里我们显然用的no_ack=True。
队列及消息持久化
生产者
import pika
credentials = pika.PlainCredentials('zhou', '')
# connection = pika.BlockingConnection(pika.ConnectionParameters(host=url_1,
# credentials=credentials, ssl=ssl, port=port))
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials))
channel = connection.channel()
# 声明queue,durable=True(队列持久化)
channel.queue_declare(queue='alex3',durable=True)
# n RabbitMQ a message can never be sent directly to the queue, it always needs to go through an exchange.
channel.basic_publish(exchange='',
routing_key='alex3', #send msg to this queue
body='Hello World!23',
properties=pika.BasicProperties(
delivery_mode=2, # 消息持久化
)
)
print(" [x] Sent 'Hello World!2'")
connection.close()
消费者
import pika
import time
credentials = pika.PlainCredentials('zhou', '')
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials)) channel = connection.channel()
# You may ask why we declare the queue again ‒ we have already declared it in our previous code.
# We could avoid that if we were sure that the queue already exists. For example if send.py program
# was run before. But we're not yet sure which program to run first. In such cases it's a good
# practice to repeat declaring the queue in both programs. channel.queue_declare(queue='alex3',durable=True)#队列持久化 def callback(ch, method, properties, body):
print(ch, method, properties) print(" [x] Received %r" % body)
time.sleep(1) channel.basic_consume(callback,
queue='alex3',
no_ack=True
)
channel.basic_qos(prefetch_count=1)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()
消息公平分发
如果Rabbit只管按顺序把消息发到各个消费者身上,不考虑消费者负载的话,很可能出现,一个机器配置不高的消费者那里堆积了很多消息处理不完,同时配置高的消费者却一直很轻松。为解决此问题,可以在各个消费者端,配置perfetch=1,意思就是告诉RabbitMQ在我这个消费者当前消息还没处理完的时候就不要再给我发新消息了。
channel.basic_qos(prefetch_count=1)
生产者
import pika,sys
credentials = pika.PlainCredentials('zhou', '')
# connection = pika.BlockingConnection(pika.ConnectionParameters(host=url_1,
# credentials=credentials, ssl=ssl, port=port))
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials))
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()
消费者
import pika,time
credentials = pika.PlainCredentials('zhou', '')
# connection = pika.BlockingConnection(pika.ConnectionParameters(host=url_1,
# credentials=credentials, ssl=ssl, port=port))
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials))
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(callback,
queue='task_queue') channel.start_consuming()
rabbitmq消息发布\订阅(Publish\Subscribe)
当要采用广播发消息的时候就要用到exchange了。
exchange是一个很简单的东西,一端从生产者里接收消息,另一端把消息推送到队列里。exchange必须清除的知道它从生产者里接收的消息要发送给谁。接收到的消息是应该被追加到指定的queue里?还是应该追加到很多个queue里?或者是扔掉?这个规则都是根据exchange的类型来定义的。
exchange的类型:
fanout: 所有bind到此exchange的queue都可以接收消息
direct: 通过routingKey和exchange决定的那个唯一的queue可以接收消息
topic:所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息
表达式符号说明:#代表一个或多个字符,*代表任何字符
例:#.a会匹配a.a,aa.a,aaa.a等
*.a会匹配a.a,b.a,c.a等
注:使用RoutingKey为#,Exchange Type为topic的时候相当于使用fanout
headers: 通过headers 来决定把消息发给哪些queue
fanout实例
send端
import pika
import sys credentials = pika.PlainCredentials('zhou', '')
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials)) channel = connection.channel() channel.exchange_declare(exchange='logs', 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()
recv端
import pika
credentials = pika.PlainCredentials('zhou', '')
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials))
channel = connection.channel()
channel.exchange_declare(exchange='logs',type='fanout')
result = channel.queue_declare(exclusive=True) # 不指定queue名字,rabbit会随机分配一个名字,exclusive=True会在使用此queue的消费者断开后,自动将queue删除
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,
)
channel.start_consuming()
direct实例
send端
import pika
import sys credentials = pika.PlainCredentials('zhou', '')
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials)) 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, #error
body=message) print(" [x] Sent %r:%r" % (severity, message))
connection.close()
recv端
import pika
import sys credentials = pika.PlainCredentials('zhou', '')
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials))
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:
sys.stderr.write("Usage: %s [info] [warning] [error]\n" % sys.argv[0])
sys.exit(1) for severity in severities: #[error info warning]
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,)
channel.start_consuming()
topic实例
send端
import pika
import sys credentials = pika.PlainCredentials('zhou', '')
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials)) 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()
recv端
import pika
import sys credentials = pika.PlainCredentials('zhou', '')
connection = pika.BlockingConnection(pika.ConnectionParameters(
host='10.0.1.14',credentials=credentials)) 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:
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(callback,queue=queue_name) channel.start_consuming()
rabbitmq的更多相关文章
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- RabbitMq应用二
在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,rabbitmq内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...
- 如何优雅的使用RabbitMQ
RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具.消息队列的使用场景大概有3种: 1.系统集成,分布式系统的设 ...
- RabbitMq应用一的补充(RabbitMQ的应用场景)
直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...
- RabbitMq应用一
RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
- windows下 安装 rabbitMQ 及操作常用命令
rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...
- RabbitMQ + PHP (三)案例演示
今天用一个简单的案例来实现 RabbitMQ + PHP 这个消息队列的运行机制. 主要分为两个部分: 第一:发送者(publisher) 第二:消费者(consumer) (一)生产者 (创建一个r ...
- RabbitMQ + PHP (二)AMQP拓展安装
上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...
随机推荐
- 基于C/S架构的3D对战网络游戏C++框架_【不定期更新通知】
由于笔者最近有比赛项目要赶,这个基于C/S架构的3D对战网络游戏C++框架也遇到了一点瓶颈需要点时间沉淀,所以近一段时间不能保证每天更新了,会保持不定期更新.同时近期笔者也会多分享一些已经做过学过的C ...
- 捕获起英文名Edda的灵感来源,我的心愿是程序员这个行业能够男女人数平衡
在腾讯的暑期训练营结识过不少鹅厂的前辈,他们对我的成长提供了很大的帮助,可以说有着知遇之恩,大部分现在还保持着联系,请教问题时会不吝赐教,以至于就在前两天11号企鹅18岁的成年礼,朋友圈刷满了领腾讯总 ...
- booting logo & booting animation
開機第一張圖片: 圖片位置: linux_repo/vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo 因為 project 選用 ...
- com.panie 项目开发随笔_功能任务设计(2016.12.28)
(一) 第一个菜单 做什么好呢? 1)上次 在研究的功能 是 爬虫,需要将定时爬虫的任务加进来 2)博客的页面,也需要重新布局出来 3)需要做一个,添加博客的页面 (二) 那就先做博客管理吧! 先添加 ...
- windows 10专业版14393.447 64位纯净无广告版系统 基于官方稳定版1607制作 更新于20161112
系统特点: 447更新日志(Win10 PC一周年更新正式版14393.447 32位/64位更新补丁KB3200970下载 Flash补丁Kb3202790下载): 1.通过网友的反馈,保留了Edg ...
- ActiveMQ_Mqtt的TCP丢包
现象 Mqtt Consumer应该收到的消息少于预期,登录ActiveMQ的管理页面里的Topics,查看Messages Enqueued发现同样少于理应接收的数量. 定位问题 怀疑是TCP丢包, ...
- maven管理本地jar包注意事项
今天lucene中集成第三方中文分词器IKAnalyzer的时候遇到了相似的问题:lucene版本4.9.IKAnalyzer版本2012FF_hf1 直接去maven仓库下载,pom配置如下: &l ...
- 配置LVS + Keepalived高可用负载均衡集群之图文教程
负载均衡系统可以选用LVS方案,而为避免Director Server单点故障引起系统崩溃,我们可以选用LVS+Keepalived组合保证高可用性. 重点:每个节点时间都同步哈! C++代码 [r ...
- 父子页面之间元素相互操作(iframe子页面)
js/jquery获取iframe子页面中元素的方法: 一.使用window.frames["iframe的ID"]获取元素 window.onload = function() ...
- laypage分页
1.分页 laypage({ cont:$("#page"), //容器,仅支持id名\原生DOM对象,jquery对象 pages:, //总页数 skip:true, //是否 ...