Flask + Gunicorn + Nginx 文件管理系统学习分享

        前段时间发现手上的树莓派闲置太久了,就想用用这个板子学习点东西,因此烧录系统后准备做个类似NAS的系统练手学习。加上对于网站系统等框架的好奇,因此选择了一套较为简单的Flask + Gunicorn + Nginx 框架进行接下来的开发,并顺便实现webterminal功能。

目录

项目链接

组件介绍

环境搭建

代码运行

效果展示

其他细节

SocketIO文件传输

报文传递总体流程

Nginx的相关配置

SocketIO和Gunicorn的冲突

webterminal实现

公网映射实现


项目链接

grey-wood-wolf/Flask-gunicorn-nginx-files-management-system: 利用Flask+gunicorn+nginx框架开发的文件管理系统,其中包括对于文件的上传下载、socket自构的上传和下载 (github.com)

组件介绍

        对于和我一样不了解的小白同学们,我这里简单谈谈我的认识。这里的Flask就是一个API接口开发的框架,可以对前端发出的GET、POST等请求做出响应。Gunicorn是一个Python的WSGI HTTP服务器,用于启动多个你开发的Flask app,以实现多worker的共同处理增加并发处理能力。Nginx是一个用于代理和反向代理的服务器,用于将前端传来的请求,以你设定的方式均衡的分发到对应的后端服务器中

        这里只是一个大致的解释,具体可参考其他文章,本文章主要用于关于我这个项目的分享。

环境搭建

        本次项目是在树莓派上搭建的,因此后端在linux环境下部署,需要python相关环境,至于前端就是使用浏览器渲染后端发来的html页面就行了。

        首先是关于Flask + Gunicorn + Nginx的下载。

sudo apt-get update
sudo apt-get install nginx
sudo systemctl start nginx
sudo pip3 install Flask
sudo pip3 install gunicorn

        随后是部分python库的下载,这个具体部署和运行的时候,大家看缺什么再下吧 。

代码运行

        对于这个项目写了一个bash脚本帮助大家一键式部署,大家也可以通过这个bash脚本查看Flask、Gunicorn、Nginx这三个组件具体是如何部署的。

cd NAS_project
sudo ./start_web.sh

        代码大部分都没有注释。。。毕竟只是闲暇时候的学习,所以还请各位自己问GPT等进行学习。

效果展示

        先给大家看看效果,等下再讲讲具体的细节吧。


 

Flask + Gunicorn + Nginx 文件管理系统

其他细节

SocketIO文件传输

        首先是关于socketIO传输文件部分,对于socketIO来说传输大量文件本来不是其主要功能,但由于我想复刻文件的块式传输,因此采用该方式进行编写。

报文传递总体流程

        如我这里的示例所示,前端的请求首先传到Nginx服务器监控的80端口中,随后根据你配置的Nginx规则进行反向代理的转发,传递到Gunicorn监听的8000、8001等端口中,最后Gunicorn将其交付给构建的Flask worker中进行报文处理。

Nginx的相关配置

        在start_web.sh文件中如下给出了Nginx的相关配置:

cat > $NGINX_SITES_AVAILABLE/$APP_NAME << EOF
upstream backend {
    ip_hash;
    $GUNICORN_SERVERS
}

server {
    listen $PORT;
    server_name $DOMAIN;
    client_max_body_size 1000M;

    location / {
        proxy_pass http://backend;
        proxy_http_version 1.1;
        proxy_set_header Upgrade \$http_upgrade; # 这个头是用来升级连接为 WebSocket
        proxy_set_header Connection "upgrade"; # 这是一个特殊的值,告诉 Nginx 升级连接
        proxy_set_header Host \$host;
        proxy_set_header X-Real-IP \$remote_addr;
        proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto \$scheme;

        # WebSocket 专用的超时设置,根据需要调整
        proxy_read_timeout 86400; # 1 day timeout, adjust to suit your needs
    }
}
EOF

        其中ip_hash表明采用ip_hash的方式进行负载均衡代理,其他参数请自行搜索学习。

SocketIO和Gunicorn的冲突

        由于本次项目采用了socketIO进行部分功能的开发,socketIO需要稳定的连接,但是由于Gunicorn对于每一次请求或者说http的报文都是随机交给一个Flask worker进行处理,因此不一定连接能稳定建立。所以最后在start_web.sh文件中给出了较为粗暴的解决方案:

# 遍历端口号列表,为每个端口号启动一个 Gunicorn 服务, 并记录pid
for port in "${GUNICORN_PORT_LIST[@]}"; do
    sudo gunicorn -k eventlet -w 1 -b 0.0.0.0:$port $APP_NAME:app --threads $THREADS --timeout 120 &
    GUNICORN_PID+=($!)
done

        建立多个Gunicorn服务器,每个Gunicorn只构建一个Flask worker,Nginx负载的时候采用ip_hash可以保证同一个ip的请求只会传递到同一个Gunicorn上,以此保证socket IO的连接稳定。

        当然可以将Gunicorn替换成其他的WSGI服务器来彻底解决这个问题,大家可以试一试,我就偷懒没尝试了。

webterminal实现

        本次项目顺便实现了关于webterminal功能,以便在浏览器中直接操作服务器的终端等等。如果你觉得不安全,或者想研究这个东西更多用法,可以尝试构建docker集群,然后webterminal连接docker的终端,实现浏览器访问容器内部终端。

公网映射实现

        对于公网映射问题,由于本项目,主要是在一个局域网中进行开发和使用的,因此对于如果想将自己的程序真的使用起来还是得进行公网映射。

        对于有公网ip的大佬们,就请自行进行公网暴露。但假如你和我一样穷(不是),没有公网ip,可以尝试参考以下博客,使用cpolar进行内网穿透从而使得可以在公网中访问你的程序。但需要注意的是,cpolar本质上是反向代理,所以你访问程序会中转一次cpolar,会变得十分慢,并且保密文件会变得不太安全,需要有额外的文件加密操作等。

树莓派使用Nginx+cpolar内网穿透实现无公网IP访问内网本地站点-CSDN博客

  • 9
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值