uwsgi服务速查手册

1. UWSGI简介

uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。
WSGI / uwsgi / uWSGI 区分。

  • WSGI是一种通信协议。
  • uwsgi同WSGI一样是一种通信协议。
  • 而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。

uwsgi协议是一个uWSGI服务器自有的协议,据说该协议大约是fcgi协议的10倍那么快。它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。

但是为什么有了uWSGI还需要nginx:

一种情况,本地有多个 web 服务,有 Python、php、java 编写的,都想监听 80 端口,这个时候就必须有一个负责转发的服务了。

如果本机确定只跑这一个服务,但是 uwsgi 和 gevent 对于静态资源处理的并不是很好,一是性能问题,二是各种 HTTP 请求缓存头,处理的也没有 Nginx 完善。

然后还有一些安全问题,Nginx 作为专业服务器,暴露在公网相对比较安全(虽然有著名的心血漏洞),uwsgi 和 gevent 的话,漏洞恐怕只比 Nginx 多而不是少。

再来就是支持的协议,uwsgi 和 gunicon 早期是不支持 https 的,只能提供 http 给浏览器访问。虽然现在这两者都支持了,但是以后的 spdy 和http2,恐怕也是 nginx 跟进更快一些。

还有一些运维优势,比如服务器被人 CC,这是一种非常常见的情况,nginx 可以比较方便的把一些 IP 加入黑名单,直接改配置文件就好了。要是 uwsgi 或者 gunicorn,恐怕还要修改自己应用的代码,把 IP 过滤写进去。

这只考虑单台机器的情况,但是如果不考虑的话,那一个 nginx 做负载均衡那就几乎是必须了。

2. UWSGI常用参数介绍

接下来会列出一些比较常用的配置参数

pythonpath=/xxx/xxx # 指定项目目录
home=/xxx/xxx # 指定虚拟环境变量
wsgi-file=xxx # 指定加载WSGI文件
socket=xxx # 指定uwsgi的客户端将要连接的socket的路径(使用UNIX socket的情况)或者地址(使用网络地址的情况)。
callable=xxx # uWSGI加载的模块中哪个变量将被调用
master=true # 指定启动主进程
processes=4 # 设置工作进程的数量
threads=2 # 设置每个工作进程的线程数
vacuum=true # 当服务器退出时自动删除unix socket文件和pid文件
logfile-chmod=644 # 指定日志文件的权限
daemonize=%(chdir)/xxx.log # 进程在后台运行,并将日志打印到指定文件
pidfile=%(chdir)/xxx.pid # 在失去权限前,将主进程pid写到指定的文件
uid=xxx # uWSGI服务器运行时的用户id
gid=xxx # uWSGI服务器运行时的用户组id
procname-prefix-spaced=xxx # 指定工作进程名称的前缀

3. 示例配置

我的SlQ Blog的示例配置:

[uwsgi]
pythonpath = /home/www/SlqBlog2 # 指定项目目录
home= /home/www/SlqBlog2/venv # 指定python虚拟环境
wsgi-file = /home/www/SlqBlog2/manage.py # 指定加载的WSGI文件
callable=app # 指定uWSGI加载的模块中哪个变量将被调用
master=true # 启动主线程
processes=4 # 设置工作进程的数量
threads=2 # 设置每个工作进程的线程数
max-request = 2000 # 设置最大请求数
socket = 127.0.0.1:3031 # 指定socket地址与ngnix对接
chmod-socket = 777 #设置socket文件权限
vacuum=true # 当服务器退出时自动删除unix socket文件和pid文件
daemonize= /home/www/log/uwsgi.log # 进程在后台运行,并将日志打印到指定文件
pidfile= /tmp/slqbloguwsgi.pid # 在失去权限前,将主进程pid写到指定的文件

4. 管理uwsgi服务

4.1 运行

前台运行:

uwsgi --ini /home/www/SlqBlog2/slqblog_uwsgi.ini

后台运行:

uwsgi --ini /home/www/SlqBlog2/slqblog_uwsgi.ini --daemonize /home/www/log/uwsgi.log

4.2 重启

对于已经设定pid进程的的可以:

# 使用kill指令优雅的重启
kill -HUP `cat /tmp/slqbloguwsgi.pid`
# 或者用--reload参数
uwsgi --reload /tmp/slqbloguwsgi.pid
# 又或者对于已经设定touch-reload的文件
touch /tmp/somefile

在Python指令中亦可以:

uwsgi.reload()

4.3 停止服务器

如果出于某些原因,你让uWSGI进程在前台运行,那么使用CTRL+C就可以停止它了。
在处理后台进程时,你将需要再次使用master pidfile的SIGINT信号将会杀死uWSGI.

kill -INT `cat /tmp/slqbloguwsgi.pid`
# 或者方便使用:
uwsgi --stop /tmp/slqbloguwsgi.pid

5. 参考