nginx搭建基于python的web环境的实现步骤


Posted in Python onJanuary 03, 2020

前言:

在搭建开始前,我们先来梳理下web服务工作流程,先看下图:

nginx搭建基于python的web环境的实现步骤

1、用户(PC)向web服务器发起http请求

2、web服务器判断用户请求文件是否为静态文件,是则直接读取静态文件并返回给用户,不是则通过WSGI协议将请求丢给web框架(django)代码处理

3、看web框架是否启动django中间件,如果启用,则依据中间件对请求进行修改,如果不启用,则进入下一步

4、web框架中的路由程序将根据请求中的url文件名将请求路由至相应py文件

5、相应py文件收到请求后根据用户提交的参数进行计算(期间可能会调用数据库),然后返回计算后的结果和自定义头部信息以及状态码返回

6、web框架将返回的数据打上通用标识符(头部信息)后返回给web服务器

7、web服务器打上web服务器的通用标识符(头部信息)后返回给用户

8、用户收到返回的数据

通过上面可以看到django框架基于WSGI协议和web服务器进行交互,那么WSGI协议又是什么呢? 咱们用代码来说明(伪代码。写一个简易的遵循WSGI协议的web服务器软件和django程序):

WSGI服务器的程序:

class WSGI_WEB(object):
 def __init__(self):
 # 1. 创建套接字
 self.tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 self.tcp_server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 # 2. 绑定
 self.tcp_server_socket.bind(("", 7890))
 # 3. 变为监听套接字
 self.tcp_server_socket.listen(128)

 def set_response_header(self, status, headers):
 self.status = status
 self.headers = [("server", "WSGI_simple_web v1.0")]
 self.headers += headers

 def run(self):
 new_socket, client_addr = self.tcp_server_socket.accept()
 env = new_socket.recv(1024)
 body = application(env, set_response_header) # env是web服务器接收到浏览器发送来的数据包;set_response_header为web服务器的一个方法地址,目的是让django帮web服务器生成http头部(不是以return的形式给web服务器);此外还有这里调用django里的应用还有一个最核心的任务,就是获取返回数据的body!
 header = self.status + self.headers
 response = header + body  
 new_socket.send(response.encode("utf-8"))

django的app程序:

def application(env, start_response):
 start_response('200 OK', [('Content-Type','text/html')])
 return [b"Hello World"]

问题:

在生产环境中使用django提供的简易web服务器性能太差,一般只用于调试。强大的nginx又不支持WSGI,那么怎么办呢?

nginx搭建基于python的web环境的实现步骤

方案:

在nginx和python应用之间加一层支持WSGI协议的web服务器。以后静态文件由nginx进行处理,动态文件丢给WSGI服务器,然后WSGI服务器再丢给web框架处理。最理想的支持WSGI协议的web服务器就是uWSGI。

nginx搭建基于python的web环境的实现步骤

下面来详细介绍下搭建uWSGI服务器以及与nginx联动的方法:

1、安装uWSGI(支持WSGI的WEB服务器):

centos下python3.6安装uWSGI方法:

yum install -y gcc* pcre-devel openssl-devel python36-devel.x86_64

pip3.6 install uwsgi

2、开启uWSGI服务

方式一:

uwsgi --http 192.168.31.123:80 --file teacher/wsgi.py --static-map=/static=static

--http 监听IP端口

--file 项目wsgi.py文件路径

--static-map 静态文件路径

注意: 执行这条命令的时候:一定要在这个项目目录中~ 

方式二(使用配置文件):

vi uwsgi.ini:

[uwsgi]

# 监听端口(nginx采用反向代理模式时必填)

http = 0.0.0.0:8888


# 项目目录

chdir=/opt/test/test1/


# 启动uwsgi的用户名和用户组

uid=root

gid=root


# 指定项目的application(我猜是这里的“test1.wsgi”拼接上面的项目目录后,就将项目中的wsgi.py文件和uWSGI服务器关联起来了)

module=test1.wsgi:application

 
# 指定sock的文件路径(nginx采用本地模式时必填)

socket=/opt/test/script/uwsgi.sock

 
# 启用主进程

master=true


# 进程个数

workers=5

pidfile=/opt/test/script/uwsgi.pid


# 自动移除unix Socket和pid文件当服务停止的时候

vacuum=true


# 序列化接受的内容,如果可能的话

thunder-lock=true


# 启用线程

enable-threads=true

 
# 设置自中断时间

harakiri=30

 
# 设置缓冲

post-buffering=4096

 
# 设置日志目录

daemonize=/opt/test/script/uwsgi.log

 
# 设置隔多久加载一次项目代码

py-autoreload=1


执行配置文件(注意:这里用什么账户执行的,以后渗透进来获取到的就是什么账户。所以这一步切忌不要用root执行。):

uwsgi --ini uwsgi.ini

彩蛋:

重启uWSGI进程: uwsgi --reload uwsgi.pid  # 代码做变更后uWSGI进程不会立即加载,此时可以重启一下uWSGI进程让它生效。。。是不是感觉有点坑,没事,可以在配置文件中设置py-autoreload

关闭uWSGI进程: uwsgi --stop uwsgi.pid

3、配置nginx

方式一(反向代理模式):

upstream uwsgi{

 server 10.10.10.29:8888;

}

 

server {

 listen 80;

 server_name localhost;

 

 #charset koi8-r;

 #access_log /var/log/nginx/host.access.log main;

 

 location / {

 proxy_pass http://uwsgi; # 通过反向代理和uWSGI服务器关联

 }

}

方式二(本地模式):

server {

 listen 8080;

 server_name localhost;

 

 #charset koi8-r;

 #access_log /var/log/nginx/host.access.log main;

 

 location / {

 include uwsgi_params; # 指定nginx和uWSGI服务器的通信方式

 uwsgi_connect_timeout 30;

 uwsgi_pass unix:/opt/test/script/uwsgi.sock; # 通过sock文件和uWSGI服务器关联! 因为nginx会去读取.sock文件,所以需要关闭selinux才行!!!

 }

}

4、此时访问django的admin管理后台时,静态资源会调取失败。这时可以将该项目所有静态资源统一收集到一个文件夹下,然后由nginx统一去调取,真正做到动静分离(动的给uWSGI,静的由nginx直接调取):

在settings.py中加入:

TATIC_ROOT = os.path.join(BASE_DIR, 'static_file')

执行如下命令(搜集项目中所有静态文件至'static_file'目录):

python3.6 manage.py collectstatic --noinput

此时会在项目目录下生成一个'static_file'文件夹,内含admin和所有app涉及的静态文件 。

在nginx中配置静态文件路径(如果nginx和uWSGI不属同一台服务器可以使用反向代理的方式来调取静态文件):

location /static/ {

 alias /opt/test/test1/static_file/;

}

此时就可以访问基于python后台的web网站了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python基础教程之Hello World!
Aug 29 Python
python通过openpyxl生成Excel文件的方法
May 12 Python
python制作企业邮箱的爆破脚本
Oct 05 Python
基于Django的python验证码(实例讲解)
Oct 23 Python
Python文本处理之按行处理大文件的方法
Apr 09 Python
利用python脚本如何简化jar操作命令
Feb 24 Python
python+logging+yaml实现日志分割
Jul 22 Python
Pytorch中index_select() 函数的实现理解
Nov 19 Python
Pytorch保存模型用于测试和用于继续训练的区别详解
Jan 10 Python
Pyspark读取parquet数据过程解析
Mar 27 Python
Django Admin后台模型列表页面如何添加自定义操作按钮
Nov 11 Python
Python应用自动化部署工具Fabric原理及使用解析
Nov 30 Python
Python如何使用字符打印照片
Jan 03 #Python
Pytorch.nn.conv2d 过程验证方式(单,多通道卷积过程)
Jan 03 #Python
如何基于python实现画不同品种的樱花树
Jan 03 #Python
Python基础之变量基本用法与进阶详解
Jan 03 #Python
PyTorch里面的torch.nn.Parameter()详解
Jan 03 #Python
Python实现银行账户资金交易管理系统
Jan 03 #Python
Pytorch提取模型特征向量保存至csv的例子
Jan 03 #Python
You might like
php实现文件下载简单示例(代码实现文件下载)
2014/03/10 PHP
javascript 操作Word和Excel的实现代码
2009/10/26 Javascript
Jquery Ajax学习实例 向页面发出请求,返回XML格式数据
2010/03/14 Javascript
jQuery Tips 为AJAX回调函数传递额外参数的方法
2010/12/28 Javascript
javascript中interval与setTimeOut的区别示例介绍
2014/03/14 Javascript
JS 排序输出实现table行号自增前端动态生成的tr
2014/08/13 Javascript
javascript格式化日期时间方法汇总
2015/06/19 Javascript
JS实现的自定义右键菜单实例二则
2015/09/01 Javascript
WordPress中利用AJAX异步获取评论用户头像的方法
2016/01/08 Javascript
基于JS判断iframe是否加载成功的方法(多种浏览器)
2016/05/13 Javascript
Node.js的文件权限及读写flag详解
2016/10/11 Javascript
jQuery通过ajax快速批量提交表单数据
2016/10/25 Javascript
vue移动UI框架滑动加载数据的方法
2018/03/12 Javascript
Vue路由切换时的左滑和右滑效果示例
2018/05/29 Javascript
Vue 路由切换时页面内容没有重新加载的解决方法
2018/09/01 Javascript
微信小程序实现加入购物车滑动轨迹
2020/11/18 Javascript
详解uniapp的全局变量实现方式
2021/01/11 Javascript
Python用模块pytz来转换时区
2016/08/19 Python
python实现简单爬虫功能的示例
2016/10/24 Python
Python实现扣除个人税后的工资计算器示例
2018/03/26 Python
Python基于opencv的图像压缩算法实例分析
2018/05/03 Python
使用python爬虫获取黄金价格的核心代码
2018/06/13 Python
详解Python 协程的详细用法使用和例子
2018/06/15 Python
Python hmac模块使用实例解析
2019/12/24 Python
Python实现加密的RAR文件解压的方法(密码已知)
2020/09/11 Python
Python APScheduler执行使用方法详解
2020/12/10 Python
详解tf.device()指定tensorflow运行的GPU或CPU设备实现
2021/02/20 Python
HTML5 Canvas如何实现纹理填充与描边(Fill And Stroke)
2013/07/15 HTML / CSS
HTML5新特性之type=file文件上传功能
2018/02/02 HTML / CSS
会计实习生自我鉴定
2013/12/12 职场文书
应聘编辑职位自荐信范文
2014/01/05 职场文书
质量负责人任命书
2014/06/06 职场文书
2015年置业顾问工作总结
2015/04/07 职场文书
三八节祝酒词
2015/08/11 职场文书
党员反腐倡廉学习心得体会
2015/08/15 职场文书
Apache POI的基本使用详解
2021/11/07 Servers