python与RocketMQ的初次携手踩坑记录

649 阅读3分钟

背景

项目中有个需求就是采集数据通过算法分析后推送到平台,算法是独立的组件,采集也是独立的组件,平台是第三方平台,于是我选择采用消息中间件作为中间传输通信的工具,Rocketmq+python的方案。

踩坑记录

1、编写demo

生产者:

import json
from rocketmq.client import Producer, Message

producer = Producer('PID')
producer.set_namesrv_addr('localhost:9876')
producer.start()

msg = Message('test')
for count in range(1, 1000,1):
    msg_body = {'id': count}
    body = json.dumps(msg_body).encode('utf-8')
    msg.set_body(body)
    ret = producer.send_sync(msg)
    print(f'status:{ret.status}')  # 0表示OK
    print(f'msg_id:{ret.msg_id}')  # 消息id,同消费者获取到的消息id
    print(f'offset:{ret.offset}')  # 偏移量,默认从0开始,1,2。。。
producer.shutdown()

消费者:

import time
from rocketmq.client import PushConsumer,PullConsumer
def callback(msg):
    print(msg.topic,msg.id,(msg.body).decode('utf-8'))
    return PullConsumer

consumer = PushConsumer('CID')
consumer.set_namesrv_addr('localhost:9876')
consumer.subscribe('test',callback)
consumer.start()
while True:
    time.sleep(3600)
    consumer.shutdown()

分别启动生产者和消费者程序,验证成功,生产者生产消息后消费者会订阅test主题消费掉消息

2、编写业务代码

开始写业务代码,添加完业务代码后,再次启动生产者和消费者程序,出现了一个问题,由于算法分析的代码很耗GPU、CPU,而rocketmq貌似有一个机制,在设定的时间内某个消息没有消费掉就会启动重发机制,会出现重复消费的现象,于是乎现在的问题就变成解决rocketmq重复消费的问题

3、解决rocketmq重复消费的问题

由于这里rocke使用的是python语言的客户端,可以参考的例子很少,只能自己摸石头过河了。 根据rocketmq的设计原理,有一个组的概念,通俗一点讲,就是如果将消费者放到一个组里,那么这个组里的某条消息被组内一个消费者消费掉了,其他消费者就不会再去消费这个消息,这很符合我们的业务需求,通过并发处理消息提升算法处理的能力并消除重复消费。 于是乎,我在消费者程序中增加了组的概念,大致代码如下:

def callback(msg):
    data = analysis(msg)
    push_json = json.loads(data)
    resultmsg = Message('result')
    resultmsg.set_body(data)
    producer.send_sync(resultmsg)
    return 0

def messageThread():
    consumer = PushConsumer('CID')
    consumer.set_namesrv_addr('localhost:9876')
    consumer.set_group('testGP')
    consumer.set_thread_count(2)
    consumer.subscribe('test', callback)
    consumer.start()
    while True:
        time.sleep(2)
    consumer.shutdown()

4、优化整个程序

为了提升吞吐量同时提升性能,我在三台虚拟机上同时跑了同样的消费者程序,测试了多次,发现没有重复消息,同时由于rocketmq自身配置了负载均衡的算法,三台虚机上同一个组testGP中消费消息基本上达到了均衡,至此,初次用python语言写rocketmq的消费程序完成踩坑携手。

总结

语言是想通的,要有一颗敢于尝试的勇敢的心,这次业务需求在技术选型上,我有两套方案,一个是Java方案一个就是这个python方案,很多人支持我用Java方案,由于时间紧要求高,python方案大家都不熟悉,是一种冒险,但是,我是偏向于选择python方案的,因为本身算法是python写的,结合起来比较容易,所以我选择了尝试,不过确实是有风险,还好最终顺利交付,还是小有成就感的。

我们要善于去理解组件的原理,就比如说rocketmq,它的底层设计原理是怎样的,他的重复消费是怎么处理的,将这些原理理解清楚后其实技术实现就不是一个太难的问题了。