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实现给数组按片赋值的方法
Jul 28 Python
Python的Socket编程过程中实现UDP端口复用的实例分享
Mar 19 Python
python3音乐播放器简单实现代码
Apr 20 Python
Python 将pdf转成图片的方法
Apr 23 Python
python中copy()与deepcopy()的区别小结
Aug 03 Python
将python图片转为二进制文本的实例
Jan 24 Python
Python 获取 datax 执行结果保存到数据库的方法
Jul 11 Python
Python 用turtle实现用正方形画圆的例子
Nov 21 Python
Python猫眼电影最近上映的电影票房信息
Sep 18 Python
关于python scrapy中添加cookie踩坑记录
Nov 17 Python
Python tensorflow卷积神经Inception V3网络结构
May 06 Python
python playwright之元素定位示例详解
Jul 23 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
【动漫杂谈】关于《请在T台上微笑》
2020/03/03 日漫
CodeIgniter php mvc框架 中国网站
2008/05/26 PHP
关于初学PHP时的知识积累总结
2013/06/07 PHP
PHP 快速排序算法详解
2014/11/10 PHP
CI框架常用方法小结
2016/05/17 PHP
PHP简单获取随机数的常用方法小结
2017/06/07 PHP
浅谈PHP发送HTTP请求的几种方式
2017/07/25 PHP
JavaScipt基本教程之JavaScript语言的基础
2008/01/16 Javascript
JS中如何设置readOnly的值
2013/12/25 Javascript
js出生日期 年月日级联菜单示例代码
2014/01/10 Javascript
angularJS与bootstrap结合实现动态加载弹出提示内容
2015/10/16 Javascript
全面解析JavaScript里的循环方法之forEach,for-in,for-of
2020/04/20 Javascript
JS实现物体带缓冲的间歇运动效果示例
2016/12/22 Javascript
详解vue项目优化之按需加载组件-使用webpack require.ensure
2017/06/13 Javascript
Vue.set() this.$set()引发的视图更新思考及注意事项
2018/08/30 Javascript
详解关于Vuex的action传入多个参数的问题
2019/02/22 Javascript
微信小程序后台持续定位功能使用详解
2019/08/23 Javascript
vue中使用element组件时事件想要传递其他参数的问题
2019/09/18 Javascript
Vue.js组件通信之自定义事件详解
2019/10/19 Javascript
[02:18]DOTA2英雄基础教程 育母蜘蛛
2014/01/20 DOTA
[01:19]DOTA2城市挑战赛报名开始 开启你的城市传奇
2018/03/23 DOTA
寻找网站后台地址的python脚本
2014/09/01 Python
python使用Matplotlib画条形图
2020/03/25 Python
对python3 sort sorted 函数的应用详解
2019/06/27 Python
python图形开发GUI库wxpython使用方法详解
2020/02/14 Python
法国时尚品牌乐都特瑞士站:La Redoute瑞士
2016/09/05 全球购物
Java平台和其他软件平台有什么不同
2015/06/05 面试题
机电一体化专业应届本科生求职信
2013/09/27 职场文书
大学生专科学习生活的自我评价
2013/12/07 职场文书
商场拾金不昧表扬信
2014/01/13 职场文书
幼儿园庆六一活动方案
2014/03/06 职场文书
认错检讨书
2014/10/02 职场文书
创先争优承诺书
2015/01/20 职场文书
常住证明范本
2015/06/23 职场文书
2016年记者节感言
2015/12/08 职场文书
Vue3.0写自定义指令的简单步骤记录
2021/06/27 Vue.js