需求 :在写的一个服务基于 Django 框架,有 http 请求的处理和监听 Kafka 的消息队列。为了解决题目提出的问题还集成了 celery,但是还没找到合适的用法。我是希望 Django 程序启动结束之后就调用我写好的创建线程或者进程的函数( Django 未启动完成运行 Kafka 监听的代码会提示未加载完成的错误)。
我现有的方案是在 celery 的 tasks 编写一个 sharetask 去执行启动监听线程的方法。然后 task 的调用写在 urls.py 。项目启动完成之后就会运行目标代码。
但是上面的方案会导致我启动线程的代码被执行两次,影响到了我监听的处理逻辑。
看到的其他方法:
所以请教各位大大有什么更好的方法?
1
janxin 2017-11-07 09:02:55 +08:00
你想把 celery 的异步动作变成同步监听?
|
2
toono OP @janxin 不是,我的想法是用 celery 启动线程去监听。如果造成了 celery 同步阻塞就不是我希望的效果了。
我的想法就是监听 Kafka 的消息,然后对消息进行处理。 集成上了 celery 可能是多余的,但是对处理这种情景没有经验,比较无头绪。 |
3
Tinet 2017-11-07 10:15:12 +08:00
http 请求的处理和监听 Kafka 的消息队列,不应该分成两个系统来完成么?
|
4
wcsjtu 2017-11-07 10:19:11 +08:00
WSGIServer 和 uwsgi 启动顺序是不一样的,middleware 在 master 中 load, 业务代码在 worker 中 load。按照你说的, 你的启动代码只能写在 middleware 所在的文件里了。
这样,就是在 master 进程里开了个线程, 你确定这是你想要的? 推荐用 celery 解决 最后一点建议, 不要在 django 全局位置开线程,django 一般都是工作在多进程模式下的。 |
5
walleL 2017-11-07 10:23:04 +08:00
消息处理独立成一个进程不好吗?
提示未加载完成错误 ——这是指 Django 的环境未初始化的报错? |
6
manzhiyong 2017-11-07 10:24:28 +08:00
你如果只是想用到 django 的 orm,那么建一个 command,按照后台进程启动就行了。
|
11
toono OP @manzhiyong Django 的 http 服务我还是要的。
|
12
pixstone 2017-11-07 10:42:28 +08:00
我们一般是开两个应用来处理。
从 kafka 收到消息后,再丢给 celery 处理,或者直接处理。 |
13
toono OP |
15
chocho 2017-11-07 10:49:45 +08:00
supervisor 另起一个进程
|
18
pixstone 2017-11-07 11:04:46 +08:00
Python GIL 就是你的瓶颈(笑,所以不开线程处理,还会影响 HTTP 部分的服务质量 。 其实可以考虑用 async 来处理。 不过我自己一直没调通。或者 stackless ( pypy 版集成了)
所以 supervisor 另起一个进程是一个最简单,性能不会有风险的解决方案。 毕竟 Python 是 Python,不是 Java 后台开一堆线程池处理的,大家都在一个 JVM 干活的模式。 |
21
wizardoz 2017-11-07 13:24:20 +08:00
如果是需要同步监听的话还是建议单独开一个进程去监听,有数据以后 POST 到 django 或者通过消息队列。
celery 的定时任务我觉得不适合这种场景。 PS:在 wsgi.py 中可以直接开线程或者进程。但是如果是我的话还是会单独另起一个程序。 |
22
clino 2017-11-07 13:35:47 +08:00
建议用 jenkins 之类的另外的工具去做
|