各位好,小白(并不懂 Full Stack 和其他网络相关技术)在用 Flask 写一个很小的 web App 的时候有一些架构和技术上的疑问,请求帮助和解答。
这个 Web App 很简单,是这样的。
这三个程序 A ,B 和 C ,每一个用 Python 看起来都不难写。但是怎么把这三个东西有机结合起来,并且(用 gunicorn ?)部署,我有些困惑。原本觉得这不就是三个 thread 或者三个 process 么,放到 flask Python app 里,flask run 的时候这三个 thread 同时 asyn 的运行。但是看到 flask 本身在(用 gunicorn ?)部署的时候似乎不是很支持自定义的 async 的东西,似乎也不支持另外单独开一个 thread ,始终运行一个任务,就不是很清楚怎么把这三个东西揉在一起了。
请有经验的同学给一些建议,谢谢。
![]() | 1 ipwx 2022-02-03 00:30:58 +08:00 ![]() 1. Python 没有真多线程,所以你这三个程序要多进程。 2. 不需要愣是结合,单独运行 A 不香嘛? 3. 至于 B ,你这 summary 丢进 redis 呗。 |
2 NLL 2022-02-03 00:48:40 +08:00 via iPhone ![]() flask apscheduler 是不是可以实现? |
3 0ZXYDDu796nVCFxq 2022-02-03 01:22:15 +08:00 ![]() 3 个线程也可以的,只要性能满足要求 不过实际应用中最好是分开 3 个进程,一套代码,多个 app 启动不同功能,这样写代码和部署起来都简单多了 |
4 dayeye2006199 2022-02-03 02:37:23 +08:00 ![]() 分成 3 个部分比较好。 a. 一个数据库 -- 这个负责不同程序之间的数据交换和存储 b. 一个 celery 应用 -- 负责 1 和 2 这两个定时任务( https://docs.celeryproject.org/en/stable/userguide/periodic-tasks.html )。生成的 summary 写入 a 的数据库,加上一个生成时间戳;做的粗糙一点,甚至不用 celery 这样的任务队列,直接用 crontab 也可以(但需要处理失败重试等问题) c. 一个 flask 应用 -- 用户请求来了之后,负责去 a 里面的数据库,查出最新的 summary 返回给用户 |
![]() | 5 Livid MOD PRO ![]() |
![]() | 6 leimao OP @ipwx 感谢。 1. 至少对程序 A 和 B 而言,他们不怎么吃资源,所以用三个假线程也无尚大雅。 2. 目前我的确是在单独运行 A 。但是 B 和 C 必须“有机”的结合起来,这样效率可以高一些。不然最蠢的办法就是 B 定期往硬盘写个东西,C 再往硬盘里读。但是这样有点蠢。 3. 我看看 Redis 这个东西是干什么的。 |
![]() | 7 leimao OP @zhijiansha 谢谢,我看看。 |
![]() | 9 leimao OP @dayeye2006199 感谢。感觉光靠数据库来进行数据交换有点不好。比如说有 1000 个用户同时请求同样的 summary ,这个数据库得被 query 1000 次,这样肯定不如直接从内存里直接读 summary 效率来的高? |
![]() | 11 Livid MOD PRO 如果涉及下面这些需求和场景的,基本上你都可以放心地用 Redis: 1. 程序生成的结果,丢了也没关系(可以再由程序生成) 2. 生成过程很复杂,但是一旦生成结束,可能会被不同的上下文反复使用 3. 容量超过 1M 的复杂数据结构 4. 没有必要一直存储的,可以给数据设置自动过期时间 |
![]() | 12 plko345 2022-02-03 10:26:39 +08:00 via Android 我之前也这样需求,用多进程库实现 |
![]() | 13 plko345 2022-02-03 10:28:33 +08:00 via Android 当时也考虑过 redis 什么的,但自己的东西不大,不想引入太多第三方工具,就自己实现了 |
![]() | 14 way2explore2 2022-02-03 11:29:56 +08:00 |
![]() | 15 ch2 2022-02-03 11:39:47 +08:00 守护进程+内存缓存+定时任务 |
16 dayeye2006199 2022-02-03 11:40:48 +08:00 @leimao 1000 Read QPS 对正常的数据库都是毛毛雨;内存读写引入 redis memcache 这样的,也会徒增复杂度。 |
![]() | 17 leimao OP @plko345 程序 B 和 C 的交互,似乎还是需要依赖第三方的东西来实现。除非你像之前的朋友说的,程序 B 把 summary 写到 database 里去,然后程序 C 每次被请求就去 database 里找 summary 。但是我之前也提了一下这么做有点浪费读写和计算。 |
![]() | 18 leimao OP @dayeye2006199 好的,谢谢你的建议。 |