Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/350.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python pika用于rabbitMQ在使用flask服务器时崩溃_Python_Python 3.x_Flask_Rabbitmq_Pika - Fatal编程技术网

Python pika用于rabbitMQ在使用flask服务器时崩溃

Python pika用于rabbitMQ在使用flask服务器时崩溃,python,python-3.x,flask,rabbitmq,pika,Python,Python 3.x,Flask,Rabbitmq,Pika,因此,我们有一个运行的单线程flask服务器,在那里我们接收来自python应用程序客户端的请求。在这个flask服务器中,我们使用rabbitMQ和pika库将消息分发给其他客户端。 发生的情况是,在get函数中,程序因错误而崩溃: pika.exceptions.ConnectionClosed:505,“意外的\u帧-应为” 类60的内容标头,取而代之的是非内容标头帧' 我在stack overflow和其他文章中搜索了很多关于这方面的主题,但它们都解决了多线程的问题,而事实并非如此。烧瓶

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

pika.exceptions.ConnectionClosed:505,“意外的\u帧-应为” 类60的内容标头,取而代之的是非内容标头帧'

我在stack overflow和其他文章中搜索了很多关于这方面的主题,但它们都解决了多线程的问题,而事实并非如此。烧瓶只能使用一根线,除非在应用程序中调用。runthreaded=yes

当在短时间间隔内(例如每秒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)
但我们也尝试将代码改为使用while,而不是a,用于当body为None且在行中崩溃时结束的位置: 方法\u帧,头\u帧,主体=channel.basic\u getqueue=istid,no\u ack=True 那样的话 同样重要的是,崩溃是随机的,它可以工作几次,然后在发送消息时在get请求后随机崩溃。如果有人知道与此相关的任何事情,我们将感谢任何帮助

另一个注意事项是,我们考虑过使用basic_consume和callback,而不是basic_get,但我们没有找到一种方法,因为我们必须将消息发送回,并且有几个用户向同一个函数发出请求

编辑1: 在rabbitMQ文档中,如果您搜索函数def basic_get,您会注意到有一些TODO注释以及对该注释的引用

由于实现细节的原因,无法再次调用此函数 直到执行回调为止


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

对于任何对解决方案感兴趣的人来说,正如在其他评论中一样,该程序不是线程安全的,因为自版本1.0起,flask使用threaded=True作为默认值。 解决办法是: 1个带app.runthreaded的流动烧瓶=假
2通过使用pika访问频道/连接时实施锁定,使程序线程安全。

您在哪里创建连接和频道对象?您当前的代码不是线程安全的。您需要检查pika是否有线程安全示例,或者在get_Messages中创建一个连接/通道。@LukeBakken我在开始时在函数外创建连接,也就是在运行应用程序时只创建一次通道。我们尝试在需要接收/发送消息的任何时候打开和关闭频道,但它仍然崩溃。然后,每当我们必须接收/发送消息时,我们也尝试打开/关闭连接。它奏效了,但我们认为它太耗费资源,而且是一个糟糕的解决办法。@eandersson你是什么意思?我们没有使用线程。据我所知,代码只在一个线程中运行,因为我们没有使用线程,也没有告诉flask在多个线程上运行。我是否做出了任何错误的假设?然后,每次我们必须接收/发送消息时,我们都试图打开/关闭连接。它起作用了…-这证明多个线程正在访问存在问题的当前代码中的连接和通道。如果打开Pika的调试输出,我想您可能会在日志消息中看到线程ID,或者可以使用自定义日志格式化程序添加该信息。