简体   繁体   English

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

[英]pika for rabbitMQ crashing while using flask server

So we have a single thread flask server running where we receive requests from a python app client. 因此,我们有一个运行中的单线程烧瓶服务器,该服务器接收来自python应用程序客户端的请求。 In this flask server we use rabbitMQ with pika library to distribute messages to other clients. 在此烧瓶服务器中,我们使用带有pika库的RabbitMQ将消息分发给其他客户端。 What is happening is that in the get function the program is crashing with the error: 发生的是,在get函数中,程序因错误而崩溃:

pika.exceptions.ConnectionClosed: (505, 'UNEXPECTED_FRAME - expected content header for class 60, got non content header frame instead') pika.exceptions.ConnectionClosed:(505,'UNEXPECTED_FRAME-类60的预期内容标头,取而代之的是非内容标头框架')

I've searched a lot of topics about this in stack overflow and others but they all address problems with multi threading which is not the case. 我在堆栈溢出中搜索了很多与此相关的主题,但它们都解决了多线程问题,而事实并非如此。 Flask should only serve with one thread unless it is called in app.run(threaded=yes). 除非在app.run(threaded = yes)中被调用,否则Flask仅应与一个线程一起使用。

The program normally crashes when multiple messages are sent in a short interval (eg 5 per second) and it's also important to note that messages are being received every second with a request to this function: 在短间隔(例如每秒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)

In this code it crashes normally in the line: 在此代码中,它通常在行中崩溃:

queue = channel.queue_declare(queue=istid)

But we also tried to change the code to use a while instead of a for where it ends when the body is None and it crashes in the line: 但是,我们还尝试更改代码,以便在主体为None并在行中崩溃时,使用while而不是for结束代码:
method_frame, header_frame, body = channel.basic_get(queue=istid, no_ack=True) in that case. 在这种情况下method_frame, header_frame, body = channel.basic_get(queue=istid, no_ack=True) Also important, the crashes are random and it can work a few times and then randomly crashes after a get request while messages are being sent. 同样重要的是,崩溃是随机的,它可以工作几次,然后在发送消息时在获取请求后随机崩溃。 If anyone knows anything related to this we would appreciate any help. 如果有人知道与此相关的任何信息,我们将不胜感激。

Another note, we thought about using basic_consume with callback instead of basic_get but we didn't find a way in which this would work since we have to send the messages back and have several user making requests to this same function. 另一个注意事项是,我们考虑将basic_consume与回调一起使用,而不是basic_get,但是我们没有找到一种可行的方法,因为我们必须将消息发送回去,并且有多个用户对此功能进行请求。

EDIT #1: In the rabbitMQ docs rabbitmq if you search for the function "def basic_get" you will notice there are some TODO comments and also a reference to this 编辑#1:在rabbitMQ文档rabbitmq中,如果您搜索函数“ def basic_get”,您会注意到这里有一些待办事项注释以及对此的引用

Due to implementation details, this cannot be called a second time until the callback is executed. 由于实现细节,在执行回调之前不能再次调用此方法。

So I suspected that this could be what was happening but even if it is I don't know how could it be solved. 所以我怀疑这可能是正在发生的事情,但是即使是这样,我也不知道如何解决。

For anyone interested in the solution, as it is in the other comments, the program was not thread safe since flask as of version 1.0 uses threaded = True as default. 对于对解决方案感兴趣的任何人,就像在其他注释中一样,该程序不是线程安全的,因为从1.0版开始的flask默认使用threaded = True。
The solution is either: 解决方案是:
1) running flask with app.run(threaded = False) 1)用app.run(threaded = False)运行烧瓶
2) Making the program thread safe by implementing locks whenever accessing the channel /connection with pika. 2)每当使用pika访问通道/连接时,通过实现锁定来确保程序线程安全。

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

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