一、项目情况:
1.本Flask项目使用Tornado方式部署,内容放到server.py文件中
##sever.py文件
import asyncio
from tornado.ioloop import IOLoop
from tornado.wsgi import WSGIContainer
from tornado.httpserver import HTTPServer
from app import app
import nest_asyncio
nest_asyncio.apply()
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
if __name__ == '__main__':
http_server = HTTPServer(WSGIContainer(app))
http_server.listen(5500,address='127.0.0.1') # 监听5500端口
IOLoop.current().start()
2.该服务有一个接口,需要调用自定义异步方法:R.getData()
@app.route("/line/robotangle", methods=['GET'])
def getrobotangle():#获取机器人角度
requestDic = {}
robotGroupList =["RobotGroupB"] #["RobotGroupA","RobotGroupB","RobotGroupC"],目前只有B区完成
for robotgroup in robotGroupList:
ip = RobotDataCf.get(robotgroup,'ip')
hostlist = RobotDataCf.get(robotgroup,'host').split(",")
namelist = RobotDataCf.get(robotgroup,'name').split(",")
for i in range(len(hostlist)):
name = namelist[i]
url = f'http://127.0.0.1:5500/{name}'
requestDic[name] = url
result = R.getData(requestDic)####该方法为异步方法,调用后会挂N个IO请求的协程
print(result)
return jsonify(result)
3.使用Spyder的IDE运行sever.py,启动服务。使用Postman发起Get请求,一切正常,能获取到数据。
二、问题:使用命令行启动sever.py,开始报错RunTimeWarning
cd 项目目录
python sever.py
...\tornado\iostream.py:902: RuntimeWarning: coroutine 'wait' was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation ...
...
三、排查:
1.初步断定是接口要使用异步方法时,需要将接口设置为异步接口
解决方案:
a.使用flask写接口,用Tornado部署,将flask接口改写为异步调用
b.直接使用Tornado写异步接口
四、解决情况:
方案a网上资料比较少,因此使用方案b:
1.用tornado改写异步接口代码
class getrobotangle(tornado.web.RequestHandler):
executor = ThreadPoolExecutor()
@tornado.gen.coroutine #添加异步装饰器
def get(self):#获取机器人角度
requestDic = {}
robotGroupList =["RobotGroupB"] #["RobotGroupA","RobotGroupB","RobotGroupC"],目前只有B区完成
for robotgroup in robotGroupList:
ip = RobotDataCf.get(robotgroup,'ip')
hostlist = RobotDataCf.get(robotgroup,'host').split(",")
namelist = RobotDataCf.get(robotgroup,'name').split(",")
for i in range(len(hostlist)):
name = namelist[i]
url = f'http://127.0.0.1:5500/{name}'
requestDic[name] = url
result =yield self.getdata(requestDic)
print(result)
# self.write(jsonify(result))
self.write(result)
@run_on_executor
def getdata(self,requestDic):
return R.getData(requestDic)
if __name__ == "__main__":
import nest_asyncio
nest_asyncio.apply()
asyncio.set_event_loop_policy(asyncio.WindowsSelectorEventLoopPolicy())
application.listen(5500,address='127.0.0,1')
tornado.ioloop.IOLoop.current().start()