python实时连接rabbitmq_Rabbitmq - python连接rabbitmq

创建用户

```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 pika

credentials = 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 pika

credentials = 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 sys

credentials = 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 time

credentials = 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] Done

receive2:

[x] Received '1'

[x] Done

[x] Received '3'

[x] Done

消息确认

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

send.py

#!/usr/bin/env python

import pika

import sys

credentials = 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 time

credentials = 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 默认是False

print(' [*] 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)

消息持久化

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 sys

connection = 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 time

connection = 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 sys

credentials = 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 pika

credentials = 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.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(

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 sys

credentials = 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 sys

credentials = 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.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:

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 sys

credentials = 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 sys

credentials = 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.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(

queue=queue_name, on_message_callback=callback, auto_ack=True)

channel.start_consuming()

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值