1
coolair 2019-05-20 22:36:14 +08:00 via Android 1
用 celery 啊
|
2
im67 2019-05-20 22:51:14 +08:00 1
会不会是 flask 的多线程模式跟你要的多线程模式有区别?
|
3
1iuh 2019-05-20 23:22:07 +08:00 1
gevent
|
4
Qzier 2019-05-20 23:37:14 +08:00 1
几种解决方法:
1. 多线程,不是让你开启 flask 的多线程模式,而是用 threading 模块再开启一个线程跑你的任务 2. flask 换成 starlette,requests 换成 requests-async,全部写异步代码 3. celery |
5
Qzier 2019-05-20 23:39:17 +08:00
4. 多进程,不是 CPU-bound 任务的话没必要,多线程就可以解决了
|
6
rogwan 2019-05-20 23:43:23 +08:00 via Android 1
你这个阻塞是网络问题,不是机器性能问题。就算用 thread 消耗也不大,先优化下网络请求,不行再优化性能方面
|
7
429839446 2019-05-21 00:06:59 +08:00 1
不如 mqtt
|
8
vZexc0m 2019-05-21 11:51:19 +08:00 1
你解决的问题的思路没对。
1. 更新 GPS 数据应该采用异步定时任务实现,可用 celery 或者 dramatiq+apscheduler 实现。 2. flask 部署采用 gunicorn+gevent 实现就行了。 |
9
yuting0501 OP |
10
1iuh 2019-05-21 22:00:58 +08:00 1
楼主呀,gevent 就是最好的解决方案。 不用上 celery。。
|
11
CEBBCAT 2019-05-22 01:05:35 +08:00 via Android 1
读起来真有点头疼,我翻来覆去看了三四遍也没看太懂。
『现在遇到 requests 请求 gps 数据时候阻塞,导致网站卡顿,故想到使用 Python 的多线程解决:』 1. requests 请求数据为什么会有阻塞?调物联网服务器接口不是调个 API 吗?几百 ms 吧? 2. 网站为什么有卡顿?用户每次看网页都要从物联网服务器取数据呀?为什么不把数据准备好呢? 3. 架构不明,不知道为什么使用多线程 您可以使用 ProcessOn 绘制图片 |
12
yuting0501 OP @1iuh 感谢两次推荐,我去了解一下 gevent 用法。
|
13
yuting0501 OP @CEBBCAT 抱歉,背景可能没有交代清楚
> 1. requests 请求数据为什么会有阻塞?调物联网服务器接口不是调个 API 吗?几百 ms 吧? 这只是个 Demo,我的 Flask 网站调用物联网服务器接口,物联网服务器向 IOT 设备请求数据,IOT 设备返回给物联网服务器,物联网服务器再返回我的 Flask 网站,中间可能耗时 3、4 秒。简单来说姑且认为是一个 Requests 请求会耗时 3、4 秒。实际上即便几百 ms 也是不可接受的,requests 是阻塞请求,在此期间用户向我的网站请求网页无法得到及时响应。 > 2. 网站为什么有卡顿?用户每次看网页都要从物联网服务器取数据呀?为什么不把数据准备好呢? 可以准备好,例如在最新数据更新前先返回历史数据。但总会遇到 Requests 阻塞场景,想知道大家怎么解决。 > 3. 架构不明,不知道为什么使用多线程 简单来说,就做两件事情, 1. 运行 Flask,响应网页请求 2. 间隔 10 秒像第三方物联网服务器发起 Requests 请求 矛盾冲突: 由于 Requests 请求耗时较长,导致 Flask 程序无法及时响应网页请求。 > 为什么使用多线程? 可能用了错误的思维去解决这个问题,因为在嵌入式中,同优先级两个任务会共享 CPU 时间,时间片轮转,这样就能并行处理上述的两件事情。 |
14
CEBBCAT 2019-05-22 13:06:23 +08:00
@yuting0501 #13
1. 为什么有阻塞 噢!我现在明白多了。我想这是架构的问题——不知道架构这个取词是否洽当——,要是我来开发不会让数据每次都要这么走一遍的,各个节点都会有缓存 /数据库。要是换成 NBIOT 那种网络,你可能就不会让数据这么走了,嘻嘻。 2. 可是使用缓存,但想问问大家怎么最优地解决 Requests 阻塞 『总会遇到 Requests 阻塞场景』,在 Web 服务器(也就是 Flask 吧?)每秒更新一次数据,用的时候直接用 Web 服务器上积累下来的数据,这和普通的页面速度就一样了吧? 我的意思可能是……解耦? 3. 现在是什么架构? 我想前两问可以体现我的思想了,再多的俺也不会了 |
15
yuting0501 OP @1iuh 再次感谢,gevent 是正确的解决方案。
总结一下这个问题,用 threading 是不对的,Python 中的 threading 没有优先级区分,也就是说执行到 B 线程的 requests 耗时请求,CPU 还是会死等。同时 Python 的 threading 不能被销毁、停止、暂停、恢复或中断。 什么情况下用 threading? 当你每个 thread 中的任务的每行代码都是在干实事,没有等待、睡眠等无意义操作时可以用 threading。 目前还在看资料,想搞懂有了 async 后是否还有使用 celery 和 gevent 的必要以及它们的区别。 参考资料: https://docs.python.org/zh-cn/3.6/library/threading.html |