使用gunicorn+gevent+nginx
平时用django或flask写web服务时,肯定是不能直接部署默认的web server的,响应太差仅用于调试。最常用的是uwsgi+nginx,大大提升了web服务的响应能力,还可以设置许多的配置参数来实现线程缓存监听等。也曾经写过一篇关于uwsgi的:python做web开发时uWSGI和nginx的作用和区别
此外也有另一种搭配,就是gunicorn+gevent+nginx。uwsgi是用c编写的,稳定且快;gunicorn是用python写的;两者都是同步的,看到有资料提到gunicorn可以配上gevent实现异步的处理避免阻塞,gevent是基于协程的。
这里不准备记录两者的详细区别和性能比较。主要记录以django为例换成gunicorn后的一些配置。
先安装
pip install gunicorn gevent
现在可以尝试下直接用命令启动
gunicorn --worker-class=gevent API.wsgi:application --reload --bind 127.0.0.1:8001
一旦运行的配置多了后,命令就显得不太方便,于是可以创建一个配置文件,与uwsgi的ini不太一样,gunicorn可以用py,下面的基本够用了:
from multiprocessing import cpu_count
import os
current_dir = os.path.dirname(os.path.abspath(__file__))
gun_log_dir = os.path.join(current_dir, "gunicorn_log")
os.makedirs(gun_log_dir, exist_ok=True, mode=0o775)
bind = ["127.0.0.1:8001"]
daemon = True # 是否开启守护进程模式
workers = cpu_count()*2+1 # 工作进程数量
threads = 2 # 每个工作者的线程数
worker_class = "gevent" # 指定一个异步处理的库
worker_connections = 65535 # 单个进程的最大连接数
keepalive = 60 # 服务器保持连接的时间,能够避免频繁的三次握手过程
timeout = 30 # 一个请求的超时时间
graceful_timeout = 10 # 重启时限
capture_output = True # 是否捕获输出
loglevel = "debug" # 日志级别
pidfile = os.path.join(gun_log_dir, 'gunicorn.pid') # 保存gunicorn的进程pid的文件
accesslog = os.path.join(gun_log_dir, 'acess.log') # 访问日志存储路径
errorlog = os.path.join(gun_log_dir, 'error.log') # 错误日志存储路径
然后运行就换成了新命令,这里的API是指django项目目录,就是里面包含了wsgi和settings的目录
gunicorn -c guni-cfg.py API.wsgi:application
然后修改nginx.conf,加入如下部分内容
location ~ /your_link {
proxy_pass http://127.0.0.1:8001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
重启下nginx即可看到效果
nginx -s reload
不过gunicorn没有一个像样的关闭命令,没有类似uwsgi中的stop之类的,可以直接ps -ef | grep gunicorn然后杀掉进程即可。