python--pika试用

rabbitmq--pika

任务处理:请求数量太多,需要把消息临时放到某个地方

发布订阅,一旦发布消息,所有订阅者都会收到一条相同的消息

sh 复制代码
# 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

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

单个消费者

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')  # 声明队列,存在忽略,没有则创建


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将以轮询的形式被消费

批量发送 消息测试

python 复制代码
"""
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

python 复制代码
# 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消息取走,防止客户端未处理消息,挂掉

python 复制代码
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

python 复制代码
# 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
                      ))

闲置消费

python 复制代码
channel.basic_qos(prefetch_count=1)
python 复制代码
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'

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()  # 创建一个频道 

# 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() 
发布--生产者
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.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'关键字分发

订阅--消费者
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()  # 创建一个频道 

# 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() 
发布--生产者
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.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.#) 接收到   # 多个单词

订阅--消费者

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()  # 创建一个频道 

# 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() 

发布--生产者

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.exchange_declare(exchange='logs', exchange_type='topic')

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

channel.start_consuming()
相关推荐
1nullptr2 分钟前
lua和C API库一些记录
开发语言·lua
Jerry Nan3 分钟前
Lua元表
开发语言·lua
?333339 分钟前
CTFHub Web进阶-PHP-Bypass disable_function攻略
开发语言·安全·web安全·php
所以经济危机就是没有新技术拉动增长了10 分钟前
二、javascript的进阶知识
开发语言·javascript·ecmascript
CriticalThinking19 分钟前
Pycharm不正常识别包含中文路径的解释器
ide·python·pycharm
Bubluu21 分钟前
浏览器点击视频裁剪当前帧,然后粘贴到页面
开发语言·javascript·音视频
AI人H哥会Java42 分钟前
【Spring】基于XML的Spring容器配置——<bean>标签与属性解析
java·开发语言·spring boot·后端·架构
sin22011 小时前
springboot数据校验报错
spring boot·后端·python
开心工作室_kaic1 小时前
springboot493基于java的美食信息推荐系统的设计与实现(论文+源码)_kaic
java·开发语言·美食
析木不会编程1 小时前
【C语言】动态内存管理:详解malloc和free函数
c语言·开发语言