step1
按照这个牛逼的教程配置docker+rabbitmq
备注这里开的外部连接的端口是5271,15672是rabbitmq自带的管理界面,5271是ssl端口.
有一个坑就是java那里,自己在虚拟机按教程装好后,第二天虚拟机打不开了一直不停的登录,后来按Ctrl+F1到F6进入到终端,找到昨天修改的/etc/profile文件还原才开机,还好服务器上有人已经搭好了
mqtt是rabbitmq的一个插件,使用方法略有不同,这里没有使用,但是可以学习
step2
按照这个复制好pika代码
这里使用的是fanout的代码
step3
基本搞定,几个问题:
Q1:ConnectionResetError: [Errno 104] Connection reset by peer
隔一段时间没法数据就给我这样了
在try…exception里报错后执行再次连接rabbitmq并创建队列,本地测试是不影响消费者接收的,今天开一晚上测一下,开一天一夜了 ,无误!
Q2:pymysql 读取数据以json的形式传输,为什么网上那么多自己写函数解决的
import pymysql
import json
db = pymysql.connect(host="ip", user="user", password="pwd", port=3306,
db="database", cursorclass=pymysql.cursors.DictCursor)
cursor = db.cursor()
sql = "select * from table"
cursor.execute(sql)
result = cursor.fetchall()
for i in result:
data = json.dumps(i)
print(data)
print(type(data))
cursorclass=pymysql.cursors.DictCursor加json.dumps直接就可以搞定
生产者
import pika
import time
import datetime
import pymysql
import json
'''
rabbitmq pika生产者
'''
# 远程rabbitmq服务的配置信息
username = 'name' # 指定远程rabbitmq的用户名密码
pwd = 'pwd'
ip_addr = "ip"
port_num = port
# 消息队列服务的连接和队列的创建
credentials = pika.PlainCredentials(username, pwd)
connection = pika.BlockingConnection(pika.ConnectionParameters(ip_addr, port_num, '/', credentials))
channel = connection.channel()
# 创建一个名为balance的队列,对queue进行durable持久化设为True(持久化第一步)
channel.queue_declare(queue='balance', durable=True)
while True:
try:
db = pymysql.connect(host="", user="", password="", port=,
db="",cursorclass = pymysql.cursors.DictCursor)
cursor = db.cursor()
sql = "select * from where is null"
cursor.execute(sql)
result = cursor.fetchall()
if len(result) == 0:
print(f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}: No data to send")
db.close()
time.sleep(20)
continue
id_ls = []
for col in result:
id_ls.append(col["id"])
message_str=json.dumps(col)
channel.exchange_declare(exchange='amq.fanout', durable=True, exchange_type='fanout')
channel.basic_publish(exchange='amq.fanout', routing_key='', body=message_str,
properties=pika.BasicProperties(delivery_mode=2))
print(f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}:{message_str}发送成功")
if len(id_ls) == 1:
update_sql = "update set =1 where id={}".format(id_ls[0])
else:
update_sql = "update set =1 where id in {}".format(tuple(id_ls))
cursor.execute(update_sql)
db.commit()
time.sleep(5)
except Exception as e:
connection.close() # 关闭消息队列服务的连接
print(f"{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')} error:", e)
credentials = pika.PlainCredentials(username, pwd)
connection = pika.BlockingConnection(pika.ConnectionParameters(ip_addr, port_num, '/', credentials))
channel = connection.channel()
# 创建一个名为balance的队列,对queue进行durable持久化设为True(持久化第一步)
channel.queue_declare(queue='gps_data', durable=True)
continue
消费者
import pika
import datetime
import json
'''
pika 消费者
'''
# 远程rabbitmq服务的配置信息
username = ''
pwd = ''
ip_addr = ""
port_num =
credentials = pika.PlainCredentials(username, pwd)
connection = pika.BlockingConnection(pika.ConnectionParameters(ip_addr, port_num, '/', credentials))
channel = connection.channel()
# 消费成功的回调函数
def callback(ch, method, properties, body):
print(" [%s] Received %r" % (time.time(), body))
# time.sleep(0.2)
# 开始依次消费balance队列中的消息
channel.basic_consume(queue='gps_data', on_message_callback=callback, auto_ack=True)
print(' [*] Waiting for messages. To exit press CTRL+C')
channel.start_consuming() # 启动消费
================================ 分割线 ================================
由于业务需要,消息不需要持久化,找了半天,没一个有用的教程,还好同事发来这位大哥的教程
根本不用 敲啥代码,直接在rabbitmq的管理界面操作即可
先新创建一个队列,这里设置x-message-tll就行,20000代表20s后自动删除消息
然后去交换机里绑定一下队列
最后代码里的channel.queue_declare(queue='gps_real', durable=True,arguments={"x-message-ttl":20000})
和channel.exchange_declare(exchange='amq.fanout', durable=True, exchange_type='fanout',arguments={"x-message-ttl":20000})
都加上x-message-ttl,用上面的代码就可以了
注意
这里交换机和队列都设置ttl,不确定是否都需要设,时间问题,都设了发现也没问题,不影响,所以代码里的quene_declare和exchange_declare也都添加了参数,万事大吉