自己学习Flask+Gevent, 做了一个小接口服务器, 但在收到请求后, 打印请求的报文, 并返回正确格式, 运行后会出现收到请求消息后,Flask卡住无响应的的问题, 有时候点击ctrl+C才能继续执行, 网上找过很多方法, 但最后从http.server这个框架中找到了灵感, 因为http.server中如果获取报文时, 同样会出现卡住, 或处理等待30s以上才能响应, 针对Flask, 我也用了相同的思路, 果然速度快了, 也不卡和无响应了.
代码如下:
@app.route('/alert', methods=['POST']) def req_alert(): print('---------------------') print(request.headers) if request.data == b'': print('请求数据格式为空!') abort(401) if request.is_json: req_str = request.data[0:int(request.content_length)] req_data = json.loads(req_str, encoding='utf-8') print_req_data(req_data) else: print('请求数据格式不是Json格式') abort(401) print('--------------------- ') headers = request.headers try: if req_data['action'] != 'alert' and req_data['action'] != 'alert_release': abort(401, 'Invalid action') if headers['message-type'] != 'alert': abort(401, 'Invalid message-type') alert_id = req_data['alert_id'] res_data = { 'result_code': '1', 'result_desc': 'Success', 'timestamp': int(time.time()), 'data': {'alert_id': alert_id} } return res_data except KeyError: abort(401, 'Invalid req data') except Exception as e: abort(401, 'Invalid req data')
重点在获取报文时是先获取request.content_length, 在通过报文长度直接从request.data中截取有效的信息长度即可. 这样处理速度加快, 也没有再出现卡住的现象. 为什么直接调用request.data, 或request.get_json或其他方式会有卡住的情况, 我具体没有研究, 我个人怀疑是请求的报文信息中除了有效长度内容外, 还有其他信息会占用缓存导致. 写的肤浅, 还请大神指点.
补充:
经过自己一段时间的验证和实践, 上面的方法, 确实可以解决一部分的卡顿的原因. 但真正卡顿的原因还是跟CMD执行有关. 上网查了一些资料, 解决方式如下:
1. 打开CMD命令行窗口
2. 在右击窗口栏, 选择默认项
3. 取消勾选快速编辑功能
4. 保存.
好多CMD执行脚本时会卡住大多数都是因为这个功能引起的. 希望大家能借鉴.