https://github.com/abersheeran/zibai
相比于 gunicorn ,兹白的性能更好,并且可以在 Windows 上直接使用。
相比于 waitress ,兹白在不使用 gevent 时单进程性能与它相当,在重载情况下比 waitress 更稳定。兹白可以和 gevent 一起使用,并内置了多进程模式。
兹白还内置了子进程卡死检测,保证了在子进程意外卡死时能得到妥善处理,保证业务稳定。支持了 HUP 、TTIN 、TTOU 信号用于管理子进程,支持零停机更新。使用了 h11 这一被 uvicorn 、httpx 、hypercorn 等库广泛使用的解析器,确保了 HTTP 协议的正确性。
具体性能测试数据可以查看仓库中的 benchmark 文件。已经在一些公司业务(主要是朋友们的公司业务)上稳定运行,效果良好。还有朋友说运行起来子进程处理请求的均衡性要比 gunicorn 更好。欢迎大家尝试、反馈问题。
因为兹白是我在维护 uvicorn 时的想法,所以兹白里的多进程管理器我提交 PR 到了 uvicorn 上,这也是 tiangolo 向我捐赠 1000 美金时提到的 PR ,可谓价值千金😝。
兹白的名称受 gunicorn 、uvicorn 命名的影响,它们都是 unicorn (独角兽)的变种。《山海经》中提到“中曲之山有兽焉,其状如马而白身黑尾,一角,虎牙爪,音如鼓音,其名曰駮,是食虎豹,可以御兵”,《逸周书·王会》又有记载“正北方义渠以兹白,兹白者若白马。锯牙,食虎豹”。所以可以认定兹白就是駮这种长相类似于独角兽的别名,由于駮的名字在 pypi 上已经被使用,于是用了兹白。
1
FanyFull 236 天前 via Android
赞一个先。得空仔细研习一波。
|
2
dayeye2006199 236 天前
好奇贵司是做什么业务的,有自研这方面基础软件的需求
|
3
shinession 236 天前
先 star, 我有用 uvicorn 启动 fastapi, 有机会试试 op 的
|
4
iorilu 236 天前
既然叫中文拼音
不如干脆用 dujiao 或 dujiaoshou 算了, 好记点 |
5
imzcg2 236 天前
不支持 fastapi
|
6
abersheeran OP @shinession #3
@imzcg2 #5 fastapi 用的 ASGI ,还是用 uvicorn 启动吧。兹白好用的几个特性,一部分已经在 PR 里等合并,一部分正在提交到 uvicorn 的路上。如果用 flask 、django 之类的,再考虑用兹白。 |
7
shinession 236 天前
@abersheeran 刚注意到是 WSGI, 那确实不支持 fastapi, 为什么不做 ASGI? flask 有点老了, django 也支持 ASGI 了
|
8
abersheeran OP @shinession 同步+gevent 生态还是比较无敌的,kui.wsgi 用来跑模型比 fastapi 香多了。
|
9
so1n 235 天前
@shinession #7 老不代表不好用啊,gevent+flask 爽多了
|
10
shinession 235 天前
@so1n gevent 没用过, 不过 flask 用了有 2 年, 简单是够简单, 个人感觉比起 fastapi 还是少点东西
|
11
abersheeran OP @shinession #10 速来试试 https://kui.aber.sh/wsgi/ 。对于代码能力良莠不齐的团队来说,同步代码要比异步代码更好。新手用 asyncio ,确实是会经常写出来阻塞 loop 的程序。gevent 可以低成本甚至零成本提高同步代码的并发能力,这一点远比 asyncio 强。
|
12
shinession 235 天前
@abersheeran #11 回不去了, 架构不能乱改, 团队不是新手, asyncio 问题不大
|
13
founddev 235 天前
建议 wsgi+asgi 都支持才有点吸引力,否则一般做业务还是选择 gunicorn+gevent 或者 uvicorn 这种比较成熟的。从个人角度还是可以尝试一下的。
|
14
abersheeran OP @founddev #13 ASGI 有 uvicorn ,我都在维护 uvicorn 了也没必要新开一个项目来对着干。兹白主要解决的就是现有 WSGI 服务器的一些痛点。
|
15
hutoer 232 天前
测试了下,性能不行呀
测试环境 OS: Manjaro Linux 23.1.4 kernel: Linux 6.6.25-1-MANJARO x86_64 CPU: i5-7500 MEM: 64 GB example.py 是 github 中的例子 zibai v0.10.2 $ python -m zibai example:app --max-workers=1000 --no-access-log $ wrk -t 8 -c 40 -d 10 http://127.0.0.1:8000 Running 10s test @ http://127.0.0.1:8000 8 threads and 40 connections Thread Stats Avg Stdev Max +/- Stdev Latency 43.96ms 1.94ms 60.47ms 82.18% Req/Sec 113.99 12.51 151.00 48.62% 9087 requests in 10.02s, 0.92MB read Requests/sec: 907.12 Transfer/sec: 94.25KB $ waitress-serve --port=8000 --threads=1000 example:app $ wrk -t 8 -c 40 -d 10 http://127.0.0.1:8000 Running 10s test @ http://127.0.0.1:8000 8 threads and 40 connections Thread Stats Avg Stdev Max +/- Stdev Latency 4.39ms 5.26ms 155.57ms 98.47% Req/Sec 1.25k 282.07 4.03k 81.15% 99653 requests in 10.10s, 13.97MB read Requests/sec: 9867.04 Transfer/sec: 1.38MB $ gunicorn example:app -k gevent --threads=1000 $ wrk -t 8 -c 40 -d 10 http://127.0.0.1:8000 Running 10s test @ http://127.0.0.1:8000 8 threads and 40 connections Thread Stats Avg Stdev Max +/- Stdev Latency 9.01ms 12.99ms 146.36ms 89.27% Req/Sec 1.08k 542.24 3.90k 74.09% 86008 requests in 10.01s, 14.03MB read Requests/sec: 8589.42 Transfer/sec: 1.40MB |
16
abersheeran OP @hutoer #15 我看 gunicorn 你开 gevent 了,你装 zibai 的时候带上 gevent 了吗?看启动日志,里面会显示是否启用了 gevent 。
|
17
abersheeran OP @hutoer #15 https://github.com/abersheeran/zibai/blob/main/benchmark.md GitHub 上我的测试结果和你这个差别有点大
|
18
hutoer 232 天前
@abersheeran 启用的。
python -m zibai example:app --max-workers=1000 --no-access-log 2024-04-10 14:35:44,944 INFO Listening on 127.0.0.1:8000 2024-04-10 14:35:45,037 INFO Using gevent for worker pool 2024-04-10 14:35:45,038 INFO Run in single process mode [268033] |
19
abersheeran OP @hutoer #18 那有点怪了,我一会用一个低配 Linux 测一下
|
20
abersheeran OP @hutoer #15
找了一台低配 Linux 服务器跑测试,我发现 -t 8 -c 40 吃不满单核 CPU ,换了一个更高的参数跑。并发更大的是 gunicorn+gevent 但是看这个数据来说,zibai 的平均请求耗时明明更短,方差更小、最大值也更小。总体并发不知道为什么还没 gunicorn 高,我再深入研究一下。可能 gunicorn 对 Linux 做了针对性优化,毕竟我放在 GitHub 上的 benchmark 来自一台 MacBook ,而那个结果是反过来的,zibai 远高于 gunicorn 。 ./wrk -t 16 -c 160 -d 1000 http://127.0.0.1:8000 Running 17m test @ http://127.0.0.1:8000 16 threads and 160 connections ^C Thread Stats Avg Stdev Max +/- Stdev Latency 200.00ms 263.38ms 1.47s 81.44% Req/Sec 715.51 0.98k 6.19k 86.00% 254899 requests in 46.36s, 41.57MB read Requests/sec: 5498.37 Transfer/sec: 0.90MB ./wrk -t 16 -c 160 -d 1000 http://127.0.0.1:8000 Running 17m test @ http://127.0.0.1:8000 16 threads and 160 connections ^C Thread Stats Avg Stdev Max +/- Stdev Latency 52.27ms 9.08ms 198.67ms 88.68% Req/Sec 191.78 23.24 262.00 79.09% 90721 requests in 29.83s, 9.18MB read Requests/sec: 3041.02 Transfer/sec: 315.20KB |
21
abersheeran OP @abersheeran #20 查到了,gunicorn 一开 gevent ,连 http 都不自己处理了,全丢给 gevent ,gunicorn 就只管进程。zibai 的用法是只用 gevent monkey patch 。gevent.wsgi 在 Linux 上比 zibai.h11 快的原因还得再查查。
|
22
fzzff 230 天前
https://github.com/emmett-framework/granian 这个也可以了解下, rust 开发性能也不错
|