1.linux 下,以命令行方式启动 Django
以下以 python37 为例,表示 python版本为 3.7,对应的pip37,可以根据自身需要,改为自己对应的python版本
1.1 将本地开发完的代码,通过git或者其他途径,上传至linux 服务器上(我这里通过git方式提交,将虚拟环境目录venv添加至.gitignore文件)
...
venv/
...
1.2 创建该项目的虚拟环境目录
为什么创建虚拟环境?
为了让项目运行在一个独立的局部的Python环境中,使得不同环境的项目互不干扰。
1.运行 Django 项目所需的依赖包
pip37 install Django==3.0.2 安装Django,如已安装此处跳过
pip37 install mysqlclient 安装mysql连接工具,如已安装此处跳过
注意 :此处可能报错:OSError: mysql_config not found,是因为linux需要mysql相关的依赖包
解决方法:yum install mysql-devel gcc gcc-devel python-devel
1.安装虚拟环境的第三方包 virtualenv (使用清华源安装)
pip37 install virtualenv -i https://pypi.python.org/simple/
2.进入你的项目根目录
cd 你的项目根路径
3.创建虚拟环境(-p 指定版本,venv表示虚拟环境所在目录)
virtualenv -p /usr/bin/python37 venv
virtualenv --system-site-packages venv 参数 --system-site-packages 指定创建虚拟环境时继承系统三方库
4.激活虚拟环境
cd venv 进入虚拟环境文件夹
source bin/activate 激活虚拟环境
pip37 list 查看当前虚拟环境下安装的第三方库
deactivate 退出虚拟环境
5.删除虚拟环境
直接删除目录即可。
1.3 测试项目是否可以启动
启动项目:python37 manage.py runserver 0.0.0.0:9003
出现:
Starting development server at http://0.0.0.0:9003/
表示启动成功!
此时可以使用 postman 类似的工具,调用服务端接口,测试是否成功。
注意:0.0.0.0 和 127.0.0.1 的区别:
两者都表示本机服务器
0.0.0.0 表示本机,外网可访问
127.0.0.1 同样表示本机,但不能通过服务器ip进行访问
2.uwigi + nginx 部署 Django 项目
如果完成了上一步操作,说明我们的 Django 项目没有问题,可以进行部署。
2.1 一些相关的知识:
部署 Django 的常用方式是,使用Nginx + uWsgi。
部署的整个链路是:Nginx -> uWsgi -> phthon web 程序,通常还会提到supervisord 工具。
uWSGI 是一个软件,部署服务的工具,了解整个过程,我们先了解一下WSGI规范,uwsgi协议等内容。
WSGI(Web Server Gateway Interface)规范,WSGI规定了Python 应用和 Python Web 服务器之间的通讯方式。目前主流的 Python Web 框架,比如Django,Flask,Tornado等,都是基于整个规范实现的。
uwsgi协议:是 uWSGI 工具独有的协议,简洁高效的 uwsgi 协议是选择 uWSGI作为部署工具的重要理由之一,详细的 uwsgi 协议 可参考 uWSGI 文档。uWSGI 是实现了 uwsgi 协议、WSGI规范和 HTTP 协议的一个C语言实现的软件。
Nginx:是一个 web 服务器,是一个反向代理工具,我们通常用它来部署静态文件。主流的 Python Web开发框架都遵循WSGI规范。
uWSGI 通过 WSGI 规范和我们编写的服务器进程通讯,然后通过自带的高效的 uwsgi 协议和 Nginx 进行通讯,最终 Nginx 通过 HTTP 协议将服务对外透出。
当一个访问进来的时候,首先到 Nginx,最终 Nginx 以 HTTP 协议相应给用户。
supervisor是一个进程管理工具。任何人都不能保证程序不异常退出,不被别人误杀,所以一个典型的工程做法就是使用 supervisor 看守你的进程,一旦异常退出,它会立马进程重新启动起来。
2.2 安装 uwsgi
pip install uwsgi
第一个 uwsgi 应用
新建 text.py 文件:
def application(env, start_response):
start_response('200 OK', [{'Content-Type', 'text/html'}])
return [b"Hello World"]
uWSGI Python 加载器将会搜索的默认函数 application
接下来,启动 uwsgi 来运行一个 HTTP 服务器,将其部署在 9001 端口上:
默认启动 单一的进程 和 一个 单一的线程
uwsgi --http :9001 --wsgi-file text.py
例:生成 4 个进程,每个进程有 2 个线程
--stats:表示执行监控任务
uwsgi --http :9001 --wsgi-file text.py --master --processes 4 --threads 2
如果要执行监控任务,可以使用stats
子系统,监控的数据格式为 JSON
uwsgi --http :9001 --wsgi-file text.py --master --processes 4 --threads 2 --stats 127.0.0.1:9091
使用 uwsgitop(类似Linux top 命令)来查看监控数据:
pip install uwsgitop
2.3 配置uwsgi + nginx,启动 django 项目
测试:进入使用命令启动 uwsgi,启动后使用 postman 或者其他接口调用工具测试,测试接口是否可以调用成功
uwsgi --http :9002 --wsgi-file django_web/wsgi.py --home venv/
如调用成功,可以将命令存到.ini 文件中,使用命令uwsgi xxxx.ini
启动。
如:新建 start_uwsgi.ini
文件,并将其放置在项目根路径下
根路径下新建文件夹uwsgi
,用于存放uwsgi.status
及uwsgi.pid
文件
[uwsgi]
http = :9002 # 对外提供 http 服务的端口
socket = 0.0.0.0:9001 # 上线使用
# django 程序的主目录
chdir=/home/workspace/myTaobao/admin_python
wsgi-file = django_web/wsgi.py
# 虚拟环境路径
home = %(chdir)/venv/
# uwsgi 进程的状态文件存放
stats=%(chdir)/uwsgi/uwsgi.status
# uwsgi 文件启动后的ip
pidfile=%(chdir)/uwsgi/uwsgi.pid
# 进程与线程
processes = 4
threads = 2
# 后台运行,并输出日志
daemonize=/home/logs/myTaobao.log
vacuum=true # 当服务器退出的时候自动清理环境,删除unix socket文件和pid文件
uwsgi 常用命令:
运行 sudo uwsgi --http 0.0.0.0:8000 --wsgi-file test.py --processes 4 --threads 3
启动:uwsgi --ini uwsgi.ini
停止:uwsgi --stop uwsgi/uwsgi.pid
重启:uwsgi --connect-and-read uwsgi/uwsgi.status
查看端口是否占用:lsof -i :9001
根据 PID 杀掉进程:sudo kill -9 2208
其他可能用到的命令:
ps aux | grep python 查看系统中运行的 python 进程
ps -ef | grep python 同上
kill -1 PID 优雅的重启进程,对服务器无影响
kill -9 PID 强制杀死进程
sodu pkill -f uwsgi -9 强制杀掉 uwsgi 进程
sudo lsof -p PID 查看进程打开了哪些文件
sudo lsof -p PID | grep TCP 查看进程中的 TCP 连接信息
netstat -nltp 查看服务器中监控了那些端口
sudo lsof -i :80 查看具体端口的占用情况
vi 退出编辑相关命令:
先按 ESC 键跳到命令模式,然后:
:w 保存文件,但不退出vi
:w file 将修改另外保存到 file 中,不退出vi
:w! 强制保存,不退出vi
:wq 保存并退出
:wq! 强制保存文件,并退出
:q 不保存文件,退出vi
:q! 不保存文件,并强制退出vi
:e! 放弃所有修改,从上次保存文件开始再编辑
nginx配置:
假如我们的网站页面部署在端口8001上,使用nginx配置将请求指向到 uwsgi 的 9001 端口上
server {
# 监听绑定 8001 端口
listen 8001;
# 域名,多的用空格分割
# server_name image.imooc.com;
autoindex off;
access_log /usr/local/nginx/logs/access.log combined;
index index.html index.htm;
# ssl on;
# ssl_certificate ../certbo/1523694051089.pem; #改证书路径
# ssl_certificate_key ../certbo/1523694051089.key; #改私钥路径
# ssl_session_timeout 5m;
# ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
# ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# ssl_prefer_server_ciphers on;
error_page 500 502 503 504 /50x.html;
if ( $query_string ~* ".*[\;'\<\>].*" ){
return 404;
}
# 指定网页
location / {
root /home/workspace/XXXX/web;
add_header Cache-Control no-store; # 不缓存
}
# 跳转 uwsgi
location /api {
# proxy_pass http://127.0.0.1:9001/api;
# add_header Access-Control-Allow-Origin *;
uwsgi_pass 127.0.0.1:9001;
include uwsgi_params;
}
}
最后,启动 nginx 即可。