有關個人工作涉及的各種小知識和技巧,記錄在這個筆記中,備查。
1、Python程序日誌實時寫入日誌
當Python程序在後臺執行時,其標準輸出並不能實時寫入日誌文件,而是要經過緩存達到一定的大小或者程序終止時才寫入。對於想debug一些問題時很不方便。可以增加參數-u實現實時寫入。
nohup python3 -u app.py >> app.log 2>&1 &
-u的作用是強制python的標準輸出和錯誤輸出不經過緩存直接寫入日誌文件。
另一種方式:
增加環境變量:PYTHONUNBUFFERED=1
2、docker清除所有<none>鏡像
在docker反覆build一個鏡像後,會存留很多none鏡像,批量清除所有none鏡像:
docker rmi `docker images | grep "<none>" | awk '{print $3}'`
windows docker清除<none>鏡像:
docker rmi $(docker images --filter “dangling=true” -q --no-trunc)
3、docker清除所有停止的容器
docker container prune
4、docker容器內部無法解析域名
Linux系統默認沒有打開IP轉發功能,在/etc/sysctl.conf裏修改項:
net.ipv4.ip_forward = 1
執行sysctl -p生效。
然後重啓docker網絡功能:
service docker stop
ip link set dev docker0 down
service docker start
5、gunicorn避免內存泄漏和變量不回收
Python的內存垃圾收回的性能很糟糕,而且可能因開發不注意釋放對象和關閉連接,甚至一些依賴庫也有內存泄漏的問題。作爲程序運行完,進程停止,內存自然就釋放了;但是如果作爲服務,Python常常會造成無法解決的內存泄漏問題。
項目中使用Flask + gunicorn + Nginx提供Python服務,結果gunicorn 的進程內存一直在增長,無法釋放。
從查找內存泄漏和垃圾回收的方向,各種方法調試了很久,都沒有解決。
基本可以認爲是Python的固有缺陷,於是從另一個進程重啓的方向解決這個問題:如果gunicorn進程內存一直在增長,那麼定時重啓一下進程不就可以了。
而且gunicorn有相關的參數:
max_requests
--max-requests INT
worker進程處理的最大請求數,後重啓進程。默認值爲0。
max_requests_jitter
--max-requests-jitter INT
要添加到max_requests的最大抖動。抖動將導致每個worker的重啓被隨機化,這是爲了避免所有worker同時被重啓。randint(0,max-requests-jitter)
例如:
max_requests = 1000
max_requests_jitter = 100
即每個worker進程處理了隨機在[1000, 1100]個請求後,自動重啓。
作用:
1、定期清理資源,防止內存泄漏
2、避免對象存活時間太久,從而導致內存垃圾回收時間過長
6、Python內存泄漏
一定不要使用大對象列表!
一定不要使用大對象列表!
一定不要使用大對象列表!
重要的事情說三遍。
7、創建有序字典
import collections
d = collections.OrderedDict()
8、Pillow從網頁下載創建對象
import requests
from PIL import Image
from io import BytesIO
url = ''
img = requests.get(url, stream=True).content
img = Image.open(BytesIO(img))
if img.mode != 'RGB':
img = img.convert('RGB')
9、docker從鏡像反推Dockerfile
利用docker history命令可以得到創建鏡像時的命令:
> docker history image:tag --format {{.CreatedBy}} --no-trunc