Docker+Rabbitmq实现消息对列

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也都添加了参数,万事大吉

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值