nginx搭建基于python的web环境的实现步骤
作者:白桦林_HK 发布时间:2023-07-27 07:06:49
前言:
在搭建开始前,我们先来梳理下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应用之间加一层支持WSGI协议的web服务器。以后静态文件由nginx进行处理,动态文件丢给WSGI服务器,然后WSGI服务器再丢给web框架处理。最理想的支持WSGI协议的web服务器就是uWSGI。
下面来详细介绍下搭建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网站了
来源:https://www.cnblogs.com/baihualin/p/12133856.html


猜你喜欢
- 简介查看百度搜索中文文本聚类我失望的发现,网上竟然没有一个完整的关于Python实现的中文文本聚类(乃至搜索关键词python 中文文本聚类
- 最小生成树的Prim算法也是贪心算法的一大经典应用。Prim算法的特点是时刻维护一棵树,算法不断加边,加的过程始终是一棵树。Prim算法过程
- cv2库在opencv库内,因此需要下载opencv-python1、打开windows命令行:win+Rcmd2、更新pip版本(不一定要
- 如果你使用的正是mysql数据库,那么你把密码或者其他敏感重要信息保存在应用程序里的机会就很大。保护这些数据免受黑客或者窥探者的获取是一个令
- 这篇文章主要介绍了Python文本处理简单易懂方法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋
- 在开始之前,我们先来看看uint 与 int 的区别上面是图,下面是源码:package main import ( "fmt&q
- 新项目,准备引用bootstrap-table这个控件来展示页面上的表格,无奈这款控件的分页工具栏没有跳转到xx页的功能,为了适应公司美工(
- 图的实现所谓图就是节点及其连接关系的集合。所以可以通过一个一维数组表示节点,外加一个二维数组表示节点之间的关系。//图的矩阵实现typede
- itertools.product:类似于求多个可迭代对象的笛卡尔积。使用的形式是:itertools.product(*iterables
- range(x)range(9) 代表着0、1、2、3、4、5、6、7、8 这九个顺序数字的集合。也就是 range(9) => ra
- 在介绍Python的self用法之前,先来介绍下Python中的类和实例……我们知道,面向对象最
- 本文实例讲述了jQuery实现弹出带遮罩层的居中浮动窗口效果。分享给大家供大家参考,具体如下:<!doctype html>&l
- 1 圆点选择选项设置效果展示代码参考#!/usr/bin/python# -*- coding:utf-8 -*-import sysfro
- 做一个简单的小实例:目录结构如下:demo1.pyclass MyClass():def __init__(self,x,y):  
- declare @id  
- 用JDBC实现对MySQL的“增删改查”:import java.sql.Connection;im
- 不知道从什么时候开始,在网络上到处可以看到div+css,到底什么是div+css呢?难道就是传说中的标准重构吗?标准从最简单的根源来说不是
- 语义分割是对图像中的每一个像素进行分类,从而完成图像分割的过程。分割主要用于医学图像领域和无人驾驶领域。和其他算法一样,图像分割发展过程也经
- 数据采集我们上一篇介绍了,如何采集电影评论,看看这个电影好不好看.今天,我们来采集大家熟悉的百度贴吧的排行榜。发送请求我们首先确定我们的目标
- 1. 加载数据集这次我们搭建一个小小的多层线性网络对糖尿病的病例进行分类首先先导入需要的库文件先来看看我们的数据集观察可以发现,前八列是我们