网络客户端 <-> 网站服务器(nginx) <-> the socket <-> uwsgi <-> Django
这里,uwsgi 是与 Django 交互的一种 python 标准,而 nginx 和 uwsgi 之间的交互方式是以 socket 包的方式进行的
说明下,我们下面会频繁提到几个名词,提前备注下
注意,这里强烈推荐用 pip 安装,否则后续会遇到一些问题。
pip install uwsgi
which uwsgi
看下路径是不是指向虚拟环境的
测试:
在项目目录下,新建一个 test.py 文件。
# test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"] # python3
#return ["Hello World"] # python2
uwsgi --http :8000 --wsgi-file test.py
这里的 8000 端口应该是可用而且空闲的,所谓可用是指 阿里云 或者 腾讯云 的该端口安全组是已经配置了的,具体不懂的可以百度,所谓空闲的,是指该端口没有被占用,具体查询方法为如下:
netstat -nltp | grep 8000
打开 http://IP:8000 是否能看到 “hello world” 的输出,如果是,说明如下通信链路是通的
客户端 <-> uWSGI <-> Python
如果不能看到,再看下上面的内容,是不是遗忘了一些步骤或者配置有问题
首先,看下你的 django 项目是不是可以跑通
python manage.py runserver 0.0.0.0:8000
然后打开 http://IP:8000/admin 是否可以看到你的 django 登录界面,如果可以的话,说明项目没问题。
然后输入
uwsgi --http :8000 --module mysite.wsgi
这里的 mysite 是 django 项目的名字,如果你的项目名字是其他的,这里对应修改一下,我们本篇都会以 mysite 作为默认的项目名
然后打开 http://IP:8000/admin 是否可以看到你的 django 登录界面,如果可以的话,说明如下的网络通信没有问题
客户端 <-> uWSGI <-> Django
这里我们默认 nginx 已经安装完成而且安装方式是 yum 安装
打开 http://IP:80 是否可以看到 nginx 的欢迎界面,如果可以说明以下通信链路是没问题
客户端 <-> nginx 服务器
如果有问题,可以看下 /var/log/nginx/error.log 日志,如果是端口被占用,直接停掉对应的进程然后重新启动 nginx
nginx -s reload
打开 nginx 路径,如果不知道可以打 nginx -t 或者 whereis nginx
我这边的 nginx 的路径是 /etc/nginx,里面的文件架构是
nginx
-- conf.d
fastcgi_params
nginx.conf
uwsgi_params
...
这里的 conf.d 就是 nginx 配置文件的目录,下一步我们会用到。
同时,因为我们需要在项目中使用到 uwsgi_params 文件,所以把这个文件复制到项目目录中,并且文件的拥有者是开发者而不是 root。
在项目目录下,新建一个 mysite_nginx.conf 文件,并填入以下信息
# mysite_nginx.conf
# the upstream component nginx needs to connect to
upstream django {
# server unix:///path/to/your/mysite/mysite.sock; # for a file socket
server 127.0.0.1:8001; # socket 的网络端口
}
# configuration of the server
server {
# the port your site will be served on
listen 8000;
# the domain name it will serve for
server_name IP; # 服务器IP
charset utf-8;
# max upload size
client_max_body_size 75M; # 可以自己调整
# Django media
location /media {
alias 项目目录/media; # 媒体文件路径
}
location /static {
alias 项目目录/static; # 静态文件路径
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include 项目目录/uwsgi_params; # 项目的 uwsgi_params 文件
}
}
然后做一个指向该配置文件的软链接
ln -s 项目目录/mysite_nginx.conf /etc/nginx/conf.d/
首先,修改一下 django 项目的配置文件(项目目录/setting.py )
将其中的 debug = True 改为 debug = False
然后在文件末尾添加如下一行
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
STATIC_URL = '/static/'
同时需要对 mysite 文件夹下面的 urls.py 文件做一个简单的修改
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
# ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
同时,需要对访问的ip和域名地址做一个设置,否则会造成 connection refused 这样的问题,这里我的例子是这样:
ALLOWED_HOSTS = ['127.0.0.1', '外网IP','www.guming-tech.com']
然后在你的项目目录中添加2个子目录
/media/
/static/
分别存放媒体文件和静态文件,然后输入以下命令
python manage.py collectstatic
然后放一张图片在 media 目录下,什么图片都可以,我们这里假设图片为 show.png
接下来,切入到系统环境中,然后重启 nginx
nginx -s reload
然后访问 http://IP:8000/media/show.png, 如果图片能够显示,则说明 nginx 的项目配置是没有问题的
输入以下命令
uwsgi --socket :8001 --wsgi-file test.py
这里的 8001 端口是基于第5步中对 nginx 项目配置文件的配置,忘记的可以重新翻看下
然后打开 http://IP:8000 是否可以看到 “hello world”,如果可以的话,说明如下的通信链路是没有问题的
客户端 <-> nginx 服务器 <-> the socket <-> uWSGI <-> Python
上一步我们使用了TCP的 socket 的端口通信,这个是比较简单的,但是在实际的网站中,更好的解决方案是 unix socket 方法,具体设置方法如下:
编辑 mysite_nginx.conf 对文件的头部部分做一些修改
server unix://项目目录/mysite.sock; # socket 文件,自动生成
# server 127.0.0.1:8001; # for a web port socket (we'll use this first)
切换到系统环境中,重启 nginx
然后输入
uwsgi --socket mysite.sock --wsgi-file test.py
然后打开 http://IP:8000 应该可以看到 “hello world”,如果有 permission error 的话,试下如下2种方法
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=666
uwsgi --socket mysite.sock --wsgi-file test.py --chmod-socket=664
我这边是对第一种方法有效
这次试下如下的命令
uwsgi --socket mysite.sock --module mysite.wsgi --chmod-socket=666
然后打开 http://IP:8000/admin 是不是可以看到 django 的登录界面了
在项目目录下新建一个 mysite_uwsgi.ini 文件,并放入以下内容
# mysite_uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = 项目目录
# Django's wsgi file
module = mysite.wsgi
# the virtualenv (full path),这个是你使用 virtualenv 建立的项目的绝对路径,但不是项目路径,一般是项目目录的上层路径
home = 项目目录的上层路径
# process-related settings
# master
master = true
# maximum number of worker processes
processes = 10
# the socket (use the full path to be safe
socket = 项目路径/mysite.sock
# ... with appropriate permissions - may be needed
chmod-socket = 666
# clear environment on exit
vacuum = false
然后输入
uwsgi --ini mysite_uwsgi.ini
然后打开 http://IP:8000/admin 应该还是可以通信
依然是用 pip 安装 uwsgi
pip install uwsgi
然后在系统环境中进入到项目目录,输入
uwsgi --ini mysite_uwsgi.ini
然后打开 http://IP:8000/admin 应该还是可以通信
uwsgi 可以在 “Emperor” 皇帝模式下工作,即可以监视所有的 uwsgi 配置文件
mkdir /etc/uwsgi
mkdir /etc/uwsgi/vassals
ln -s 项目目录/mysite_uwsgi.ini /etc/uwsgi/vassals/
uwsgi --emperor /etc/uwsgi/vassals --uid user --gid user-group
具体的 user 和 user-group 这里你可以自己选择,比方说对系统用户 django
groups django
输出 django 的用户组,填进去试试
这里我们选择推荐的 /etc/rc.local 进行编辑
然后加入如下的命令
uwsgi安装路径/uwsgi --emperor /etc/uwsgi/vassals --uid 用户 --gid 用户组 --daemonize /var/log/uwsgi-emperor.log
这里的 uwsgi安装路径可以通过以下的命令得到
which uwsgi
然后
source /etc/rc.local
需要提到的一点 /etc/rc.local 在centos7的版本里是只读的,所以我们需要给它加入一个可执行的权限,同时 /etc/rc.local 的服务名为 rc-local,所以我们这里将其设定为自启动
chmod +x /etc/rc.d/rc.local
systemctl enable rc-local
可以尝试重启下系统,看看服务是否自动打开
systemctl status rc-local
直接打开 http://IP:8000/admin 应该可以看到网站正常运行
部署完成
如果在项目中新增加了一个应用app,需要对项目进行重启,这时候我们需要对 uwsgi 的配置文件 mysite_uwsgi.ini 做一个修改。即添加一行
touch-reload = 项目路径/reload.ini
然后在项目目录中,输入以下命令
touch reload.ini
这时候不只要重新启动 nginx 还有 uwsgi(已经在rc-local中)
nginx -s reload
killall uwsgi
source /etc/rc.local