1. 程式人生 > 其它 >flask找不到css_Flask 配合Nginx做按需同步圖片的程式

flask找不到css_Flask 配合Nginx做按需同步圖片的程式

技術標籤:flask找不到css

好久沒擼文字了,標題讀起來可能有點不講武德(太繞了,看不出所以然)。

事情是這樣的:

帶頭大哥:麻煩線上的所有圖片也同步一份到測試服。

線上環境是在海外,測試服是在境內。當然,可以先不考慮網路環境的問題,實際上測試服能用到的圖片可能就幾張,線上目前的儲存有1.8GB+的圖片內容。所以才想到按需要去同步線上的圖片到本地測試服的事情,只要程式和網路穩定,便可一勞永逸了。

我們先意淫一些域名出來:

線下測試服域名:offline.com

線下測試服儲存路徑:/data/file/

線上生產服域名:online.com

處理流程:

  1. 瀏覽器請求從資料庫獲取的一個測試服不存在的檔案

  2. Nginx 配置靜態檔案目錄為

  3. Nginx找不到本地檔案產生404

  4. Nginx404 後將url拼接新的url轉發的 Flask後端程式處理

  5. Flask接受到帶引數的請求,從線上生產服務下載圖片儲存到本地

  6. 儲存好圖片後直接使用 Flask框架返回靜態檔案給請求方

  7. 下次再次請求同一檔案將由 nginx 直接返回(原始需求和最終目的)

Flask 程式程式碼:

import osimport requestsfrom urllib import requestfromurllib.parseimporturlparsefrom flask import Flask, request, send_from_directoryapp=Flask(__name__,static_url_path='/data/file/')STATIC_ROOT=r'/data/file/'deffetch_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/pythonapp.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系統下執行。

這下輕鬆省成本了,代價就是測試服首次請求對應圖片的時候會比較慢。

因為這是飄洋過海後再給你看的無碼高清圖片啊64d16771645b9b5d2e3777d98fa59eed.png

看到這裡,是不是想起了CDN!!!

所以,這類問題還有很多其他的解決方案,比如用squid,varnish,甚至是nginx直接快取,但這些配置起來可能會比較複雜。

當然,各有利弊,我認為我上面的做法對目標檔案管理起來相對比較方便。

近期又收到部分朋友希望 idcops 能夠使用上IP地址管理的功能,django-idcops 最近也在努力更新中。develop 分支已更新了 Network 和IPAddress 兩個模型,但後面應該還會有改動。

但由於個人精力有限,該功能目前也才開發到1/3左右,離能上線使用還有一段距離。