Django + uWSGI + Nginx 实现生产环境部署
Posted skiler
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Django + uWSGI + Nginx 实现生产环境部署相关的知识,希望对你有一定的参考价值。
一、Uwsgi 是啥?
WSGI(Web Server Gateway Interface),是一种Web服务器网关接口。它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的程序)通信的一种规范。
uWSGI 是一个快速的、纯C语言开发的、自维护的、对开发者友好的 WSGI 服务器,旨在提供专业的 Python web应用发布和开发。可使用 C/C++/Objective-C 来为 uWSGI 编写插件。
要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。
- WSGI是一种Web服务器网关接口。它是一个Web服务器(如nginx,uWSGI等服务器)与web应用(如用Flask框架写的程序)通信的一种规范。
- uwsgi是一种线路协议而不是通信协议,在此常用于在uWSGI服务器与其他网络服务器的数据通信。
- 而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。
- uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。
uWSGI的主要特点如下
- 超快的性能
- 低内存占用(实测为apache2的mod_wsgi的一半左右)
- 多app管理(终于不用冥思苦想下个app用哪个端口比较好了-.-)
- 详尽的日志功能(可以用来分析app性能和瓶颈)
- 高度可定制(内存大小限制,服务一定次数后重启等)
- 处理静态请求不太好
二、Nginx是啥?
Nginx(发音同engine x)是一个网页服务器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的协议链接,以及一个负载均衡器和一个HTTP缓存。其特点是占有内存少,并发能力强。
三、比较好使的框架结构
四、环境搭建
a、Linux服务器一台
[root@web01 ~]# cat /etc/redhat-release CentOS release 6.6 (Final) [root@web01 ~]# uname -r 2.6.32-504.el6.x86_64
b、安装Python和Django相关的软件和工具包
- 安装setuptools
[root@django tools]# yum install pcre pcre-devel openssl openssl-devel zlib bzip2-devel -y [root@django tools]# ll -rw-r--r-- 1 root root 641502 3月 2 18:50 setuptools-19.6.tar.gz [root@django tools]# tar xf setuptools-19.6 [root@django tools]# cd setuptools-19.6 [root@django tools]#python setup.py install [root@django tools]#cd .. ################################################################## #nginx模块 pcre pcre-devel #perl语言兼容正则表达式,用来做Nginx的HTTP Rewrite 模块 bzip2-devel ·#提供压缩功能 openssl openssl-devel #https加密模块 ################################################################### zlib #在编译python3的时候,加载setuptools的时候会报错,所以这里提前处理啦!
- 安装pip
[root@django tools]# ll -rw-r--r-- 1 root root 1197370 3月 2 13:30 pip-9.0.1.tar.gz [root@django tools]# tar xf pip-9.0.1.tar.gz [root@django tools]# cd pip-9.0.1 [root@django pip-9.0.1]# python setup.py install [root@django pip-9.0.1]# cd .. #配置环境变量: [root@django bin]# vi /etc/profile export PATH="/usr/local/python3/bin:$PATH" [root@django bin]# tail -1 /etc/profile export PATH="/usr/local/python3/bin:$PATH" [root@django bin]# source /etc/profile #查看帮助 [root@django bin]# pip3 或 pip
- 安装sqlite3
方法一: yum install sqlite-devel 或 方法二: 软件下载官网:http://www.sqlite.org [root@django tools]# ll -rw-r--r-- 1 root root 2515143 3月 2 13:33 sqlite-autoconf-3170000.tar.gz [root@django tools]# tar xf sqlite-autoconf-3170000.tar.gz [root@django tools]# cd sqlite-autoconf-3170000 [root@django tools]# ./configure [root@django tools]#make && make install
- 升级到Python3
方法一: 升级为python3.5版本步骤 root@template ~]# cd /home/oldboy/tools/ #下载python-3.5.2 [root@template tools]# wget https://www.python.org/ftp/python/3.5.2/Python-3.5.2.tgz [root@template tools]# ll 总用量 20104 -rw-r--r-- 1 root root 20566643 6月 26 05:47 Python-3.5.2.tgz #解压到下载目录 [root@template tools]# tar zxvf Python-3.5.2.tgz #进入解压后的文件夹 [root@template tools]# cd Python-3.5.2 #在编译前先在/usr/local建一个文件夹python3(作为python的安装路径,以免覆盖老的版本) [root@template Python-3.5.2]# mkdir /usr/local/python3 #开始编译安装 [root@template Python-3.5.2]# ./configure --prefix=/usr/local/python3 [root@template Python-3.5.2]# make && make install 此时没有覆盖老版本,再将原来/usr/bin/python链接改为别的名字 [root@template Python-3.5.2]# mv /usr/bin/python /usr/bin/python_old #再建立新版本python的软链接 [root@template Python-3.5.2]# ln -s /usr/local/python3/bin/python3 /usr/bin/python #就会显示出python的新版本信息 [root@template Python-3.5.2]# python Python 3.5.2 (default, Aug 2 2016, 11:35:06) [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> exit() #<----退出python PS:如果不建立新安装路径python3,而是直接默认安装,则安装后的新python应该会覆盖linux下自带的老版本。当然如果还想保留原来的版本,那么这种方法最好不过了。 注意事项: 这种方法虽然能安装成功,但会导致yum不能正常使用。 解决方法: [root@template tools]# cp /usr/bin/yum /usr/bin/yum.backup_2016-08-02 修改第一行参数 vi /usr/bin/yum 把 #!/usr/bin/python 修改为:/usr/bin/python_old 或 把 #!/usr/bin/python 修改为:/usr/bin/python2.6 #查看版本 [root@template Python-3.5.2]# python --version Python 3.5.2 #查看安装路径(可以省略这步) [root@web01 ~]# python Python 3.5.2 (default, May 27 2017, 18:39:42) [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> print(sys.path) [\'\', \'/usr/local/python3/lib/python35.zip\', \'/usr/local/python3/lib/python3.5\', \'/usr/local/python3/lib/python3.5/plat-linux\', \'/usr/local/python3/lib/python3.5/lib-dynload\', \'/usr/local/python3/lib/python3.5/site-packages\'] >>> exit()
- 安装Django
方式一:用pip3安装 pip3 install django 升级方法: pip3 install django --upgrade
- 安装Pymysql (选装,具体看项目使用的数据库)
pip3 install PyMySQL #检查模块是否安装成功 [root@web01 ~]# python Python 3.5.2 (default, May 27 2017, 18:39:42) [GCC 4.4.7 20120313 (Red Hat 4.4.7-11)] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import pymysql >>> >>> exit()
c、uWSGI的安装
# 安装 uwsgi [root@localhost teacher]# pip3 install uwsgi
[root@web01 nulige]# cd /home/nulige [root@web01 nulige]# mkdir -p uwsgi_test [root@web01 nulige]# cd uwsgi_test/ #测试文件 [root@web01 uwsgi_test]# vi test.py def application(env, start_response): start_response(\'200 OK\', [(\'Content-Type\',\'text/html\')]) return [b"Hello World"] # python3 #return ["Hello World"] # python2 # 启动 [root@web01 uwsgi_test]# uwsgi --http :8000 --wsgi-file test.py # 查看进程 [root@web01 ~]# ps -ef|grep uwsgi root 17970 1000 0 19:12 pts/0 00:00:00 uwsgi --http :8000 --wsgi-file test.py root 17972 17970 0 19:12 pts/0 00:00:00 uwsgi --http :8000 --wsgi-file test.py root 17996 17973 0 19:14 pts/1 00:00:00 grep uwsgi # 浏览器访问
d、nginx的安装
- 更改操作系统默认的yum源
#以CentOS6.x 系统为例 1、备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup 2、更换成国内源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo 3、之后运行yum makecache生成缓存
2. 安装nginx
yum -y install nginx
六、启动项目
a、uWSGI的启动
- 命令行启动
[root@python-dev ~]# uwsgi --http 192.168.14.4:8080 --file teacher/wsgi.py --static-map=/static=static
- 配置文件启动
# uwsig使用配置文件启动 [uwsgi] # 项目目录 chdir=/opt/project_teacher/teacher/ # 指定项目的application module=teacher.wsgi:application # 指定sock的文件路径 socket=/opt/project_teacher/script/uwsgi.sock # 进程个数 workers=5 pidfile=/opt/project_teacher/script/uwsgi.pid # 指定IP端口 http=192.168.31.123:8080 # 指定静态文件 static-map=/static=/opt/test_project/teacher/static # 启动uwsgi的用户名和用户组 uid=root gid=root # 启用主进程 master=true # 自动移除unix Socket和pid文件当服务停止的时候 vacuum=true # 序列化接受的内容,如果可能的话 thunder-lock=true # 启用线程 enable-threads=true # 设置自中断时间 harakiri=30 # 设置缓冲 post-buffering=4096 # 设置日志目录 daemonize=/opt/project_teacher/script/uwsgi.log
# 通过配置文件启动 uwsgi --ini uwsgi.ini # 会生成两个文件 PID文件 他是标识这个程序所处的状态 SOCK文件 他是用来和其他程序通信的 # 停止uwsgi uwsgi --stop uwsgi.pid # 重载配置 uwsgi --reload uwsgi.ini
b、nginx的配置
#先进入到配置文件: vi /etc/nginx/conf.d/ # 这个server标识开始配置了 server { listen 80; # 我要监听那个端口 server_name 10.129.205.183 ; # 你访问的路径前面的url名称 access_log /var/log/nginx/access.log main; # Nginx日志配置 charset utf-8; # Nginx编码 gzip on; # 启用压缩,这个的作用就是给用户一个网页,比如3M压缩后1M这样传输速度就会提高很多 gzip_types text/plain application/x-javascript text/css text/javascript application/x-httpd-php application/json text/json image/jpeg image/gif image/png application/octet-stream; # 支持压缩的类型 error_page 404 /404.html; # 错误页面 error_page 500 502 503 504 /50x.html; # 错误页面 # 指定项目路径uwsgi location / { # 这个location就和咱们Django的url(r\'^admin/\', admin.site.urls), include uwsgi_params; # 导入一个Nginx模块他是用来和uWSGI进行通讯的 uwsgi_connect_timeout 30; # 设置连接uWSGI超时时间 uwsgi_pass unix:/opt/project_teacher/script/uwsgi.sock; # 指定uwsgi的sock文件所有动态请求就会直接丢给他 } # 指定静态文件路径 location /static/ { alias /opt/project_teacher/teacher/static/; index index.html index.htm; } }
/etc/init.d/nginx start /etc/init.d/nginx stop # 这里有个命令configtest,Nginx配置是重启生效的,如果你修改完了,不知道对不对又担心影响其他人可以使用它测试 /etc/init.d/nginx configtest # 如果是生产环境的话Nginx正在运行,就不要直接stop start 或者 restart 直接reload就行了 # 对线上影响最低(生产环境用的方法) /etc/init.d/nginx reload
解决Django静态配置文件丢失问题
问题原因: 是因为admin所需的js,css等静态文件都在django的安装目录内,但是我们并没有配置指向Django的配置文件。 解决办法: 我们可以通过配置 STATIC_ROOT = os.path.join(BASE_DIR, "static_all")来指定静态文件的默认家目录是那里,然后把项目里所有的静态文件都收集起来放到这个目录下面。 收集命令: python3 manage.py collectstatic --noinput 修改Nginx 指定静态路径 alias /opt/test_project/teacher/static_all/;
参数优化,请参考官方文档:
首先参考下官网的 things to know : http://uwsgi-docs.readthedocs.org/en/latest/ThingsToKnow.html
我这边最终启动的命令如下:
uwsgi --socket 127.0.0.1:9090 -p 16 -l 8192 -M -R 100000 -z30 -L --wsgi-file app.py --max-apps 65535 --stats 127.0.0.1:1717 --post-buffering 100M --cpu affinity --buffer-size 65535 --daemonize /tmp/uwsgi --pidfile /tmp/uwsgi.pid --memory-report --threads 16
以上是关于Django + uWSGI + Nginx 实现生产环境部署的主要内容,如果未能解决你的问题,请参考以下文章
Django + Uwsgi + Nginx 实现生产环境部署
Django + uWSGI + Nginx 实现生产环境部署