安装需要的包
yum install python3
yum install nginx
yum install gunicorn
pip install gevent
pip install supervisor
gunicorn的简单使用,在服务器上任意一个位置新建一个python文件, 文件名自己定义:
vi testgunicorn.py
# 在testgunicorn.py中输入以下内容
def app(environ, start_response):
data = b"Hello, World!\n"
start_response("200 OK", [("Content-Type", "text/plain"),("Content-Length", str(len(data)))])
return iter([data])
使用gunicorn运行testgunicorn.py, 在testgunicorn.py文件的当前目录输入下面命令:
gunicorn -w 2 -b 0.0.0.0:18000 testgunicorn:app
在浏览器输入 外网ip:端口 , 如果出现"Hello, World!"即表示gunicorn正常
配置nginx文件
# 新建一个配置文件,自定义名字,比如命名为hello_nginx.conf
touch /etc/nginx/conf.d/hello_nginx.conf
# 在/etc/nginx/conf.d/hello_nginx.conf里输入以下内容
server {
listen 11111;
server_name second.sunshine.site;
charset utf-8;
location / {
proxy_pass http://0.0.0.0:17881; # 这里要配合启动文件使用
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static {
alias /root/hello/static/;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
对文件里面配置进行解释:
server {
listen 11111;
server_name second.sunshine.site; # 访问项目的时候是在浏览器输入: second.sunshine.site:11111,second.sunshine.site是我的域名,也可以换成外网ip,
charset utf-8;
location / {
proxy_pass http://0.0.0.0:17881; # 浏览器输入: second.sunshine.site:11111会去访问本地的17881端口起的进程
proxy_redirect off;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
location /static {
alias /root/hello/static/; # 托管这个路径下hello项目的静态文件
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
将django项目和nginx连接在一起
(1)在项目根目录创建一个gunicorn.py文件.(就是有manage.py的那个目录)
vi gunicorn.py
(2)在文件中输入以下内容
# coding:utf-8
import multiprocessing
bind = '0.0.0.0:17881' #绑定ip和端口号
backlog = 512 #监听队列
chdir = '/root/hello' #gunicorn要切换到的目的工作目录, 项目的根目录
timeout = 30 #超时
worker_class = 'gevent' #使用gevent模式,还可以使用sync 模式,默认的是sync模式
workers = multiprocessing.cpu_count() * 2 + 1 #进程数
threads = 2 #指定每个进程开启的线程数
loglevel = 'info' #日志级别,这个日志级别指的是错误日志的级别,而访问日志的级别无法设置
access_log_format = '%(t)s %(p)s %(h)s "%(r)s" %(s)s %(L)s %(b)s %(f)s" "%(a)s"' #设置gunicorn访问日志格式,错误日志无法设置
accesslog = "/root/hello/gunicorn_log/gunicorn_access.log" #访问日志文件
errorlog = "/root/hello/gunicorn_log/gunicorn_error.log" #错误日志文件
配置文件gunicorn.py中的bind 和chdir将nginx, 项目目录和gunicorn连接在一起了
启动项目, 有三种方法:
(1) 第一种方法:命令启动(不推荐,一般不这样操作)
# 在gunicorn.py目录下执行命令gunicorn Django_project.wsgi -c gunicorn.py, 比如我的项目叫hello:
gunicorn hello.wsgi -c gunicorn.py
(2)第二种方法:使用脚本
# 在根目录下(即有manage.py的那个目录下), 创建restart.sh
touch restart.sh
# 在restart.sh下输入以下内容:
#!/bin/sh
## service name
#项目的目录
SERVICE_DIR=/root/hello
#gunicorn的名字
SERVICE_NAME=gunicorn
#gunicorn的配置文件名
SERVICE_CONF=gunicon.py
#pid存放的位置
PID=gunicorn\.pid
#export PATH=$PATH:$HOME/bin:/usr/local/python3/bin
export PATH=$PATH:$HOME/bin:/usr/bin
cd $SERVICE_DIR
start(){
nohup gunicorn hello.wsgi -c $SERVICE_DIR/gunicorn.py>/dev/null 2>&1 &
echo $! > $SERVICE_DIR/$PID
echo "*** start $SERVICE_NAME ***"
}
stop(){
kill `cat $SERVICE_DIR/$PID`
rm -rf $SERVICE_DIR/$PID
echo "*** stop $SERVICE_NAME ***"
sleep 2
P_ID=`ps -ef | grep -w "$SERVICE_NAME" | grep -v "grep" | awk '{print $2}'`
if [ "$P_ID" == "" ]; then
echo "*** $SERVICE_NAME process not exists or stop success ***"
else
echo "*** $SERVICE_NAME process pid is:$P_ID ***"
echo "*** begin kill $SERVICE_NAME process,kill is:$P_ID ***"
kill -9 $P_ID
fi
}
f_usage() {
echo "USAGE: restart [options]"
echo "OPTIONS:"
echo " start"
echo " stop "
echo " restart"
}
case "$1" in
"start")
start
;;
"stop")
stop
;;
"restart")
stop
sleep 2
start
echo "*** restart $SERVICE_NAME ***"
;;
*)
f_usage
;;
esac
exit 0
运行脚本: ./restart.sh start
(3)第三种方法: 使用supervisor启动项目; supervisor是用来管理进程的,这里可以用来管理gunicorn进程, 配置步骤如下:
a. 在/etc目录下创建如下目录结构
├── supervisor
│ ├── conf.d
│ └── var
│ ├── log
└── supervisord.conf
命令如下:
mkdir -p /etc/supervisor/conf.d
mkdir -p /etc/supervisor/var/log
cd /etc
echo_supervisord_conf > supervisord.conf
b. 修改supervisord.conf
首先找到 [unix_http_server] 版块,将 file 设置改为如下的值:
[unix_http_server]
file=/etc/supervisor/var/supervisor.sock
即让 socket 文件生成在 /etc/supervisor/var目录下
c. 修改 [supervisord] 板块下的 logfile 和 pidfile 文件的路径,还有 user 改为系统用户,这样 supervisor 启动的进程将以系统用户运行,避免可能的权限问题:
logfile=/etc/supervisor/var/log/supervisord.log
pidfile=/etc/supervisor/var/supervisord.pid
user=root
d. 修改[supervisorctl] 板块:
serverurl=unix:///etc/supervisor/var/supervisor.sock
e. [include] 版块,将 /etc/supervisor/conf.d/ 目录下所有以 .ini 结尾的文件内容包含到配置中来,这样便于配置的模块化管理,和之前 Nginx 配置文件的处理方式是类似的。
files = /etc/supervisor/conf.d/*.ini
f: 到 conf.d 新建应用的配置:
[program:hello]
command=gunicorn hello.wsgi -c /root/hello/gunicorn.py
directory=/root/hello
autostart=true
autorestart=unexpected
user=root
stdout_logfile=/etc/supervisor/var/log/hello-stdout.log
stderr_logfile=/etc/supervisor/var/log/hello-stderr.log
[program:hello] 指明运行应用的进程,名为 hello。
command 为进程启动时执行的命令。
directory 指定执行命令时所在的目录。
autostart 随 Supervisor 启动自动启动进程。
autorestart 进程意外退出时重启。
user 进程运行的用户,防止权限问题。
stdout_logfile,stderr_logfile 日志输出文件
g. 启动supervisor:
supervisord -c /etc/supervisord.conf
在浏览器访问: second.sunshine.site:11111
├── conf.d
│?? ├── hello.ini
└── var
├── log
│?? ├── hello-stderr.log
│?? ├── hello-stdout.log
│?? └── supervisord.log
├── supervisord.pid
└── supervisor.sock
项目/root/hello最终的文件夹是这样的
├── db.sqlite3
├── gunicorn_log
│ ├── gunicorn_access.log
│ └── gunicorn_error.log
├── gunicorn.pid
├── gunicorn.py
├── hello
│ ├── asgi.py
│ ├── __init__.py
│ ├── __pycache__
│ │ ├── __init__.cpython-36.pyc
│ │ ├── settings.cpython-36.pyc
│ │ ├── urls.cpython-36.pyc
│ │ └── wsgi.cpython-36.pyc
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── manage.py
├── __pycache__
│ └── gunicorn.cpython-36.pyc
├── restart.sh
└── static
以下是一些常用命令及参考文章:
gunicorn -w 2 -b 0.0.0.0:18000 testgunicorn:app
supervisord -c /etc/supervisord.conf
supervisorctl -c /etc/supervisord.conf status
gunicorn Djanfo_project.wsgi -c gunicorn.py
./restart.sh start
supervisorctl shutdown
supervisorctl status
supervisorctl update
supervisorctl reload
supervisorctl -c /etc/supervisord.conf start program_name
supervisorctl -c /etc/supervisord.conf stop program_name
supervisorctl -c /etc/supervisord.conf restart program_name
supervisorctl -c /etc/supervisord.conf start all
supervisorctl -c /etc/supervisord.conf stop all
Django+gunicorn+nginx项目部署 - 修仙小白 - 博客园 (cnblogs.com)
使用 Supervisor 管理服务器后台进程 - 知乎 (zhihu.com)
nginx + gunicorn + supervisor 部署 django 项目 - SegmentFault 思否
Nginx+Gunicorn+Supervisor 部署 Django 博客应用_HelloDjango - Django博客教程(第二版)_追梦人物的博客 (zmrenwu.com)
用supervisor管理python进程 | 酷python (coolpython.net)
Supervisor (进程管理利器) 使用说明 - 运维笔记 - 散尽浮华 - 博客园 (cnblogs.com)
Error: class uri 'gevent' invalid or not found:
[Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/gunicorn/workers/ggevent.py", line 13, in
import gevent
ModuleNotFoundError: No module named 'gevent'
raise RuntimeError("gevent worker requires gevent 1.4 or higher")
RuntimeError: gevent worker requires gevent 1.4 or higher
# 出现上面的报错就需要安装1.4版本以上的gevent
# 安装gevent的时候也许会发生greenlet的错
ERROR: Cannot uninstall 'greenlet'. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
# 执行命令
yum install -y python3-devel
pip install --ignore-installed greenlet
pip3 install gevent
ERROR: Cannot uninstall ‘greenlet’. It is a distutils installed project and thus we cannot accurately determine which files belong to it which would lead to only a partial uninstall.
yum install -y python3-devel
pip install --ignore-installed greenlet
pip3 install gevent