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获取当前页面内所有链接的四种方法对比分析
Aug 19 Python
python实现SOM算法
Feb 23 Python
Python cookbook(数据结构与算法)筛选及提取序列中元素的方法
Mar 19 Python
python实现京东秒杀功能
Jul 30 Python
Python遍历文件夹 处理json文件的方法
Jan 22 Python
python实现合并两个排序的链表
Mar 03 Python
Python3字符串encode与decode的讲解
Apr 02 Python
导入tensorflow时报错:cannot import name 'abs'的解决
Oct 10 Python
Python selenium自动化测试模型图解
Apr 15 Python
Pycharm插件(Grep Console)自定义规则输出颜色日志的方法
May 27 Python
python3中celery异步框架简单使用+守护进程方式启动
Jan 20 Python
python使用pywinauto驱动微信客户端实现公众号爬虫
May 19 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/09/02 PHP
CentOS下搭建PHP环境与WordPress博客程序的全流程总结
2016/05/07 PHP
浅析PHP7 的垃圾回收机制
2019/09/06 PHP
js实现图片轮换效果代码
2013/04/16 Javascript
jquery sortable的拖动方法示例详解
2014/01/16 Javascript
对JavaScript中this指针的新理解分享
2015/01/31 Javascript
Javascript中的方法链(Method Chaining)介绍
2015/03/15 Javascript
JavaScript代码性能优化总结篇
2016/05/15 Javascript
BootStrap 下拉菜单点击之后不会出现下拉菜单(下拉菜单不弹出)的解决方案
2016/12/14 Javascript
JS原生轮播图的简单实现(推荐)
2017/07/22 Javascript
Node.js 多线程完全指南总结
2019/03/27 Javascript
用jQuery实现抽奖程序
2020/04/12 jQuery
Python对两个有序列表进行合并和排序的例子
2014/06/13 Python
Python最火、R极具潜力 2017机器学习调查报告
2017/12/11 Python
python实现远程通过网络邮件控制计算机重启或关机
2018/02/22 Python
使用Python通过win32 COM打开Excel并添加Sheet的方法
2018/05/02 Python
python机器学习之神经网络实现
2018/10/13 Python
深入浅析Python 中 is 语法带来的误解
2019/05/07 Python
详解利用Python scipy.signal.filtfilt() 实现信号滤波
2019/06/05 Python
python networkx 根据图的权重画图实现
2019/07/10 Python
解决Django 在ForeignKey中出现 non-nullable field错误的问题
2019/08/06 Python
python os.path.isfile()因参数问题判断错误的解决
2019/11/29 Python
python UDF 实现对csv批量md5加密操作
2021/01/01 Python
纯CSS绘制漂亮的圆形图案效果
2014/05/07 HTML / CSS
使用SVG实现提示框功能的示例代码
2020/06/05 HTML / CSS
爱尔兰家电数码商城:Currys PC World爱尔兰
2016/07/23 全球购物
一个精品风格的世界:Atterley
2019/05/01 全球购物
环保倡议书300字
2014/05/15 职场文书
学校安全防火方案
2014/06/07 职场文书
运输企业安全生产责任书
2014/07/28 职场文书
扶贫办主任查摆“四风”问题个人对照检查材料思想汇报
2014/10/02 职场文书
水知道答案观后感
2015/06/08 职场文书
施工现场安全管理制度
2015/08/05 职场文书
公司会议开幕词
2016/03/03 职场文书
2019年中,最受大众欢迎的6本新书
2019/08/07 职场文书
Spring Data JPA的Audit功能审计数据库的变更
2021/06/26 Java/Android