你的位置:首页 > 信息动态 > 新闻中心
信息动态
联系我们

nginx搭建基于python的web环境

2021/12/16 9:09:19

前言:

 

在搭建开始前,我们先来梳理下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)
</span><span style="color: rgba(0, 0, 255, 1)">def</span><span style="color: rgba(0, 0, 0, 1)"> set_response_header(self, status, headers):
    self.status </span>=<span style="color: rgba(0, 0, 0, 1)"> status
    self.headers </span>= [(<span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">server</span><span style="color: rgba(128, 0, 0, 1)">"</span>, <span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(128, 0, 0, 1)">WSGI_simple_web v1.0</span><span style="color: rgba(128, 0, 0, 1)">"</span><span style="color: rgba(0, 0, 0, 1)">)]
    self.headers </span>+=<span style="color: rgba(0, 0, 0, 1)"> headers

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

 

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 </span>10.10.10.29:8888<span style="color: rgba(0, 0, 0, 1)">;

}

server {

listen       </span>80<span style="color: rgba(0, 0, 0, 1)">;

server_name  localhost;



</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">charset koi8-r;</span>

<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">access_log  /var/log/nginx/host.access.log  main;</span>
location </span>/<span style="color: rgba(0, 0, 0, 1)"> {

    proxy_pass http:</span>//uwsgi; <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 通过反向代理和uWSGI服务器关联</span>
}

}

复制代码

 

方式二(本地模式):

复制代码
server {
listen       </span>8080<span style="color: rgba(0, 0, 0, 1)">;

server_name  localhost;



</span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">charset koi8-r;</span>

<span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)">access_log  /var/log/nginx/host.access.log  main;</span>
location </span>/<span style="color: rgba(0, 0, 0, 1)"> {

    include uwsgi_params; </span><span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 指定nginx和uWSGI服务器的通信方式</span>
uwsgi_connect_timeout 30 ;
    uwsgi_pass unix:</span>/opt/test/script/uwsgi.sock;    <span style="color: rgba(0, 128, 0, 1)">#</span><span style="color: rgba(0, 128, 0, 1)"> 通过sock文件和uWSGI服务器关联! 因为nginx会去读取.sock文件,所以<strong>需要关闭selinux才行</strong>!!!</span>
}

}

复制代码

 

 

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   </span>/opt/test/test1/static_file/<span style="color: rgba(0, 0, 0, 1)">;

}

 

 

 

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

https://www.cnblogs.com/baihualin/p/12133856.html