nginx 配置静态文件目录_Flask 配合Nginx做按需同步图片的程序

好久没撸文字了,标题读起来可能有点不讲武德(太绕了,看不出所以然)。

事情是这样的:

带头大哥:麻烦线上的所有图片也同步一份到测试服。

线上环境是在海外,测试服是在境内。当然,可以先不考虑网络环境的问题,实际上测试服能用到的图片可能就几张,线上目前的存储有1.8GB+的图片内容。所以才想到按需要去同步线上的图片到本地测试服的事情,只要程序和网络稳定,便可一劳永逸了。

我们先意淫一些域名出来:

线下测试服域名:offline.com

线下测试服存储路径:/data/file/

线上生产服域名:online.com

处理流程:

  1. 浏览器请求从数据库获取的一个测试服不存在的文件

  2. Nginx 配置静态文件目录为

  3. Nginx 找不到本地文件产生404

  4. Nginx 404 后将url拼接新的url转发的 Flask 后端程序处理

  5. Flask 接受到带参数的请求,从线上生产服务下载图片保存到本地

  6. 保存好图片后直接使用 Flask 框架返回静态文件给请求方

  7. 下次再次请求同一文件将由 nginx 直接返回(原始需求和最终目的)

Flask 程序代码:

import osimport requestsfrom urllib import requestfrom urllib.parse import urlparsefrom flask import Flask, request, send_from_directoryapp = Flask(__name__, static_url_path='/data/file/')STATIC_ROOT=r'/data/file/'def fetch_file(url):    # 从线上下载图片的函数,比较粗糙,没有任何容错机制    # Usage:    #     url = 'http://online.com/images/aaa/bbb/ccc.jpeg'    #     fetch_file(url)    req = requests.get(url)    pre, lnk, filename = urlparse(url).path.rpartition('/')    FullPath = STATIC_ROOT + pre    if not os.path.exists(FullPath):        os.makedirs(FullPath)    FullFilePath = FullPath + lnk + filename    with open(FullFilePath, 'wb') as f:        f.write(req.content)@app.route('/')def send_static():    # 接受 Nginx 转发过来请求    # path参数:    # /?path=images/aaa/bbb/ccc.jpeg    path = request.args.get('path')    domain = 'http://online.com/'    fetch_file(domain + path)    pre, _, filename = urlparse(path).path.rpartition('/')    directory = STATIC_ROOT + pre    return send_from_directory(directory, filename)if __name__ == "__main__":    app.run()

运行 flask 代码:

python3 -m venv envsource envpip install flask requests -i https://mirrors.aliyun.com/pypi/simplecp ~/app.py ../env/bin/python app.py# Flask默认占用Tcp 5000 端口号

Nginx 配置段:

server {    listen 80;    server_name offline.com;    location / {        alias /data/file/;        add_header content-type "image/png";        expires 7h;        access_log off;    }    # 找不到的图片时转发的 flask 程序动态处理    error_page 404 = @redirect;    location @redirect {        rewrite /(.+)$ /?path=$1 break;        proxy_pass http://127.0.0.1:5000;    }}

Supervisor 守护一下 flask 程序

[program:images_transit]process_name=%(program_name)s_%(process_num)02ddirectory=/data/ImageTransitcommand=/data/ImageTransit/env/bin/python /data/ImageTransit/app.pystopsignal=QUITuser=root                   ; setuid to this UNIX account to run the programlog_stderr=truelogfile=/data/logs/supervisord/images_transit.log

因为没有对文件目录做进一步处理,所以程序仅能在Linux系统下运行。

这下轻松省成本了,代价就是测试服首次请求对应图片的时候会比较慢。

因为这是飘洋过海后再给你看的无码高清图片啊083d855d91932eccc5f884559c53a2bf.png

看到这里,是不是想起了CDN!!!

所以,这类问题还有很多其他的解决方案,比如用squid,varnish,甚至是nginx直接缓存,但这些配置起来可能会比较复杂。

当然,各有利弊,我认为我上面的做法对目标文件管理起来相对比较方便。

近期又收到部分朋友希望 idcops 能够使用上IP地址管理的功能,django-idcops 最近也在努力更新中。develop 分支已更新了 Network 和IPAddress 两个模型,但后面应该还会有改动。

但由于个人精力有限,该功能目前也才开发到1/3左右,离能上线使用还有一段距离。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值