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

前言:

在搭建开始前,我们先来梳理下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网站了

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

(0)

相关推荐

  • nginx worker进程循环的实现

    worker进程启动后,其首先会初始化自身运行所需要的环境,然后会进入一个循环,在该循环中不断检查是否有需要执行的事件,然后处理事件.在这个过程中,worker进程也是需要与master进程交互的,更有甚者,worker进程作为一个子进程,也是可以接收命令行指令(比如kill等)以进行相应逻辑的处理的.那么worker进程是如何与master或者命令行指令进行交互的呢?本文首先会对worker进程与master进程交互方式,以及worker进程如何处理命令行指令的流程进行讲解,然后会从源码上对w

  • nginx 负载均衡 多站点共享Session

    多站点共享Session常见的作法有: •使用.net自动的状态服务(Asp.net State Service); •使用.net的Session数据库: •使用Memcached. •使用Cookie方式实现多个站点间的共享(这种方式只限于几个站点都在同一域名的情况下): 这里我们就 演练一下 以数据库的形来存储Session,来实现多站点共享Session. 首先我们 建好一下站点,如下图: Default.aspx 其中 有二个Button  ,SetSession 主要是用于给一个 S

  • nginx+tomcat实现负载均衡,使用redis session共享

    环境准备 1.准备一台nginx服务器 ip192.168.1.133 端口81 安装过程: #首先安装依赖: yum -y install gcc-c++ yum -y install pcre pcre-devel yum -y install zlib zlib-devel yum -y install openssl openssl-devel #注意 : 安装nginx必须使用 root 用户安装 #创建一个nginx目录 mkdir /usr/local/src/nginx #进入到

  • Nginx根据url中的path动态转发到upstream的实现

    在Nginx中,有一些高级场景,需要根据url中的path参数,动态转发到不通的upstream 场景1 /svr1/xxxx?yyy 转发到 svr1:8080/xxxx?yyy /svr2/xxxx?yyy 转发到 svr2:8080/xxxx?yyy 配置如下: location ~* /(srv[1-9]+)/(.*)$ { allow all; proxy_pass http://$1/$2$is_args$args; proxy_set_header Host $host; prox

  • Nginx Session共享问题解决方案解析

    这篇文章主要介绍了Nginx Session共享问题解决方案解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Nginx解决Session共享问题: 1.nginx或者haproxy做的负载均衡,用nginx做的负载均衡可以添加ip_hash这个配置:用haproxy做的负载均衡可以用balance source这个配置,从而使用一个IP的请求发到同一个服务器: 2.利用数据库同步session: 3.利用cookie同步session数据,

  • Nginx+Tomcat关于Session的管理的实现

    前言 Nginx+Tomcat对Session的管理一直有了解,但是一直没有实际操作一遍,本文从最简单的安装启动开始,通过实例的方式循序渐进的介绍了几种管理session的方式. nginx安装配置 1.安装nginx [root@localhost ~]# yum install nginx 提示报如下错误: No package nginx available. 解决办法安装epel:EPEL是企业版 Linux 附加软件包的简称,EPEL是一个由Fedora特别兴趣小组创建.维护并管理的,

  • 详解Nginx轮询算法底层实现的方法

    轮询算法简介 在工作中很多人都使用到了nginx,对nginx得配置也是烂熟于心,今天我主要想介绍一下nginx轮询算法得几种底层实现方式. 简单轮询算法 这种算法比较简单,举个例子就是你有三台服务器 第一台服务器 192.168.1.1 第二台服务器 192.168.1.2 第三台服务器 192.168.1.3 第一个请求过来之后默认访问第一台,第二个请求过来访问第二台,第三次请求过来访问第三台,第四次请求过来访问第一台,以此类推.以下是我代码实现简单得算法: public class Sim

  • Nginx中共享session会话配置方法例子

    Session一般都指时域.在计算机术语中,Session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间以及如果需要的话,可能还有一定的操作空间. Session一般都指时域.在计算机术语中,Session是指一个终端用户与交互系统进行通信的时间间隔,通常指从注册进入系统到注销退出系统之间所经过的时间以及如果需要的话,可能还有一定的操作空间. 通常情况下能把session改成cookie,就能避开session的一些弊端,在从前看的一本J2EE的

  • 详解Nginx反向代理实现会话(session)保持的两种方式

    一.ip_hash: ip_hash使用源地址哈希算法,将同一客户端的请求总是发往同一个后端服务器,除非该服务器不可用. ip_hash语法: upstream backend { ip_hash; server backend1.example.com; server backend2.example.com; server backend3.example.com down; server backend4.example.com; } ip_hash简单易用,但有如下问题: 当后端服务器宕

  • nginx+redis实现session共享

    上一篇我们介绍了nginx实现的负载均衡和动静分离,可看这边. 我们在文章的末尾说到,负载均衡需要面临的一个问题是内存数据的同步.例如:我有A,B两台服务器做了负载均衡,当我在A服务器上执行了登录并且将登录数据存入session的时候,这些session数据只存在于A服务器上,而没有在B服务器上,假如在处理下一个请求的时候,我需要用到session的数据,而不巧的是,这个请求刚好被交由B服务器来处理,这时候就会出现B服务器拿不到session数据的情况,从而造成错误. 这是一个无法避免的问题,有

随机推荐