繁体   English   中英

使用flask服务器时,rabbitMQ的pika崩溃

[英]pika for rabbitMQ crashing while using flask server

因此,我们有一个运行中的单线程烧瓶服务器,该服务器接收来自python应用程序客户端的请求。 在此烧瓶服务器中,我们使用带有pika库的RabbitMQ将消息分发给其他客户端。 发生的是,在get函数中,程序因错误而崩溃:

pika.exceptions.ConnectionClosed:(505,'UNEXPECTED_FRAME-类60的预期内容标头,取而代之的是非内容标头框架')

我在堆栈溢出中搜索了很多与此相关的主题,但它们都解决了多线程问题,而事实并非如此。 除非在app.run(threaded = yes)中被调用,否则Flask仅应与一个线程一起使用。

在短间隔(例如每秒5条)中发送多条消息时,该程序通常会崩溃,并且还必须注意,每秒收到的消息都是对此功能的请求:

@app.route('/api/users/getMessages', methods=['POST'])  
def get_Messages():  
    data = json.loads(request.data)
    token = data['token']

    payload = jwt.decode(token, 'SECRET', algorithms=['HS256'])
    istid = payload['istid']
    print('istid: '+istid)

    messages = []

    queue = channel.queue_declare(queue=istid)
    for i in range(queue.method.message_count):
        method_frame, header_frame, body = channel.basic_get(queue=istid, no_ack=True)
        if method_frame:
            #print(method_frame, header_frame, body)
            messages.append(body)
        else:
            print('No message returned')

    res = {'messages':messages, 'error':0}
    return jsonify(res)

在此代码中,它通常在行中崩溃:

queue = channel.queue_declare(queue=istid)

但是,我们还尝试更改代码,以便在主体为None并在行中崩溃时,使用while而不是for结束代码:
在这种情况下method_frame, header_frame, body = channel.basic_get(queue=istid, no_ack=True) 同样重要的是,崩溃是随机的,它可以工作几次,然后在发送消息时在获取请求后随机崩溃。 如果有人知道与此相关的任何信息,我们将不胜感激。

另一个注意事项是,我们考虑将basic_consume与回调一起使用,而不是basic_get,但是我们没有找到一种可行的方法,因为我们必须将消息发送回去,并且有多个用户对此功能进行请求。

编辑#1:在rabbitMQ文档rabbitmq中,如果您搜索函数“ def basic_get”,您会注意到这里有一些待办事项注释以及对此的引用

由于实现细节,在执行回调之前不能再次调用此方法。

所以我怀疑这可能是正在发生的事情,但是即使是这样,我也不知道如何解决。

对于对解决方案感兴趣的任何人,就像在其他注释中一样,该程序不是线程安全的,因为从1.0版开始的flask默认使用threaded = True。
解决方案是:
1)用app.run(threaded = False)运行烧瓶
2)每当使用pika访问通道/连接时,通过实现锁定来确保程序线程安全。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM