Uvicorn原生支持ASGI协议,专为异步应用设计,通过uvloop事件循环实现高并发I/O处理;Gunicorn基于同步WSGI协议,无法直接运行FastAPI等ASGI应用,需配合Uvicorn Worker才能间接支持。

Uvicorn原生支持ASGI协议,Gunicorn不支持
ASGI是异步应用的通信契约,它要求服务器能接收、分发和响应异步事件(比如websocket.connect或http.request),而Gunicorn的底层是WSGI——一个同步接口,它只认application(environ, start_response)这种一次调用、一次返回的模式。你硬把FastAPI应用塞给Gunicorn,默认会报错:TypeError: 'coroutine' object is not callable,因为Gunicorn试图同步调用一个async def函数。
Uvicorn从设计第一天起就只对接ASGI:它的app参数必须是ASGI callable(如app = FastAPI()),内部用uvloop驱动事件循环,每个请求进来后直接挂进异步队列,无需进程切换开销。
Uvicorn的并发模型天然适配async/await
Uvicorn默认单进程+事件循环,所有I/O等待(数据库查询、HTTP调用、文件读写)都通过await让出控制权,同一进程可同时维持数千连接。Gunicorn即使配上gevent或eventlet,也只是“伪异步”——它靠协程抢占式调度,仍受限于Python的GIL和库兼容性,且容易因阻塞调用(如requests.get())拖垮整个worker。
- 用
aiohttp+asyncpg+ Uvicorn:I/O等待时CPU空转,其他请求照常处理 - 用
requests+ Uvicorn:一个阻塞调用就卡死整个事件循环,QPS断崖下跌 - Gunicorn无论配什么worker,都无法让
async def视图真正异步执行
Uvicorn的worker模式不是“多进程替代”,而是“多核加速”
很多人误以为--workers 4在Uvicorn里和Gunicorn一样是“主从分发请求”,其实不然。Uvicorn的每个worker是一个独立的ASGI实例+独立事件循环,彼此不共享状态,也不需要主进程协调请求分发——它依赖操作系统层面的socket reuse(SO_REUSEPORT)让内核自动负载均衡。这意味着:
立即学习“Python免费学习笔记(深入)”;
- 没有Gunicorn那种master进程监听、fork子进程、再转发请求的延迟
- 每个worker内存隔离,崩溃不影响其他worker
- 但你也得自己确保应用代码无全局状态(比如缓存字典不能跨worker共享)
而Gunicorn的worker是同步的,加再多worker也解决不了单个请求里的I/O阻塞问题。
生产中别单独用Uvicorn,但别用Gunicorn跑纯ASGI应用
Uvicorn缺进程管理、健康检查、优雅重启等生产级能力;Gunicorn又没法正确启动ASGI应用。所以真实部署链路通常是:nginx → gunicorn -k uvicorn.workers.UvicornWorker——Gunicorn只当“进程看守员”,真正干活的还是Uvicorn worker。这时候你看到的gunicorn命令只是外壳,实际HTTP解析、路由、异步调度全由Uvicorn完成。
最容易被忽略的一点:如果你的应用混用了同步和异步代码(比如部分路径用def,部分用async def),Uvicorn会降级为同步处理那部分,但Gunicorn根本不会识别async def,直接报错退出。


















