1、系统环境,必要知识
#cat /etc/redhat-release CentOS Linux release 7.5.1804 (Core) #uname -r3.10.0-862.3.2.el7.x86_64
暂时关闭防护墙,关闭selinux:
#systemctl stop firewalld.service#setenforce 0#getenforce Permissive
准备知识:
django:一个基于python的开源web框架。
uWSGI:一个基于自有的uwsgi协议,wsgi协议和http服务协议的web网关
nginx:高性能的代理web服务器
wsgi.py:django项目自带的wsgi接口文件(位于:项目/项目名/wsgi.py)
整个项目流程:
首先客户端通过浏览器访问服务器资源;nginx作为对外服务的端口(80),nginx接收到客户端http请求后会解包分析,如果是静态文件就去配置的静态文件中查找资源并返回给客户端,如果是动态资源,nginx就通过配置文件将请求传递给uwsgi处理,并转发给uwsgi,wsgi根据请求调用django工程的文件和函数,处理后django将返回值交给wsgi,wsgi将返回值进行打包,转发给uWSGI,uWSGI接收到数据后转发给nginx,最终返回给客户端。
2、安装python3.6.5
(1)安装python依赖包
yum -y install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel python-devel
(2)安装python
#wget https://www.python.org/ftp/python/3.6.5/Python-3.6.5.tgz#mkdir -p /usr/local/python356#tar zxvf Python-3.6.5.tgz#cd Python-3.6.5#./configure --prefix=/usr/local/python356#make#make install#ln -s /usr/local/python356/bin/python3 /usr/local/bin/python3#ln -s /usr/local/python356/bin/pip3 /usr/local/bin/pip3#pip3 install --upgrade pip ?#更新pip#pip3 install ipython ?#安装ipython方便调试
测试安装是否正常:
#python3 -VPython 3.6.5#pip3 -Vpip 10.0.1 from /usr/local/python356/lib/python3.6/site-packages/pip (python 3.6)
3、安装uWSGI
使用python的pip工具包安装:
#pip3 install uwsgi#ln -s /usr/local/python356/bin/uwsgi /usr/local/bin/uwsgi ?#建立软链接#uwsgi --version ?#检查安装成功2.0.17
建立uWSGI的配置文件,在django项目中建立uwsgi.ini文件:
[uwsgi]socket = 127.0.0.1:9090chdir = /djproject/mysitemodule = mysite.wsgi ???#这里填的是相对路径master = trueprocesses = 2threads = 2max-requests = 2000vacuum = truedaemonize = /djproject/mysite/uwsgi.logstats = 127.0.0.1:9001post-buffering = 65535buffer-size = 65535harakiri-verbose = trueharakiri = 300uid = nginxpidfile = /djproject/mysite/uwsgi.pid
参数说明:
socket:指定监听地址和端口
chdir:指定工程的绝对路径,如Django的项目路径
module:指定web应用的入口模块,如Django项目下的wsgi.py接口文件
master:启动主进程
processes:启动进程数
threads:启动线程数
max-requests:最大请求数
daemonize:指定uWSGI日志文件路径
stats:指定状态查询端口,如:127.0.0.1:9001
wsgi-file:指定启动的文件
post-buffering:设置缓冲区
buffer-size:设置缓冲区文件大小
harakiri-verbose:设置超时true为开启
harakiri:设置超时时间
uid、gid:设置用户和组
pidfile:指定启动时的pid文件路径
uwsgi信号控制:
HUP :优雅的重新加载所有进程和配置,同(--reload)一样
TERM :强制重新加载主进程和配置
INT :立即杀死整个uWSGI;同于:--stop
QUIT :立即杀死真个uWSGI
重新启动实例:
#kill -HUP `cat /tmp/project-mast.pid`
#uwsgi --reload /tmp/project-master.pid
还可以在python程序中使用uwsgi.reload()重新加载
停止服务器:
#uwsgi --stop /tmp/project-master.pid
#kill -INT `cat /tmp/project-master.pid`
编写启动脚本:
#vim /etc/init.d/uwsgi
#!/bin/bash#this is uwsgi server script. /etc/init.d/functionsuwsgi=/usr/local/bin/uwsgiuwsgi_pid=/djangoproject/mysite/uwsig.piduwsgi_conf=/djangoproject/mysite/uwsigconf.iniuwsgi_pn=`ps -ef|grep -v "grep"|grep -c "uwsgi"`ERVAL=0start(){ ???$uwsgi --ini $uwsgi_conf >& /dev/unll ???ERVAL=$? ???if [ $ERVAL -eq 0 ];then ???????action "uwsgid starting ..." /bin/true ???else ???????action "uwsgid start is error" /bin/false ???fi}stop(){ ???$uwsgi --stop $uwsgi_pid >& /dev/null ???ERVAL=$? ???if [ $ERVAL -eq 0 ];then ???????action "uwsgid stoping ..." /bin/true ???else ???????action "uwsgid stop is error" /bin/false ???fi}case "$1" in ???start) ???????if [ $uwsgi_pn -ge 5 ];then ???????????action "uwsgi is running!" /bin/false ???????else ???????????start ???????????ERVAL=0 ???????fi ???????;; ???stop) ???????if [ $uwsgi_pn -ge 5 ];then ???????????stop ???????????ERVAL=0 ???????else ???????????action "uwsgi no running!" /bin/false ???????fi ???????;; ???reload) ???????if [ $uwsgi_pn -ge 5 ];then ???????????$uwsgi --reload $uwsgi_pid >&/dev/null ???????????ERVAL=$? ???????????[ $ERVAL -eq 0 ] && action "uwsgi reloading ..." /bin/true ???????else ???????????action "uwsgi reload error" /bin/false ???????fi ???????;; ???restart) ???????stop ???????sleep 2 ???????start ???????;; ???*) ???????echo $"Usage: $0 {start|stop|restart|reload|status}" ???????ERVAL=2esacexit $ERVAL
centOS7 system系统服务脚本:
#cat uwsgi.service [Unit]Description=uwsgi serviceAfter=network.target[Service]Type=forkingPIDFile=/run/uwsgi.pidExecStartPre=/usr/bin/rm -f /run/uwsgi.pidExecStart=/usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.iniExecReload=/bin/kill -s HUP $MAINPIDKillSignal=SIGQUITTimeoutStopSec=5KillMode=processPrivateTmp=true[Install]WantedBy=multi-user.target
测试服务:
#uwsgi --ini /djproject/mysite/uwsgi.ini ???#启动服务#ps -ef|grep "uwsgi" ??#查看进程root ????103596 ?????1 ?2 16:02 ? ???????00:00:00 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.iniroot ????103598 103596 ?0 16:02 ? ???????00:00:00 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.iniroot ????103599 103596 ?0 16:02 ? ???????00:00:00 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini#netstat -lntp|grep "uwsgi"tcp ???????0 ?????0 127.0.0.1:9090 ?????????0.0.0.0:* ??????????????LISTEN ?????103596/uwsgi ???????tcp ???????0 ?????0 127.0.0.1:9001 ?????????0.0.0.0:* ??????????????LISTEN ?????103596/uwsgi
看上面进程是少了一个主进程,通过systemctl 查看就清楚了:
#systemctl status -l uwsgi.service ● uwsgi.service - uwsgi service ??Loaded: loaded (/usr/lib/systemd/system/uwsgi.service; disabled; vendor preset: disabled) ??Active: active (running) since 五 2018-05-25 16:02:06 CST; 4min 14s ago ?Process: 103593 ExecStart=/usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini (code=exited, status=0/SUCCESS) ?Process: 103591 ExecStartPre=/usr/bin/rm -f /run/uwsgi.pid (code=exited, status=0/SUCCESS) Main PID: 103596 (uwsgi) ??CGroup: /system.slice/uwsgi.service ??????????├─103596 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini ??????????├─103598 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini ??????????└─103599 /usr/local/python356/bin/uwsgi --ini /djproject/mysite/uwsgi.ini5月 25 16:02:06 ZPY systemd[1]: Starting uwsgi service...5月 25 16:02:06 ZPY uwsgi[103593]: [uWSGI] getting INI configuration from /djproject/mysite/uwsgi.ini5月 25 16:02:06 ZPY systemd[1]: PID file /run/uwsgi.pid not readable (yet?) after start.5月 25 16:02:06 ZPY systemd[1]: Started uwsgi service.
4、安装nginx
这里采用yum安装nginx:
yum -y install nginx
配置nginx与uwsgi代理:
user nginx;worker_processes auto;error_log /var/log/nginx/error.log;pid /run/nginx.pid;# Load dynamic modules. See /usr/share/nginx/README.dynamic.include /usr/share/nginx/modules/*.conf;events { ???worker_connections 1024;}http { ???log_format ?main ?‘$remote_addr - $remote_user [$time_local] "$request" ‘ ?????????????????????‘$status $body_bytes_sent "$http_referer" ‘ ?????????????????????‘"$http_user_agent" "$http_x_forwarded_for"‘; ???access_log ?/var/log/nginx/access.log ?main; ???sendfile ???????????on; ???tcp_nopush ?????????on; ???tcp_nodelay ????????on; ???keepalive_timeout ??65; ???types_hash_max_size 2048; ???include ????????????/etc/nginx/mime.types; ???default_type ???????application/octet-stream; ???# Load modular configuration files from the /etc/nginx/conf.d directory. ???# See http://nginx.org/en/docs/ngx_core_module.html#include ???# for more information. ???include /etc/nginx/conf.d/*.conf;server { ???listen 80; ???server_name localhost; ???charset ????utf-8; ???access_log ?????/var/log/nginx/nginx_access.log main; ???error_log ??????/var/log/nginx/nginx_error.log; ???client_max_body_size 75M; ???location /static { ???????alias /djproject/mysite/static; ?#指定django的静态文件 ???????} ???location / { ???????include ????/etc/nginx/uwsgi_params; ?#加载uwsgi模块 ???????uwsgi_pass ?127.0.0.1:9090; ??#所有请求转到9090端口交给uwsgi处理 ???????} ???}}
5、安装Django
#pip3 install django
#ln -s /usr/local/python356/bin/django-admin /usr/local/bin/django-admin
创建项目:
#django-admin startproject mysite
创建app:
#cd mysite/#django-admin startapp app01
先建立个测试文件:
#cat settings.pyALLOWED_HOSTS = [‘192.168.146.139‘] ?#添加本地IP,外网访问#cat urls.py from django.contrib import adminfrom django.urls import pathfrom app01 import views ??#导入app01视图urlpatterns = [ ???path(‘admin/‘, admin.site.urls), ???path(‘‘,views.index,name=‘index‘), ?#添加路由]#cat ../app01/views.pyfrom django.shortcuts import renderfrom django.http import HttpResponse# Create your views here.def index(request): ???#添加视图函数 ?return HttpResponse(‘hello world‘)
重新加载uwsgi:
#uwsgi --reload uwsgi.pid
访问:http://192.168.146.139 能显示“hello world”说明环境部署成功了。
(1)配置Django模版文件的使用:
首先必须在项目的setting文件中配置templates模版文件的搜索路径;找到TEMPLATES项,在DIRS中写入模版搜索路径:
‘DIRS‘: [os.path.join(BASE_DIR,‘templates‘)], ??#此处为项目目录下的templates
配置home路由,在视图中使用render渲染模版文件,然后建立模版文件进行测试。
#vim app01/views.pydef home(request): ?return render(request,‘app01/home.html‘)#vim mysite/urls.pyurlpatterns = [ ???path(‘home/‘,views.home),]#mkdir -p templates/app01#vim templates/app01/home.html<!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<title>test</title></head><body><h1>this is test file</h1></body></html>
测试:http://192.168.146.139/home
(2)配置djando静态文件加载
首先在django的项目文件中,打开setting.py,找到STATIC_URL填写搜索路径
#STATIC_URL = ‘/static/‘ ??#在linux下这两种写法都可以,在windows系统下必须两种都要写上,不知何解!STATICFILES_DIRS = ( ???????os.path.join(BASE_DIR,‘static‘),)#在模块中引入静态文件时,必须是/static,此静态文件在项目下面<script src="/static/jquery-3.3.1.js"></script>
6、MySQL安装配置
#下载二进制包安装wget https://downloads.mysql.com/archives/get/file/mysql-5.5.32-linux2.6-x86_64.tar.gztar zxvf mysql-5.5.32-linux2.6-x86_64.tar.gzmv mysql-5.5.32-linux2.6-x86_64 /usr/local/mysql-5.5.32ln -s /usr/local/mysql-5.5.32 /usr/local/mysqluseradd -s /sbin/nologin -M mysqlmkdir /mysql/data -pchown -R mysql.mysql /mysql/datacd /usr/local/mysql#添加配置文件和启动脚本cp support-files/my-small.cnf /etc/my.cnfcp support-files/mysql.server /etc/init.d/mysqld#初始化数据库./scripts/mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/mysql/data/echo $?#修改启动脚本路径sed -i ‘s#^basedir=#basedir=/usr/local/mysql#g‘ /etc/init.d/mysqldsed -i ‘s#^datadir=#datadir=/mysql/data#g‘ /etc/init.d/mysqldchmod +x /etc/init.d/mysqld#启动和关闭MySQL/etc/init.d/mysqld start/etc/init.d/mysqld stop#方法2:/usr/local/mysql/bin/msyql_safe & ???#后台启动mysqladmin shutdown ?#优雅关闭MySQL服务#查看运行状态#netstat -lntup|grep 3306tcp ???????0 ?????0 0.0.0.0:3306 ???????????0.0.0.0:* ??????????????LISTEN ?????70099/mysqld ???????#添加系统自启动chkconfig --add mysqldchkconfig --level 345 mysqld on#添加环境变量echo "PATH=/usr/local/mysql/bin:$PATH" >> /etc/profilesource /etc/profile#修改初始化密码mysqladmin -uroot password ‘123456‘
#建立一个数据库,后面要用到MySQL [(none)]> create database django;Query OK, 1 row affected (0.00 sec)
(1)配置Django链接MySQL:
在setting中,Django默认使用的是sqlite数据库:
DATABASES = { ???‘default‘: { ???????‘ENGINE‘: ‘django.db.backends.sqlite3‘, ???????‘NAME‘: os.path.join(BASE_DIR, ‘db.sqlite3‘), ???}}
修改成MySQL数据库配置:
DATABASES = { ???????‘default‘:{ ???????‘ENGINE‘: ‘django.db.backends.mysql‘, ???????‘NAME‘: ‘django‘, ???????‘USER‘: ‘root‘, ???????‘PASSWORD‘: ‘123.com‘, ???????‘HOST‘: ‘127.0.0.1‘, ???????‘PORT‘: ‘3306‘, ???????}}
ENGINE : 指定数据库驱动,不同的数据库这个字段不同,下面是常见的集中数据库的ENGINE的写法:
django.db.backends.postgresql ?# PostgreSQL ?django.db.backends.mysql ??????# mysql ?django.db.backends.sqlite3 ????# sqlite ?django.db.backends.oracle ?????# oracle
#yum install mysql-devel ??#安装MySQL插件#pip3 install mysqlclient ???#安装MySQL驱动
(2)通过template模版与MySQL实现简单表单交互
在app目录下的models文件中创建model类用于生成数据表:
#cat app01/models.py from django.db import models# Create your models here.class userinfo(models.Model): ???name = models.CharField(max_length=32) ???password = models.CharField(max_length=32) ???age = models.IntegerField() ???salary = models.IntegerField()
设置setting.py文件,将app加入到INSTALLED_APPS中:
INSTALLED_APPS = [ ???????‘django.contrib.admin‘, ???????‘django.contrib.auth‘, ???????‘django.contrib.contenttypes‘, ???????‘django.contrib.sessions‘, ???????‘django.contrib.messages‘, ???????‘django.contrib.staticfiles‘, ???????‘app01‘ ???????]
根据model类创建数据库表:
#cmd进入django项目路径下#python manage.py migrate #创建表结构,非model类的其他表,django所需要的#python manage.py makemigrations app名 #做数据迁移的准备如:python manage.py makemigrations app01 app01是项目中的app名字#python manage.py migrate # 执行迁移,创建medel表结构
在templages下建立模版文件:
#cat templates/app01/home.html <!DOCTYPE html><html lang="en"><head> ???<meta charset="UTF-8"> ???<title>test</title> ???<style> ???body{ ???????background-image: url(‘/static/78556.jpg‘); ???} ???</style></head><body><form action="" method="post"> ??#提交数据给自身 ?????<p><input type="text" name="username"/></p> ?????<p><input type="text" name="password"/></p> ?????<p><input type="text" name="age"/></p> ?????<p><input type="text" name="salary"/></p> ?????<p><input type="submit" value="提交"/></p></form><table border="1"> ??<thead> ??????<tr> ???????????????<th>用户名</th> ???????????????<th>密码</th> ???????????????<th>年龄</th> ???????????????<th>工资</th> ??????</tr> ??</thead> ???????????<tbody> ???????????????{% for item in data %} #循环获取传入字典数据 ???????????????<tr> ???????????????????<td>{{item.name}}</td> ???????????????????<td>{{item.password}}</td> ???????????????????<td>{{item.age}}</td> ???????????????????<td>{{item.salary}}</td> ???????????????</tr> ???????????????{% endfor %} ???????????</tbody> ???????</table><h1>this is test file</h1><script src="/static/jquery-3.3.1.js"></script></body></html>
在app下新建视图函数,与数据库交互:
#cat app01/views.py
from django.shortcuts import renderfrom django.http import HttpResponsefrom app01 import models ??#引入数据类模版# Create your views here.def home(request): ??#创建home函数处理请求 ?if request.method == "POST": ??#判断是否为post提交 ???#print(request.POST) ???models.userinfo.objects.create( ????#提交表单的数据到数据库 ???name = request.POST[‘username‘], ???password = request.POST[‘password‘], ???age = request.POST[‘age‘], ???salary = request.POST[‘salary‘],) ?data = models.userinfo.objects.all() ??#获取数据库数据 ?return render(request,‘app01/home.html‘,{‘data‘:data}) #渲染模版文件并传递数据库表给模版
#此处是以post方式提交,需要修改Django项目setting设置中的MIDDLEWARE,将csrf安全机制注销了:
MIDDLEWARE = [ ???‘django.middleware.security.SecurityMiddleware‘, ???‘django.contrib.sessions.middleware.SessionMiddleware‘, ???‘django.middleware.common.CommonMiddleware‘, ???#‘django.middleware.csrf.CsrfViewMiddleware‘, ???‘django.contrib.auth.middleware.AuthenticationMiddleware‘, ???‘django.contrib.messages.middleware.MessageMiddleware‘, ???‘django.middleware.clickjacking.XFrameOptionsMiddleware‘,]
#建立路由:
#cat mysite/urls.pyfrom django.contrib import adminfrom django.urls import pathfrom app01 import viewsurlpatterns = [ ???path(‘admin/‘, admin.site.urls), ???path(‘home/‘,views.home),]
重新启动uWSGI:
#uwsgi --stop uwsgi.pid#uwsgi --ini uwsgi.ini
#浏览器访问:http://192.168.146.139/home
#提交数据到数据库后并返回给浏览器客户端
虚拟环境搭建实例:
echo ‘PS1="[\[\e[32;40m\]\u\[\e[0m\]@\[\e[32;40m\]\h\[\e[0m\]@\[\e[33;40m\]\A\[\e[0m\]\[\e[36;40m\]\W\[\e[0m\]\[\e[35;40m\]<\#>\[\e[0m\]]\\$"‘ ~/.bashrc. ~/.bashrc#配置epel源:wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-7.repoyum clean allyum makecache#按照依赖包yum install libffi-devel openssl openssl-devel zlib-devel bzip2-devel ncurses-devel sqlite-devel readline-devel tk-devel gdbm-devel db4-devel libpcap-devel xz-devel python-devel#安装Python3.7wget https://www.python.org/ftp/python/3.7.0/Python-3.7.0.tar.xztar xvf Python-3.7.0.tar.xzmkdir -p /usr/local/python37cd Python-3.7.0./configure --prefix=/usr/local/python37/make && make installln -s /usr/local/python37/bin/python3 /usr/local/bin/python3ln -s /usr/local/python37/bin/pip3 /usr/local/bin/pip3pip3 install --upgrade pip#配置国内python源mkdir -p ~/.pipcat > ~/.pip/pip.conf << EFO[global]timeout=60index-url=https://pypi.tuna.tsinghua.edu.cn/simple[install]trusted-host=https://pypi.tuna.tsinghua.edu.cnEFO#创建虚拟环境python3 -m venv /mysitecd mysite/git clone git://github.com/kennethreitz/autoenv.gitecho ‘source /mysite/autoenv/activate.sh‘ >> ~/.bashrcsource ~/.bashrcecho "source /mysite/bin/activate" >/mysite/.env#在虚拟环境中安装Djangopip install djangodjango-admin.py startproject myblogcd myblog/#测试Djangovim /mysite/myblog/myblog/settings.pyALLOWED_HOSTS = ["*"]python manage.py runserver 0.0.0.0:8000#在虚拟环境中安装Uwsgipip install uwsgi#测试uwsgi#创建测试文件cat test.pydef application(env, start_response):start_response(‘200 OK‘, [(‘Content-Type‘,‘text/html‘)])return [b"Hello World"]uwsgi --http :9000 --wsgi-file test.py#使用uwsgi测试djangouwsgi --http :9000 --module myblog.wsgi#安装nginxyum install nginxsystemctl enable nginxsystemctl start nginx#nginx配置django和uwsgi反向代理:location /static {alias /mysite/myblog;}location / {uwsgi_pass 127.0.0.1:9000;include /etc/nginx/uwsgi_params;uwsgi_param UWSGI_DIR /mysite/myblog;uwsgi_param UWSGI_MODULE myblog.wsgi;uwsgi_param UWSGI_ENV /mysite;}#contOS7创建系统服务cat /etc/systemd/system/uwsgi.service[Unit]Description=uWSGI EmperorAfter=syslog.target[Service]ExecStart=/root/uwsgi/uwsgi --ini /etc/uwsgi/emperor.ini# Requires systemd version 211 or newerRuntimeDirectory=uwsgiRestart=alwaysKillSignal=SIGQUITType=notifyStandardError=syslogNotifyAccess=all[Install]WantedBy=multi-user.target#uwsgi配置文件:[uwsgi]socket = 127.0.0.1:9000chdir = /root/mysite/myblogmodule = myblog.wsgimaster = trueprocesses = 2threads = 2max-requests = 2000vacuum = true#home = /root/mysitedaemonize = /var/log/uwsgi/uwsgi.logstats = 127.0.0.1:9001post-buffering = 65535buffer-size = 65535harakiri-verbose = trueharakiri = 300pidfile = /run/uwsgi.pidvenv = /root/mysite/.venv#常用选项:--http ?????在指定的地址上添加http端口--http-socket ?使用HTTP协议绑定到指定的UNIX/TCP套接字上--wsgi-file ???加载WSGI文件--processes ???指定进程数--threads 指定每个进程的线程数-M --master 启用主进程--stats ?指定状态查询绑定地址端口,如:127.0.0.1:9001-s --socket ?使用默认协议绑定到指定的UNIX/TCP套接字--chdir:指定工程的绝对路径,如Django的项目路径 ?--module:指定web应用的API,如Django项目下的wsgi.py接口文件 ???--max-requests:最大请求数--daemonize:指定uWSGI日志文件路径 ???--post-buffering:设置缓冲区--buffer-size:设置缓冲区文件大小--harakiri-verbose:设置超时true为开启--harakiri:设置超时时间--uid、--gid:设置用户和组--pidfile:指定启动时的pid文件路径 ???--venv ?指定python虚拟环境
---------------------------------------------------------------------------------end
nginx+uWSGI+django+virtualenv+supervisor发布web服务器
原文地址:https://www.cnblogs.com/mjc69213/p/9818783.html