请教下, flask 中的任务如何用多线程/多进程处理(能提高处理器利用效率的方法都行)

2020-03-09 17:15:48 +08:00
 asd648299819

这几天在学习怎么用 flask 搭建一个 api,现在成功搭建了,但是对系统性能的利用率让我有点不满意,每秒只能处理三个请求,但是 cpu 的利用率还没到 20%,内存占用也十分低,所以我感觉应该是单线程 /单进程的锅


我从一开始的直接 app.run 到后来的使用 gevent.pywsgi 中的 WSGIServer 再到使用 gunicorn 开启多进程和多线程,性能利用率一直不超过 30%,所以很让我纠结,特此来请教一下大佬们

screen gunicorn --threads 8 -w 3 -b 0.0.0.0:2333 flask_test:app

这是我的 gunicorn 启动代码,但是实测跟用 WSGIServer 的性能差不多。


以下是我程序的代码

@app.route('/api', methods=['POST'])
def post():
    a = request.form['a']
    b = request.form['b']
    try:
        caculate = api.Caculate(a, b)
        result, time = caculate.start()
        recognize_info = {'time': time, 'result': result, 'success': 1}
        return jsonify(recognize_info), 200
    except:
        recognize_info = {'message': '计算程序出错', 'success': 0}
        return jsonify(recognize_info), 200

主要花费的时间都在计算那一步,所以我在想有没有什么方法可以在 flask 的任务里使用多线程,目前我的想法是使用 queue 队列,但是不知道该如何对应返回,请大佬们讲解讲解

5587 次点击
所在节点    Python
16 条回复
tmackan
2020-03-09 17:34:00 +08:00
性能利用率一直不超过 30%?? 你压测没到极限吧?
flask 多任务?flask 可以和 celery 结合

api 服务的话,一般都是
1.调 wsgi 配置
2.业务优化 比如增加缓存
3.加机器配置

py 高并发其实一般,qps1500 已经很多了
misaka19000
2020-03-09 17:40:17 +08:00
你是怎么压测的?
RedisMasterNode
2020-03-09 18:25:31 +08:00
运行期间 ps 检查进程情况,判断是否正常”运行“
压测期间 top 检查进程占用资源的情况
运行没有问题的话检查每个进程占用了多少资源,其实你写明--threads 8,你的机器是什么样的配置?每个进程处理请求可以让单个进程跑到 100%吗?如果单个可以再考虑多个?

(另外想要吃满资源好像还是应该用多进程? GIL ?)
superalsrk
2020-03-09 18:40:48 +08:00
guicorn
superalsrk
2020-03-09 18:41:40 +08:00
gunicorn -k gevent 试试这个?
YUX
2020-03-09 18:45:45 +08:00
1. 你可以改用 aiohttp
2. 可以看一下 meinheld
asd648299819
2020-03-10 00:10:03 +08:00
@misaka19000 本地多线程请求服务器,开了 50 个线程后服务器的返回已经比正常慢很多了,再加也没有意义了,然后再看服务器上的 flask 的 debug,每个请求的处理时间都是 0.3ms 左右
asd648299819
2020-03-10 00:20:50 +08:00
@tmackan
1. 调 wsgi 配置是不是就是调整 gunicorn 的参数呀?
2. 只是一个计算任务,看 celery 需要中间件,并不想那么麻烦,增加缓存也意味着要弄个数据库吧?因为我没学过数据库感觉这里又是一个大坑。
3. 加配置我试过了,目前在 1h2g5m 上运行的效率和在 2h4g1m 上的效率一致,所以我认为是我的代码问题而不是机器性能问题。
Eds1995
2020-03-10 11:11:10 +08:00
用这个试试 gunicorn -w 3 -k gevent -b 0.0.0.0:2333 flask_test:app
asd648299819
2020-03-10 17:32:38 +08:00
@Eds1995
使用了,发现在压测下计算成功率会降低很多,反而不如使用 gevent.pywsgi 中的 WSGIServer
triangle111
2020-03-11 17:58:19 +08:00
不用 gevent 和 gunicorn,试试 app.run(threaded=True)?
lithbitren
2020-04-02 02:13:41 +08:00
app.run(processes=os.cpu_count())试试?
hl0832
2020-04-06 22:03:06 +08:00
你这几乎都是计算过程( cpu 密集),多线程下 GIL 会使效果大打折扣~
asd648299819
2020-04-08 21:39:25 +08:00
@hl0832
那该咋办呀?求指教
RyougiShiki
2020-04-10 11:48:56 +08:00
flask 内不要开多线程。gunicorn 起 2-4 个进程在不同端口(每一个 gunicorn 进程不必多线程多 worker), 前面 nginx 负载均衡。
asd648299819
2020-04-12 22:28:21 +08:00
@RyougiShiki
谢谢指点,这是利用多机器来满足计算需求吗

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/651258

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX