知识的分享,不该该只是展现出来,还应该解释这样作是为何...html
献给和我同样懵懂中不断汲取知识,进步的人们。前端
授人与鱼,不如授人以渔!python
Djangomysql
.基于python的一个web框架,同类框架有Flask、Tornado...
uWSGIlinux
.实现了WSGI协议的一个web服务器
web服务器和web框架nginx
.在理解uWSGI和WSGI以前,先要弄清楚web开发的两大块,web服务器和web框架。 .web服务器即用来接受客户端请求,创建链接,转发响应的程序。至于转发的内容是什么,交由web框架来处理,即处理这些业务逻辑。如查询数据库、生成实时信息等。 .Nginx就是一个web服务器,Django或flask就是web框架。
uWSGI和WSGIgit
.那么如何实现uWSGI和WSGI的配合呢?如何作到任意一个web服务器,都能搭配任意一个框架呢? 这就产生了WSGI协议。只要web服务器和web框架知足WSGI协议,它们就能相互搭配。 因此WSGI只是一个协议,一个约定。而不是python的模块、框架等具体的功能。 .而uWSGI则是实现WSGI协议的一个web服务器。即用来接受请求,转发响应的程序。 实际上,一个uWSGI的web服务器,再加上Django这样的框架,就已经能够实现网站功能了,那么为什么还须要Nginx呢?
须要Nginx的缘由github
一个普通的我的网站,访问量不大的时候,用uWSGI和Django部署是没问题的,可是一旦访问量过大,客户的请求链接就要进行长时间的等待。 这个时候就出现了分布式服务器,也就是说我用多台服务器,这些服务器都能处理请求,可是谁来分配客户的的请求链接和web服务器呢?Nginx就是这样一个管家的存在,由他分配,这其实就是Nginx的反向代理,即代理服务器。
Nginx简单介绍web
.Nginx是俄罗斯人编写的十分轻量级的HTTP服务器,Nginx以事件驱动的方式编写,因此有很是好的性能,同时也是一个很是高效的反向代理、负载平衡。其拥有匹配Lighttpd的性能,同时尚未Lighttpd的内存泄漏问题。 .nginx作为HTTP服务器,有如下几项基本特性: 处理静态文件,索引文件以及自动索引;打开文件描述符缓冲. 无缓存的反向代理加速,简单的负载均衡和容错. FastCGI,简单的负载均衡和容错. 模块化的结构。包括gzipping, byte ranges, chunked responses,以及 SSI-filter等filter。若是由FastCGI或其它代理服务器处理单页中存在的多个SSI,则这项处理能够并行运行,而不须要相互等待。 支持SSL 和 TLSSNI. .Nginx专为性能优化而开发,性能是其最重要的考量,实现上很是注重效率 。它支持内核Poll模型,能经受高负载的考验,有报告代表能支持高达 50,000个并发链接数。 .Nginx具备很高的稳定性。其它HTTP服务器,当遇到访问的峰值,或者有人恶意发起慢速链接时,也极可能会致使服务器物理内存耗尽频繁交换,失去响应,只能重启服务器。例如当前apache一旦上到200个以上进程,web响应速度就明显很是缓慢了。而Nginx采起了分阶段资源分配技术,使得它的CPU与内存占用率很是低。nginx官方表示保持10,000个没有活动的链接,它只占2.5M内存,因此相似DOS这样的攻击对nginx来讲基本上是毫无用处的。就稳定性而言,nginx比lighthttpd更胜一筹。 .Nginx支持热部署。它的启动特别容易, 而且几乎能够作到7*24不间断运行,即便运行数个月也不须要从新启动。你还可以在不间断服务的状况下,对软件版本进行进行升级。 .Nginx采用master-slave模型,可以充分利用SMP的优点,且可以减小工做进程在磁盘I/O的阻塞延迟。当采用select()/poll()调用时,还能够限制每一个进程的链接数。 .Nginx代码质量很是高,代码很规范,手法成熟, 模块扩展也很容易。特别值得一提的是强大的Upstream与Filter链。Upstream为诸如reverse proxy,与其余服务器通讯模块的编写奠基了很好的基础。而Filter链最酷的部分就是各个filter没必要等待前一个filter执行完毕。它能够把前一个filter的输出作为当前filter的输入,这有点像Unix的管线。这意味着,一个模块能够开始压缩从后端服务器发送过来的请求,且能够在模块接收完后端服务器的整个请求以前把压缩流转向客户端。
wsgi.pyredis
django项目携带的一个wsgi接口文件 若是项目名叫br_api的话,此文件就位于[br_api/br_api/wsgi.py]
相关资料
.wsgi:一种实现python解析的通用接口标准/协议,俗称web服务网关接口 须要搞清楚一点:wsgi不是服务器、Python模块、框架、API或者任何软件,它只是一种规范,描述web服务器与web程序通讯的规范。 .uwsgi:同wsgi同样,也是一种通讯协议 uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型,它与wsgi相比是两样东西。 .uWSGI:一种python web server或者能够这么称它:Server/Gatway uWSGI是实现了uWSGI和wsgi两种协议的Web服务器,负责相应python的web请求。 uWSGI实现了wsgi协议、uwsgi协议、http协议
流程
1.首先客户端向服务器发送请求,请求资源, 2.nginx做为直接对外的服务接口,接收到客户端发送过来的http请求,会解包、分析, 若是是静态文件请求就根据配置的静态文件目录,返回请求的资源, 若是是动态请求,nginx就经过配置文件,将请求传递给uWSGI,uWSGI将接收到包进行处理,并转发给wsgi,3.wsgi根据返回值进行打包,转发给uSWGI, uWSGI接收后转发给nginx,nginx最终将返回值返回给客户端(如浏览器) *.这里须要了解一点:不一样的组件之间的信息传递涉及到数据格式和协议的转换
分析
1.首先,守在最外面的nginx并非必须的,uwsgi彻底能够完成整个与浏览器(前端)交互的流程; 2.在nginx上加上安全性或其余限制,能够达到保护程序的做用; 3.uWSGI本事是内网接口,开启多个work和processes可能都不够用,而nginx能够代理堕胎uWSGI完成uWSGI的 负载均衡; 4.django在某些状况下对静态文件的处理能力不是很好,二用nginx来处理会更加高效。
首先,项目是部署在服务器上,环境是centeos,linux系统环境
使用xshell远程链接服务器搭建项目环境
yum update -y
yum -y groupinstall "Development tools" yum install openssl-devel bzip2-devel expat-devel gdbm-devel readline-devel sqlite-devel psmisc libffi-devel
1)前往用户根目录cd ~ 2)下载 或 上传 Python3.6.7 wget https://www.python.org/ftp/python/3.6.7/Python-3.6.7.tar.xz 3)解压安装包 tar -xf Python-3.6.7.tar.xz 4)进入目标文件 cd Python-3.6.7 5)配置安装路径 ./configure --prefix=/usr/local/python3 6)编译并安装 make && sudo make install 7)创建软链接:终端命令 python3,pip3 ln -s /usr/local/python3/bin/python3 /usr/bin/python3 ln -s /usr/local/python3/bin/pip3.6 /usr/bin/pip3 8)删除安装包与文件(可选) cd .. rm -rf Python-3.6.7 rm -rf Python-3.6.7.tar.xz
1)建立pip配置路径mkdir ~/.pip 2)进入目录编辑配置文件:填入下方内容 cd ~/.pip && vim pip.conf [global] index-url = http://pypi.douban.com/simple [install] use-mirrors =true mirrors =http://pypi.douban.com/simple/ trusted-host =pypi.douban.com
默认工做路径 ~/.virtualenvs
1)安装依赖 pip3 install virtualenv pip3 install virtualenvwrapper 2)创建虚拟环境软链接 ln -s /usr/local/python3/bin/virtualenv /usr/bin/virtualenv 3)配置虚拟环境服务默认启动: vim ~/.bash_profile 添加下方内容: VIRTUALENVWRAPPER_PYTHON=/usr/bin/python3 source /usr/local/python3/bin/virtualenvwrapper.sh 4)退出保存 esc >>> :wq 5)让配置文件生效 source ~/.bash_profile 使用虚拟环境部署项目 1.先建立一个虚拟环境: mkvirtualenv 虚拟环境名称 2.建立完毕会自动进入该虚拟环境,第二次进入方法 workon 虚拟环境名称 3.查看已经存在的虚拟环境 workon 4.推出当前虚拟环境 deactivate
1)前往用户根目录cd ~ 2)下载mysql57 wget http://dev.mysql.com/get/mysql57-community-release-el7-10.noarch.rpm 3)安装mysql57 yum -y install mysql57-community-release-el7-10.noarch.rpm yum -y install mysql-community-server 4)启动mysql57并查看启动状态 启动 systemctl start mysqld.service 状态 systemctl status mysqld.service 5)Mysql5.7在第一次启动会设置一个默认初始密码,须要查看root用户、登陆并修改,而后退出,从新登陆 查看 grep "password" /var/log/mysqld.log 登陆 mysql -uroot -p 修改 ALTER USER 'root'@'localhost' IDENTIFIED BY 'new password'; 退出 exit 6)建立项目数据库和独立用户(注意本地Django项目settings文件须要配置对应数据库名称和密码) 建立数据库 create database '数据库名' default charset=utf8; 建立用户并授予权限(注意密码必须包含字符、数字和特殊字符) grant 权限(create, update) on 库.表 to '帐号'@'host' identified by '密码' grant all privileges on xxx.* to 'xxx'@'%' identified by 'xxx'; grant all privileges on xxx.* to 'xxx'@'localhost' identified by 'xxx'; 刷新生效 flush privileges; 非root户查看数据库只能看到受权的数据库列表,而root能够看到所有 查看用户相关信息 select user,host,authentication_string from mysql.user;
1)前往用户根目录 cd ~ 2)下载redis-5.0.5 wget http://download.redis.io/releases/redis-5.0.5.tar.gz 3)解压安装包 tar -xf redis-5.0.5.tar.gz 4)进入目标文件 cd redis-5.0.5 5)编译环境 make 6)复制环境到指定路径完成安装 cp -r ~/redis-5.0.5 /usr/local/redis 7)配置redis能够后台启动:修改下方内容 vim /usr/local/redis/redis.conf daemonize yes 8)完成配置修改 esc0 :wq 9)创建软链接 ln -s /usr/local/redis/src/redis-server /usr/bin/redis-server ln -s /usr/local/redis/src/redis-cli /usr/bin/redis-cli 10)后台运行redis redis-server & ctrl + c 11)测试redis环境 redis-cli config set requirepass '12345' ctrl + c 12)关闭redis服务 pkill -f redis -9
1)前往用户根目录 cd ~ 2)下载nginx1.13.7 wget http://nginx.org/download/nginx-1.13.7.tar.gz 3)解压安装包 tar -xf nginx-1.13.7.tar.gz 4)进入目标文件 cd nginx-1.13.7 5)配置安装路径:/usr/local/nginx ./configure --prefix=/usr/local/nginx 6)编译并安装 make && sudo make install 7)创建软链接:终端命令 nginx ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx 8)删除安装包与文件:(非必须) rm -rf nginx-1.13.7 rm -rf nginx-1.13.7.tar.xz 9)测试Nginx环境,服务器运行nginx,本地访问服务器ip nginx 服务器绑定的域名 或 ip:80
nginx操做命令
1)启动 nginx 2)关闭nginx nginx -s stop 3)重启nginx nginx -s reload 4)查看端口,强行关闭 ps -aux|grep nginx kill <进程编号> 查看端口占用 netstat -tunlp|grep 8000
1).安装(若是是虚拟环境记得在虚拟环境下再安装一遍) pip3 install uwsgi 2).创建软链接 ln -s /usr/local/python3/bin/uwsgi /usr/bin/uwsgi 3).测试一下: 在本地新建test.py文件,写入内容 def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b"Hello World"] 而后保存复制到服务器root目录 cd ~ sudo uwsgi --http 0.0.0.0:8000 --wsgi-file test.py 本地浏览器输入http://118.25.94.126:8000/ (前面是个人公网ip) tips: 若是端口被占用,使用 lsof -i :8000 列出占用端口的程序pid号,杀掉进程再执行一遍就能够了 sudo kill -9 pid
配置以前须要环境知足要求
.python pip已安装 .django项目文件已经上传服务器,固然django已经安装完毕 .django项目所依赖的第三方模块都已经安装完毕(安装方法同与本地同样,经过pip install ***安装) django项目测试在项目目录下:python manage.py runserver 0.0.0.0:8000
3.2.3_1 nginx配置
创建工程单独的nginx配置文件
查看nginx的默认配置文件目录(nginx.conf)的路径
nginx -t
显示结果参考:
nginx: the configuration file /usr/local/nginx/conf/nginx.conf syntax is ok nginx: configuration file /usr/local/nginx/conf/nginx.conf test is successful
因此nginx默认配置文件路径为:
/usr/local/nginx/conf/nginx.conf
建立nginx配置文件
.确保nginx.conf的同目录下有[uwsgi_params]文件 使用命令cd /usr/local/nginx/conf/进行查看 .没有的话根据连接(https://github.com/nginx/nginx/blob/master/conf/uwsgi_params)获取,后面要用到。 .在本身的工程目录下(/home/project/br_api/),创建如 br_api.conf(/home/project/br_api/br_api.conf)的配置文件; 复制nginx.conf里面所有的内容,所有写入br_api.conf中。 而后按照下面写的,把所有写入br_api.conf配置文件中的server段部分所有替换掉。 ⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇
server { listen 80; server_name 127.0.0.1; charset utf-8; access_log /home/project/br_api/nginx_access.log; error_log /home/project/br_api/nginx_error.log; client_max_body_size 75M; location /static { alias /home/project/br_api/static; } location /media { alias /home/project/br_api/media; } location / { root /home/project/br_api; include /usr/local/nginx/conf/uwsgi_params; uwsgi_pass 127.0.0.1:8001; } }
替换内容说明: .listen 80 表明服务器开放80端口,也就是说外界能够经过服务器ip:80端口访问到nginx服务器,这里80端口默承认以不写 .access_log与error_log 定义nginx访问日志和错误日志的存放路径,这里我把他们所有放到项目br_api项目根目录下 .location /目录名 {} 表明项目路径的引导 .location /static {} 项目的静态文件定位配置 django静态文件的绝对路径是根据本身的实际状况来肯定的,通常在本身的django项目根目录的/static目录下,或本身python manage.py collectstatic后的路径下。 像个人是在/home/project/br_api/static下。 .location / 指访问项目根目录时,nginx要作的事。其中须要指定 uwsgi_params文件的绝对路径,上面已经提到了;若是还有media文件之类的静态目录,仿照static的写法,本身补充。 .uwsgi_pass 指uWSGI绑定的监听地址,这里使用了9090端口,这里须要和下面的uwsgi配置文件中的socket一致
3.2.3_2 uwsgi配置
项目根目录建立uwsgi.ini文件,写入如下内容
[uwsgi] socket = 127.0.0.1:8001 chdir=/home/project/br_api module=br_api.wsgi:application master = true processes=2 threads=2 max-requests=2000 chmod-socket=664 vacuum=true daemonize = /home/project/br_api/uwsgi.log
3.2.3_3 配置路径总览
项目配置 | 配置路径 |
---|---|
项目路径 | /home/project/br_api |
项目静态文件路径 | /home/project/br_api/static |
项目media文件路径 | /home/project/br_api/media |
wsgi.py的路径 | /home/project/br_api/br_api/wsgi.py |
uwsgi.ini的路径 | /home/project/br_api/uwsgi.ini |
uwsgi日志路径 | /home/project/br_api/uwsgi.log |
br_api.conf的路径 | /home/project/br_api/br_api.conf |
uwsgi_params的路径 | /usr/local/nginx/conf/uwsgi_params |
nginx访问日志路径 | /home/project/br_api/nginx_access.log |
nginx错误日志路径 | /home/project/br_api/nginx_error.log |
能够发现,我几乎把全部有关项目的配置文件和日志文件都放在该项目目录下了,方便后期维护与查错。
启动 uWSGI
sudo uwsgi --ini /home/project/br_api/uwsgi.ini
启动 nginx
.在这以前,咱们要先去nginx配置文件的根目录拷贝mime.types(/usr/local/nginx/conf/mime.types)到工程目录(/home/project/br_api/mime.types),和br_api.conf放在一块儿。 不然启动时会报错 .固然,若是不想拷贝mime.types文件,也能够将配置文件中“include mime.types;”一项,改为绝对路径“include /usr/local/nginx/conf/mime.types;” 若是nginx已经开启,先关闭nginx(service nginx stop或nginx -s stop),再执行如下命令:
若是nginx已经开启,先关闭nginx(service nginx stop或nginx -s stop),再执行如下命令: nginx -c /home/project/br_api/br_api.conf 这里的-c 表示加载配置文件启动 nginx -s reload
补充
若是出现502错误,查看uwsgi.log文件发现缺乏模块,若是是这个错误,能够在br_api/br_api/wsgi.py中添加环境变量参数:
import os, sys sys.path.append('/home/project/br_api') # 添加的2个环境变量,将第三方模块包所在目录添加进去 sys.path.append('/root/.virtualenvs/br_api/lib/python3.6/site-packages') from django.core.wsgi import get_wsgi_application os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'br_api.dev') application = get_wsgi_application()