用 Celery 前:
1. 用户发请求
2. 服务端接受处理
3. 服务端处理(花很长时间)
4. 用户收到结果
用 Celery 后:
1. 用户发请求
2. 服务端把接受请求
3. 服务端把要处理的函数以及参数丢到 task queue,并获得一个 task id (很快)
4. 用户收到 task id(您的请求已受理,但是还没有完成,但你可以用 task id 来查询结果,如果你不需要知道执行结果的话就不用再查了)
用户发多少请求用户说了算,但是具体什么时间真正处理这个请求里的操作服务端说了算。celery 比较适用于比较慢(不管是慢在 I/O 还是慢在 CPU )的操作,这种操作用户并不急着要结果,但是他在乎的是服务端收到这个请求,并且会在一定时间后完成这个操作。
如果是一个几秒内(不会积压一堆)就可以完成的慢操作,慢在 I/O 同时用户急着要(客户端同步在等待)
,那服务端用 asyncio 就可以同时更好支持多个用户并发,并不一定要用 celery, 用 celery 的话比较重了没必要。你说的数据库并发应该用 asyncio 去解决,可以理解为同一个进程内部做了个 celery 但是只适用于 I/O 慢的场景。如果不想写 asyncio 代码,只想写同步代码,那用 gevent 也可以。asyncio 的本质是把一个 blocking (阻塞) 的动作转换成 non-blocking (非阻塞):需要等待的时候不要让调用者等待,而是直接告诉调用者你先忙别的我还要一会儿才完事儿。
> 用户不用等待,结果执行完会通知用户。
通知这个过程默认是不存在的,还是得请求发起方凭 task id 去查询结果。或者实现一个对应的 [backend](
https://docs.celeryproject.org/en/stable/internals/reference/celery.backends.rpc.html) 让 celery 通知到这个地方。