UWSGI 和 Gunicorn 比对
摘要: 本文档旨在对 PythonWeb项目 优化底层启动方式进行比较,特别是 UWSGI 和 Gunicorn。UWSGI(Universal Web Server Gateway Interface)是一种 Python Web 服务器网关接口,它可以与各种 Web 服务器结合使用,提供高效的 Web 应用程序部署解决方案。Gunicorn(Green Unicorn)是一个基于 Python 的 Web 服务器,它是一个预叉装的、多进程的 Web 服务器,专为运行 Python Web 应用程序而设计。我们将从性能、资源利用和易用性等方面对这两种启动方式进行比较。
一、引言
在 Web 应用程序的部署中,选择合适的 Web 服务器和启动方式对于性能和资源利用率至关重要。UWSGI 和 Gunicorn 是两种常用的 Python Web 服务器和启动方式,它们都提供了高效的 Web 应用程序部署解决方案。
二、UWSGI 和 Gunicorn 简介
UWSGI 是一种 Python Web 服务器网关接口,它可以与各种 Web 服务器结合使用,提供高效的 Web 应用程序部署解决方案。UWSGI 的主要优点是它的灵活性和可扩展性,它可以与各种 Web 服务器和框架结合使用,提供高性能的 Web 应用程序部署解决方案。
Gunicorn 是一个基于 Python 的 Web 服务器,它是一个预叉装的、多进程的 Web 服务器,专为运行 Python Web 应用程序而设计。Gunicorn 的主要优点是它的性能和资源利用率,它可以在一台服务器上运行多个 Python Web 应用程序,提供高效的 Web 应用程序部署解决方案。
三、性能比较
我们使用了相同的硬件配置和测试环境,对 UWSGI 和 Gunicorn 的性能进行了测试。测试结果表明,UWSGI 的性能要优于 Gunicorn,特别是在高并发和大流量的情况下。UWSGI 可以更好地利用多核 CPU 和内存,提供更高的并发处理能力和更快的响应时间。
四、资源利用率比较
我们对 UWSGI 和 Gunicorn 的资源利用率进行了测试。测试结果表明,UWSGI 的资源利用率要优于 Gunicorn,特别是在内存使用方面。UWSGI 可以更好地控制内存使用,避免内存泄漏和内存溢出等问题。
五、易用性比较
UWSGI 和 Gunicorn 的易用性都比较好,它们都提供了简单的配置和部署方式。但是,UWSGI 的配置和部署方式更加灵活,它可以与各种 Web 服务器和框架结合使用,提供更加定制化的部署解决方案。
六、结论
综上所述,UWSGI 和 Gunicorn 都是优秀的 Python Web 服务器和启动方式,它们都提供了高效的 Web 应用程序部署解决方案。但是,从性能、资源利用率和易用性等方面来看,UWSGI 更加优秀,它可以提供更高的性能和更好的资源利用率,同时也更加灵活和易于定制。因此,我们建议在优化底层启动方式时,优先考虑使用 UWSGI。
难点:
- 日志切割。
- 因为在 linux系统下,一个进程打开文件时使用的是文件系统的 inode 编号而非文件名。移动或者重命名一个文件,并不会修改它的 inode 编号。因此需要在进行 rotate 之后,通知 uwsgi 重新打开 log 文件。
- 请求队列缓存问题。 请求堆积在uwsgi 队列中。 Uwsgi 重启后 消费队列中的数据产生异常。服务进程发生变化。 需要二次验证
硬件:
- 假设服务器有 4 个 CPU 核心和 8GB 内存,以下是推荐的配置:
- 进程数:8(4 个核心 * 2 个进程/核心)
- 线程数:2(每个进程 2 个线程)
Uwsgi logto 和 logrotate 区别
配置复杂度:
logto:配置简单,直接在 uWSGI 配置文件中指定日志文件路径。 # 自己写日志轮转
logrotate:配置相对复杂,需要单独的配置文件和定期任务。 # 脱了服务。7 , 天天
功能:
logto:仅负责将日志写入指定文件,不具备轮转、压缩等功能。
logrotate:提供全面的日志管理功能,包括定期轮转、压缩、删除旧日志等。
灵活性:
logto:适用于简单的日志记录需求。
logrotate:适用于需要复杂日志管理策略的生产环境。
# 总结
使用 logto 需要编写 日志轮转 shell 代码
使用 logrotate 不需要编写 日志轮转代码
uwsgi 实现日志方式
方式一:Supervisor + uwsgi + logto
配置文件 uwsgi.ini
[uwsgi]
master = true
threaded-logger = true
chdir = /project/xxx_sys
listen = 14400
pidfile = app.pid
log-format = %(addr) - [%(ltime)] %(status) "%(method) %(uri) %(proto)" %(size) "%(uagent)"
wsgi-file = app.py
callable = app
http-socket = :5000
processes = 16
threads = 2
buffer-size = 65537
lazy-apps = true
log-master = true
logto = /project/xxx_sys/app.log
master-fifo = /project/xxx_sys/uwsgi.fifo
Supervisor 创建app服务
# vim /etc/supervisor/conf.d/app.conf
[program:app]
command=uwsgi --ini /project/xxx_sys/uwsgi.ini
directory=/project/xxx_sys
restart.sh 重构。包含:
-
git文件拉取。
-
数据库迁移。
-
log文件搬迁。
-
fifo 通知uwsgi的logto文件。
-
supervisor重启 uwsgi
-
区分 online 和 本地开发测试两种模式。本地继续使用 app.py 启动,online 使用上述流程
方式二:Supervisor + uwsgi + logoter
uwsgi.ini
[uwsgi]
master = true
chdir = /project/xxx_sys/
pidfile = app.pid
log-format = [pid: %(pid)|app: -|req: -/-] %(addr) (%(user)) {%(vars) vars in %(pktsize) bytes} [%(ctime)] %(method) %(uri) => generated %(rsize) bytes in %(msecs) msecs (%(proto) %(status)) %(headers) headers in %(hsize) bytes (%(switches) switches on core %(core))
wsgi-file = app.py
callable = app
http-socket = :88
processes = 16
threads = 8
buffer-size = 65537
enable-threads = true
listen = 1440
lazy-apps = true
reload-mercy = 1
worker-reload-mercy = 1
logto = /project/xxx_sys/log/uwsgi/app.log
log-master = true
threaded-logger = true
master-fifo = /project/xxx_sys/log/uwsgi.fifo
Supervisor 创建app服务
# vim /etc/supervisor/conf.d/app.conf
[program:app]
command=uwsgi --ini /project/xxx_sys/uwsgi.ini
directory=/project/xxx_sys/
配置 logrotate
# cd /etc/logrotate.d
# vim app
# logrotate -df /etc/logrotate.d/app 手动执行日志轮转
/project/xxx_sys/log/uwsgi/app.log {
create 0664 root root
daily
compress
delaycompress
missingok
dateext
dateyesterday
rotate 10
notifempty
sharedscripts
# 执行完毕 rotate 之后,通知 uWSGI 重新打开日志,以下两种方法任选其一
postrotate
echo l > /project/xxx_sys/log/uwsgi.fifo
endscript
}
# 手动触发日志轮转。logrotate -vf -s /project/xxx_sys/log/uwsgi/bak_log/app01.log /etc/logrotate.d/app
总结
- Flask app 服务使用 uwsgi 依托 守护运行,才能实现日志轮转。即: nohup,& , supervisor等
- Supervisor 可以实现自动重启。 可以将看门狗服务核心代码 添加到 supervisor 中管控
- 性能uwsgi 更好
- Gunicorn 和 uwsgi 。部署流程上一样。 仅配置文件不同,综合说uwsgi性能高于gunicorn
- 推荐使用 方式二 (日志轮转不自由,服务自由)。 但是 方式一 更适合目前app项目 :(日志自由,服务自由)