Python+Django+uwsgi+Nginx 项目部署采坑记

一. 环境描述

  • 服务器: 阿里云ecs
  • 系统版本:Ubuntu 18.04LTS
  • 部署环境:Python3.6 + Django 1.11.13 + uwsgi 2.0.18 + MySQL 5.7 + Redis + Nginx

###二. 步骤
说明: 至于如何在阿里云服务器中安装虚拟环境、Mysql、Reids、Nginx等我这偏文章不进行说明,免得把文章的篇幅写得太长,我这里主要记录一下配置中的几个关键步骤及可能遇到的问题及解决方案。

2.1 上线前更改setting中的配置

主要从以下几个方面进行

  1. setting.py文件中的 DEBUGTrue改为Flase
  2. 将数据库账号、邮箱账号、微信公众号/小程序等相关的配置改成正式的账号;
  3. 确定线上日志的路径并调整正确;
  4. 配置好静态文件存放位置,如我下面打算把静态文件存放到项目根目录的front_end/static下面
STATIC_ROOT = os.path.join(os.path.dirname(os.path.dirname(BASE_DIR)), 'front_end/static')

说明:由于开发环境和线上环境的账号配置不一样,这一块要格外注意。有时候维护两个不同环境中的账号配置其实挺麻烦的,而且还容易弄错,一不小心还容易上传到代码仓库将重要的账号信息给给泄露了,为了安全起见,我们要把两个不同环境下的账号绝对的隔离并且交由系统保管,这样就省去了前面的一系列麻烦。后面我会专门花一篇篇幅来详细介绍处理方法。

2.2 收集静态文件

执行收集静态文件的命令

python manage.py collectstatic

这样Django admin中的静态文件(CSS/JS/HTML等)就都被收集到上面配置的项目根目录的front_end/static下面。

2.3 uwsgi的安装

对于uwsgi不了解的人可以参考uwsgi docs,这里我只是进行简单的介绍如何使用及踩过的坑

  1. 安装
pip install uwsgi
  1. 配置uwsgi的配置文件,这里选用最简单的配置方法,直接通过配置uwsgi.ini文件
[uwsgi]
#使用nginx连接时使用,Django程序所在服务器地址
socket=127.0.0.1:8001
#直接做web服务器使用,Django程序所在服务器地址
#http=49.75.55.2:8001
#项目目录
chdir=/www/project/xxxx/xxxx
#项目中wsgi.py文件的目录,相对于项目目录
wsgi-file=xxxx/wsgi.py
# 进程数
processes=5
# 线程数
threads=10
# uwsgi服务器的角色
master=True
# 存放进程编号的文件
pidfile=uwsgi.pid
# 日志文件,因为uwsgi可以脱离终端在后台运行,日志看不见。我们以前的runserver是依赖终端的
daemonize=uwsgi.log
# 指定依赖的虚拟环境
virtualenv=/Users/xxxx/.virtualenv/project_name
# 指定插件的位置
plugins-dir=/usr/lib/uwsgi/plugins
# 指定系统运行依赖的插件
plugins=python3, http
#当服务器退出的时候自动删除unix socket文件和pid文件。
vacuum=true

关于uwsgi服务启动与停止的说明

  • 启动uwsgi服务器, 在uwsgi服务器文件目录下运行下面命令
uwsgi --ini uwsgi.ini
  • 停止uwsgi服务的方法
uwsgi --stop uwsgi.pid

说明:

1.还可以使用kill命令通过进程号或者killall命令通过进程名杀死uwsgi服务以达到停止服务的目的
2.判断uwsgi 服务是否运行的两个方法ps -aux | grep uwsgi/ lsof -i:8001

2.4 nginx的配置

nginx在这里的作为主要是进行服务(uwsgi, 静态文件)的转发,还有个就是负载均衡(多台服务器之间)

upstream blog {
		# 此处为uwsgi运行的ip地址和端口号
        server 127.0.0.1:8001;  
         # 如果有多台服务器,可以在此处继续添加服务器地址
     }

     server {
         listen  8000;
         server_name api.kendny.cn;

         location / {
             include uwsgi_params;
             uwsgi_pass blog;
         }
     }

     server {
         listen       80;
         server_name  www.kendny.cn;
         location /xadmin {
             include uwsgi_params;
             uwsgi_pass blog;
         }

         location / {
             root   /www/blog/front_end;
             index  index.html index.htm;
         }

         error_page   500 502 503 504  /50x.html;
         location = /50x.html {
             root   html;
         }
     }
nginx进行操作的
  1. 验证nginx配置是否正确
nginx -t

如果出现问题会详细指出来是哪一行

  1. 启动nginx服务
sudo service nginx start
  1. 停止nginx服务
sudo service nginx stop

4.重启nginx服务

sudo service nginx restart

说明:nginx服务的日志一般存放在var/logs/ningx/下面

三. 遇到问题汇总

遇到问题不要慌,出现问题肯定是由某些不正确的操作或者配置导致的,这时候我们可以很好的利用系统的各种日志查看记录的报错信息,然后进行仔细的研究和认真的思考,问题终会被解决的。重要的事情说三遍:遇到问题,看log、看log、看log!!!

3.1. uwsgi 报错

uwsgi报错一: !!! no internal routing support, rebuild with pcre support !!!

首先我们想到的是查看日志:到日志的目前下面去,然后通过命令tail -f uwsgi.log查看报错信息
解决方法:卸载掉uwsgi,然后安装相关的依赖,重写安装uwsgi

pip uninstall uwsgi
sudo apt-get install libpcre3 libpcre3-dev
pip install uwsgi

参考:https://stackoverflow.com/questions/21669354/rebuild-uwsgi-with-pcre-support

uwsgi报错二: no app loaded. going in full dynamic mode
  • 原因1: 不是在django环境下启动的应用,加载不了应用(app); 解决方法:切换到安装了django的环境下启动应用。
  • 原因2: 没有安装uwsgi服务启动应用需要python插件, 这里需要重新安装。
#卸载uwsgi,
sudo apt-get remove uwsgi
sudo apt-get update
#重新安装uwsgi
sudo apt-get install uwsgi
sudo apt-get install uwsgi-plugin-python3 
sudo pip3 install uwsgi
启动uwsgi报错三 :/usr/lib/uwsgi/plugins/python_plugin.so: cannot open shared object file: No such file or directory

网上流传这这样一种解决方案 “把配置文件中的 plugins = python/3 注释掉”,这虽然解决了报错,但是项目还是难以正常运行,正确的解决方案是, 添加plugins所在的目录,并且指定插件所在的位置

# 指定插件的位置
plugins-dir=/usr/lib/uwsgi/plugins

然后用超级管理员的命令启动uwsgi的服务

sudo uwsgi --ini uwsgi.ini
运行uwsgi过程中的报错: DAMN ! worker 2 (pid: 4247) died, killed by signal 9 :( trying respawn ...Respawned uWSGI worker 2 (new pid: 4457)

引起这个报错的大概原因是:signal 9 means it received a SIGKILL. so something sent a kill to your worker. it’s relatively likely that the out-of-memory killer decided to kill your app because it was using too much memory.
所以需要了解uwsgi的运行的原理,找出引起的原因。可以从以下几个方面考虑:

  1. 后台代码层面
  2. 服务配置层面

首先我新建一个空的django项目,用同样的uwsgi配置去跑这个空框架项目,同样出现了这样一个问题,这就基本可以排除是自己代码层面导致的原因。然后从配置着手了,经过仔细查阅官方文档及多次尝试,基本可以定位是因为进程开辟的多个线程在跑服务导致进程内存过大,系统之间kill掉了worker(线程是共享进程资源的)。后面我改了下面几项设置uwsgi服务就正常了

thread-stacksize=512
enable-threads=false
lazy-apps=false

参考:

  1. https://stackoverflow.com/questions/25414902/how-to-find-out-why-uwsgi-kill-workers
  2. https://uwsgi-docs.readthedocs.io/en/latest/

3.2. 报 Site matching query does not exist.的解决方案

If you don’t have a site defined in your database and django wants to reference it, you will need to create one.
From a python manage.py shell :

from django.contrib.sites.models import Site
new_site = Site.objects.create(domain='foo.com', name='foo.com')
print (new_site.id)

Now set that site ID in your settings.py to SITE_ID

参考: https://stackoverflow.com/questions/11814059/site-matching-query-does-not-exist

说明: 后面我将逐渐将我的blog转移到我的个人网站, 欢迎关注并评论!

你可能感兴趣的:(Django,uwsgi,Python)