1 不要开启自动确认 auto_ack=False
;
channel.basic_consume(
on_message_callback=callback,
queue="tflCarVolume2777",
auto_ack=False # 禁止自动确认消息
)
- 使用手动确认
ch.basic_ack(delivery_tag=method.delivery_tag)
2 一定要有心跳heartbeat=0
服务器会断开连接的
heartbeat=60
完整代码如下
import json
import time
import pika
import pymysql as pymysql
def db(sql):
conn = pymysql.connect(host="xxx", port=3306, user='xx', password='xxx',
database='xxx')
cursor = conn.cursor(cursor=pymysql.cursors.DictCursor)
try:
cursor.execute(sql)
conn.commit()
except Exception as e:
print("sql报错", e)
cursor.close()
conn.close()
return
def mq(callback):
# 账号密码
credentials = pika.PlainCredentials(username="xx", password="xxx")
# 连接的消息队列地址
connection = pika.BlockingConnection(
pika.ConnectionParameters(host="xxx", port=5672, credentials=credentials, heartbeat=60))
# 实例化一个对象 它回来操纵消息队列
channel = connection.channel()
# print("success")
channel.queue_declare(queue="xxx", durable=True)
channel.basic_consume(
on_message_callback=callback,
queue="xxx",
auto_ack=False # 禁止自动确认消息
)
try:
channel.start_consuming()
except Exception as e:
print("监听报错时间:", time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))
print("监听报错:", e)
# connection.close()
mq(callback)
def callback(ch, method, properties, body):
str_body = body.decode("utf-8")
# 手动确认消息
try:
ch.basic_ack(delivery_tag=method.delivery_tag)
except Exception as e:
# 处理异常
print("ack报错:", str(e))
print(f"""{time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time()))}消费者接收到了任务: {str_body}""")
str_body_dict = json.loads(str_body)
print(str_body_dict["sql"])
db(str_body_dict["sql"])
# 记录日志
with open('./277.log', 'a', encoding="utf-8") as f:
f.write(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())))
f.write(str_body_dict["sql"])
f.write("\n")
if __name__ == '__main__':
mq(callback=callback)