python--pika试用

rabbitmq–pika

任务处理:请求数量太多,需要把消息临时放到某个地方
发布订阅,一旦发布消息,所有订阅者都会收到一条相同的消息

# yum安装
安装配置epel源
rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
$ yum -y install erlang
$ yum -y install rabbitmq-server
$ systemctl start rabbitmq-server 

#docker 启动
docker pull rabbitmq:3.7.7-management
docker run --name mq -p 5672:5672 -p 15672:15672 -d rabbitmq:3.7.7-management

# 添加用户
sudo rabbitmqctl add_user rabbitmq mq123456
# 设置用户为administrator角色
sudo rabbitmqctl set_user_tags rabbitmq administrator
# 设置权限
sudo rabbitmqctl set_permissions -p "/" root ".*" ".*" ".*"

# 然后重启rabbiMQ服务
sudo systemctl restart rabbitmq-server 

pika使用方法—> 1.3.2

https://www.rabbitmq.com/tutorials/tutorial-two-python

####################################生产者#####################################
 
import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道    

channel.queue_declare(queue='name1')  # 声明队列,存在忽略,没有则创建     生产者与消费者都设置下,防止报错
mq_messege="Hello World!"
channel.basic_publish(exchange='',
                      routing_key='name1',  # 指定队列名称
                      body=mq_messege)  # 往该队列中发送一个消息
print(mq_messege+"publish success")
connection.close()  

hello world

单个消费者

#  单个消费者
import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道

channel.queue_declare(queue='name1')  # 声明队列,存在忽略,没有则创建


def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)
    ch.basic_ack(delivery_tag = method.delivery_tag) # 告诉服务端消息已取走,配合auto_ack=False使用



# channel.basic_consume('name1',callback,True)
channel.basic_consume(queue='name1', auto_ack=True, on_message_callback=callback)  # 默认 auto_ack=True


print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()


C:\pythonProject1\venv\Scripts\python.exe C:/pythonProject1/jtest.py
 [*] Waiting for messages. To exit press CTRL+C
 [x] Received b'{Hello World!}'
 [x] Received b'{Hello World!2}'  #继续等待

work queues

多个消费者

再起一个消费者,同时消费,默认情况下,当有多个消费者启动时,mq将以轮询的形式被消费

批量发送 消息测试

"""
data.txt
{"goods_id":0,"product_id":9770,"sku_id":0}
{"goods_id":0,"product_id":9771,"sku_id":1}
{"goods_id":0,"product_id":9772,"sku_id":2}
{"goods_id":0,"product_id":9773,"sku_id":3}
"""
import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道

channel.queue_declare(queue='name1')  # 声明队列,存在忽略,没有则创建

# 定义消息的headers
headers = {
    'key1': 'value1',
    'key2': 'value2'
}
 
with open('data.txt', 'r') as file:
    for mq_messege in file:
        channel.basic_publish(exchange='',
                      routing_key='name1',  # 指定队列名称
                      body=mq_messege.strip()),  # 往该队列中发送一些消息, 去掉换行符
                      properties=pika.BasicProperties(headers=headers)
        print(mq_messege.strip()+"\n"+"publish success")
connection.close()

ack

防止客户端未处理消息,挂掉 auto_ack=False

# auto_ack=False时,rabbitmq里将出现unack消息   消费者,每次启动都会从头消费一次
import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道

channel.queue_declare(queue='name1')  # 声明队列,存在忽略,没有则创建


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

channel.basic_consume(queue='name1', auto_ack=False, on_message_callback=callback)  # 默认 auto_ack=True

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming()   

告知server消息取走,防止客户端未处理消息,挂掉

def callback(ch, method, properties, body):
    print(" [x] Received %r" % body)
    # test_action   # mq处理动作,处理失败时,将不会ack消息 
    ch.basic_ack(delivery_tag = method.delivery_tag) # 告诉服务端消息已取走,配合auto_ack=False使用

durable持久化

防止服务端挂掉,消息未持久化,丢失durable=True

# durable=True  默认False,不会改变已声明创建过的、非持久化的队列
channel.queue_declare(queue='name1',durable=True)  # 声明队列,存在忽略,没有则创建

channel.basic_publish(exchange='',
                      routing_key="name1",
                      body=mq_message,
                      # make message persistent
                      properties=pika.BasicProperties(   
                         delivery_mode = pika.DeliveryMode.Persistent
                      ))

闲置消费

channel.basic_qos(prefetch_count=1)
channel.queue_declare(queue='name1')  # 声明队列,存在忽略,没有则创建

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

# 闲置消费,避免消费者消费满,阻塞其他消费者消费
channel.basic_qos(prefetch_count=1)
channel.basic_consume(queue='name1', auto_ack=False, on_message_callback=callback)  # 默认 auto_ack=True

全发布publish

exchange

订阅–消费者

每次运行,都会生成一个随机的queue,在rabbitmq页面上可以看到

exchange_type='fanout'

import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道 

# exchange='log'   exchange(秘书)的名称
# exchange_type=’fanout’,秘书工作方式将消息发送给所有的队列
channel.exchange_declare(exchange='logs', exchange_type='fanout')

# 随机生成一个队列
result = channel.queue_declare(queue='',exclusive=True)
queue_name = result.method.queue

# 让exchange和queque进行绑定
channel.queue_bind(exchange='logs', queue=queue_name)


def callback(ch, method, properties, body):
    print(" 消费者 Received %r" % body)

channel.basic_consume(queue=queue_name, auto_ack=True, on_message_callback=callback)  # 默认 auto_ack=True

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming() 
发布–生产者
import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道 

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

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

channel.start_consuming() 

如果上面的 订阅–消费者 代码运行了两个,那么每个订阅消费者都会收到 发布–生产者 的message

关键字发布(Routing)

exchange_type='direct' routing_key='your key'关键字分发

订阅–消费者
import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道 

# exchange='log'   exchange(秘书)的名称
# exchange_type=’fanout’,秘书工作方式将消息发送给所有的队列
channel.exchange_declare(exchange='logs', exchange_type='direct')

# 随机生成一个队列
result = channel.queue_declare(queue='',exclusive=True)
queue_name = result.method.queue

# 让exchange和queque进行绑定     # 另一个只有一个test绑定即可
channel.queue_bind(exchange='logs', queue=queue_name,routing_key='test')
channel.queue_bind(exchange='logs', queue=queue_name,routing_key='ceshi')

def callback(ch, method, properties, body):
    print(" 消费者 Received %r" % body)

channel.basic_consume(queue=queue_name, auto_ack=True, on_message_callback=callback)  # 默认 auto_ack=True

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming() 
发布–生产者
import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道

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

channel.basic_publish(exchange='logs',
                      routing_key='ceshi',   # ceshi  一个收到,test都能收到
                      body='message')

channel.start_consuming()

模糊匹配 topic *

exchange_type='topic'

old.test --  exchange  -- g1(关键字:old.*) 接收到     * 一个单词
                       -- g2(关键字:old.#) 接收到
                        
old.test.ceshi --  exchange  -- g1(关键字:old.*) 接收到
                             -- g2(关键字:old.#) 接收到   # 多个单词

订阅–消费者

import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道 

# exchange='log'   exchange(秘书)的名称
# exchange_type=’fanout’,秘书工作方式将消息发送给所有的队列
channel.exchange_declare(exchange='logs', exchange_type='topic')

# 随机生成一个队列
result = channel.queue_declare(queue='',exclusive=True)
queue_name = result.method.queue

# 让exchange和queque进行绑定     另起一个用  old.# 
channel.queue_bind(exchange='logs', queue=queue_name,routing_key='old.*')

#    另起一个用  old.# 
# channel.queue_bind(exchange='logs', queue=queue_name,routing_key='old.#')


def callback(ch, method, properties, body):
    print(" 消费者 Received %r" % body)

channel.basic_consume(queue=queue_name, auto_ack=True, on_message_callback=callback)  # 默认 auto_ack=True

print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming() 

发布–生产者

import pika

credentials = pika.PlainCredentials("rabbitmq", "mq123456")
connection = pika.BlockingConnection(pika.ConnectionParameters('192.168.1.11', 5672, '/',credentials=credentials))

# 创建一个链接对象,对象中绑定rabbitmq的IP地址
channel = connection.channel()  # 创建一个频道

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

channel.basic_publish(exchange='logs',
                      routing_key='old.test',   # 再发一次 old.test.ceshi
                      body='message')

channel.start_consuming()
  • 3
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值