flask找不到css_Flask 配合Nginx做按需同步圖片的程式
技術標籤:flask找不到css
好久沒擼文字了,標題讀起來可能有點不講武德(太繞了,看不出所以然)。
事情是這樣的:
帶頭大哥:麻煩線上的所有圖片也同步一份到測試服。
線上環境是在海外,測試服是在境內。當然,可以先不考慮網路環境的問題,實際上測試服能用到的圖片可能就幾張,線上目前的儲存有1.8GB+的圖片內容。所以才想到按需要去同步線上的圖片到本地測試服的事情,只要程式和網路穩定,便可一勞永逸了。
我們先意淫一些域名出來:
線下測試服域名:offline.com
線下測試服儲存路徑:/data/file/
線上生產服域名:online.com
處理流程:
瀏覽器請求從資料庫獲取的一個測試服不存在的檔案
Nginx 配置靜態檔案目錄為
Nginx找不到本地檔案產生404
Nginx404 後將url拼接新的url轉發的 Flask後端程式處理
Flask接受到帶引數的請求,從線上生產服務下載圖片儲存到本地
儲存好圖片後直接使用 Flask框架返回靜態檔案給請求方
下次再次請求同一檔案將由 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系統下執行。
這下輕鬆省成本了,代價就是測試服首次請求對應圖片的時候會比較慢。
因為這是飄洋過海後再給你看的無碼高清圖片啊。
看到這裡,是不是想起了CDN!!!
所以,這類問題還有很多其他的解決方案,比如用squid,varnish,甚至是nginx直接快取,但這些配置起來可能會比較複雜。
當然,各有利弊,我認為我上面的做法對目標檔案管理起來相對比較方便。
近期又收到部分朋友希望 idcops 能夠使用上IP地址管理的功能,django-idcops 最近也在努力更新中。develop 分支已更新了 Network 和IPAddress 兩個模型,但後面應該還會有改動。
但由於個人精力有限,該功能目前也才開發到1/3左右,離能上線使用還有一段距離。