class RedisStream(object):
"""
redis 使用stream 数据结构 实现消息队列
使用消费者组模式 实现组内多个消息 分给多个不同的消费者消费
"""
def __init__(self) -> None:
self.response = {'code': 200, 'msg': '成功', 'data': None}
self.conn = redis.StrictRedis(host='127.0.0.1', port=6379)
self.stream_name = 'stream'
self.group_name = 'group'
self.consumer_name = 'consumer1'
def xadd_info(self, data):
"""添加数据到队列 设置最大长度为2"""
res = self.conn.xadd(self.stream_name, data, '*', maxlen=2)
if not res:
self.response['code'] = 500
self.response['msg'] = '失败'
return self.response
def create_group(self):
"""创建消费者组,判断消费者组是否存在"""
flag = self.check_consumer_group_exists()
if flag:
self.response['code'] = 201
self.response['msg'] = '消费者组已存在'
return self.response
else:
res = self.conn.xgroup_create(self.stream_name, self.group_name, 0)
if not res:
self.response['code'] = 500
self.response['msg'] = '创建消费者组失败'
return self.response
def consumer(self):
"""消费消息 消费完成标记信息已完成
'>' : 获取到目前为止,从未传递给其他消费者的消息,并且会更新last_delivered_id,通常都是传递这个参数
"""
response = self.create_group()
if response.get('code') == 500:
return response
while True:
res = self.conn.xreadgroup(self.group_name, self.consumer_name, {self.stream_name: '>'}, count=1)
if not res:
self.response['code'] = 404
self.response['msg'] = '当前没有可消费数据'
return self.response
for stream, data in res[0][1]:
message_id = stream.decode('utf-8')
message_data = dict()
for key, val in data.items():
message_data[key.decode('utf-8')] = val.decode('utf-8')
self.xack_stream(message_id)
def xack_stream(self, id):
"""标记消息为已完成"""
res = self.conn.xack(self.stream_name, self.group_name, id)
if not res:
self.response['code'] = 500
self.response['msg'] = '记录消息处理完成失败'
return self.response
def check_consumer_group_exists(self):
# 获取指定Stream的消费者组列表
groups = self.conn.xinfo_groups(self.stream_name)
for group in groups:
if group['name'].decode('utf-8') == self.group_name:
return True
return False
if __name__ == "__main__":
stream = RedisStream()
# print(stream.xadd_info({'name': 'gjj', 'sex': 'nv'}))
# print(stream.xadd_info({'name': 'yyy', 'sex': 'nan'}))
print(stream.consumer())
python 实现redis stream类型简单消息队列
于 2023-12-12 18:02:05 首次发布