Date Modified Tags python / uwsgi

Introduction

前面的nginx配置https一文,说明了如何在nginx上配置https,本文则作为补充,说明了在pyhon flask 或者django等web框架下,怎么配置https,以及nginx 和uWSGI的搭配。

1. 配置https

理论上,直接在nginx的站点配置文件中,声明well-known文件夹的特殊访问权限即可:

location ^~ /.well-known {
    allow all;
}

但是在实际使用中,在我怎么修改配置文件也不能成功以后,发现其实只要明白certbot的验证,实际上是从外部对http://your_domain/.well-known/acme-challenge/some_token_value的访问之后,就可以直接在你的项目里,解析这个地址即可,以python flask为例:

@main.route('/.well-known/acme-challenge/<token_value>')
def letsencrpyt(token_value):
    with open('.well-known/acme-challenge/{}'.format(token_value)) as f:
        answer = f.readline().strip()
    return answer

注意这里直接open .well-known,没有写全路径,你也可以写全路径。

2. nginx 配置uWSGI

2.1 uwsgi uWSGI WSGI nginx

WSGI是一种Web服务器网关接口。它是一个Web服务器(如nginx)与应用服务器(如uWSGI服务器)通信的一种规范。

uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http等协议。

Nginx中HttpUwsgiModule的作用是与uWSGI服务器进行交换。

WSGI vs uwsgi(小写) vs uWSGI ?

uwsgi同WSGI一样是一种通信协议,而uWSGI是实现了uwsgi和WSGI两种协议的Web服务器。

uwsgi协议是一个uWSGI服务器自有的协议,它用于定义传输信息的类型(type of information),每一个uwsgi packet前4byte为传输信息类型描述,它与WSGI相比是两样东西。

有了uWSGI为什么还需要nginx?

nginx具备优秀的静态内容处理能力,然后将动态内容转发给uWSGI服务器,这样可以达到很好的客户端响应。

2.2 uWSGI安装使用

2.2.1 uWSGI配置文件

pip3 install uwsgi后,根据你的项目编写config文件:

[uwsgi]
; 执行的启动文件
wsgi-file = manage.py
; 对应 manage.py 的同名全局变量,是一个 Flask app
callable = app
; 虚拟环境的文件夹,如果没有使用虚拟环境,注释掉即可
;venv = /root/DownloadYoutube/venv
; 启动 socket监听
socket = 0.0.0.0:5001
# 下面的设置有效避免了504超时错误!
#web 应用开发一个最常见的问题就是 “stuck requests”(卡住的请求)。你所有的线程/worker 都被卡住(被请求堵塞), 然后你的应用再也不能接受更多的请求。 为了避免这个问题你可以设置一个 harakiri 计时器。它是一个监视器(由主进程管理),当 进程被卡住的时间超过特定的秒数后就销毁这个进程(慎重选择 harakiri 的值)。
harakiri = 30
# 这将会产生 2 个进程,一个主进程(当你的进程死掉时会重新 spawn 一个新的)
master = true
processes = 2
# 如果你想维持 Python 的线程支持同时应用又不启动多个线程,只需要加上 --enable-threads 选项 (或者 enable-threads = true 在 ini 风格配置文件中)。
enable-threads = true
# 为每个工作进程设置请求数的上限。当一个工作进程处理的请求数达到这个值,那么该工作进程就会被回收重用(重启)。你可以使用这个选项来默默地对抗内存泄漏
max-requests = 5000 
# 设置用于uwsgi包解析的内部缓存区大小为32k。默认是4k。
buffer-size = 32768
# 设置在平滑的重启(直到接收到的请求处理完才重启)一个工作子进程中,等待这个工作结束的最长秒数。这个配置会使在平滑地重启工作子进程中,如果工作进程结束时间超过了8秒就会被强行结束(忽略之前已经接收到的请求而直接结束)
reload-mercy = 8

注意如果你想提前测试自己的项目,将最后的socket监听改成http,即可直接通过uWSGI建立起http服务器。作为socket监听是因为需要和nginx配合。

注意配置文件里后面添加的部分,有效地避免了504超时错误!

2.2.2 配置nginx

在nginx中配置部分如下:

# 由于使用的是uwsgi,所以需要将数据转发过去。如果是lnmp之类安装,则这里默认没有下面特殊的规则
    location / {
        include      uwsgi_params;
        uwsgi_pass   127.0.0.1:5001; 
        uwsgi_param UWSGI_CHDIR  /root/DownloadYoutube;
        uwsgi_param UWSGI_SCRIPT manage:app; 
      }

2.2.3重启服务

如果你修改了项目代码,需要重启uwsgi服务,网上一般是:

kill -HUP `cat /tmp/project-master.pid`

当然这里的pid是你uwsgi进程的pid。

而且大家都在用仍然不支持python3的supervisor,那干脆就不要用它好了,我建议学一学简单的systemd语法,写一个后台service,就可以通过systemctl restart your_project.service来重启了以及进程自动重启了。

我的/lib/systemd/system/findhao.net.service文件内容如下:

[Unit]
Description=findhao.net website
# 指定了在nginx启动后再启动,这个非必需
After=nginx.target 

[Service]
Type=simple
# pid文件地址,自己指定即可
PIDFile=/run/findhao.net.pid
# 执行的uwsgi命令
ExecStart=/usr/local/bin/uwsgi /root/DownloadYoutube/uwsgi_conf.ini
ExecReload=/usr/local/bin/uwsgi --reload /run/findhao.net.pid
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/findhao.net.pid
TimeoutStopSec=3
KillMode=mixed

[Install]
WantedBy=multi-user.target

启动服务,添加开机启动项:

pkill uwsgi
systemctl start findhao.net.service
systectl enable findhao.net.service

Reference

uWSGI笔记——概念篇

部署Flask + uWSGI + Nginx

重启uwsgi的几种方法

Python/WSGI 应用快速入门-官方文档

nginx + uwsgi + Django 应用部署


文章版权归 FindHao 所有丨本站默认采用CC-BY-NC-SA 4.0协议进行授权|
转载必须包含本声明,并以超链接形式注明作者 FindHao 和本文原始地址:
https://findhao.net/easycoding/2033.html

Comments