有关个人工作涉及的各种小知识和技巧,记录在这个笔记中,备查。
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