场景:
python服务
flask+mysql
一开始的时候每次都重新建立连接,返回耗时比较长
就改为用连接池
用连接池读取mysql数据
再客户端批量或者多线程的大量调用
报错pymysql AttributeError: 'NoneType' object has no attribute 'settimeout'
解决思路:
有时候能取到结果有时候取不到,而且同一个请求不能稳定复现报错
感觉是没有获取到mysql的链接所以拿不到数据,就none type了
而且看监控timewait 很高
看mysql服务器端的日志,Got an error reading communication packets
表示:连接没有成功建立就被mysql kill了
改了mysql的设置:链接等待时长、最大连接数等参数,都没有效果
调整调用方式:不再大量调用
大量调用报错很多,单线程调用量少的时候报错量减少
因此分析多线程调用的问题
想到是不是并发过多
解决方案:
和mysql交互的时候加上互斥锁
import threading
lock = threading.Lock()
lock.acquire()
curos.excure(command,data)
lock.release()
注意:
互斥锁要前后配对,否则会死锁
比如拿到链接和释放链接前后加锁解锁,或者执行语句前后加锁解锁
原因:
因为并发抢资源,没有拿到链接,报错
并发拿不到链接的可以wait,但是超时就会被kill
加锁就可以等待