敬贤礼士网

猿创征文|python gevent 执行MySQLdb/mysqlclient连接卡住解决方案

猿创征文|python gevent 执行MySQLdb/mysqlclient连接卡住解决方案

文章目录

  • 一、猿创前言
  • 二、征文执行解决方案
  • 三、连接pymysql和Mysqlclient区别
  • 四、卡住为什么要使用gunicorn+gevent

一、解决前言

为了提高Django的猿创并发性能,所以使用gunicorn+gevent组合来启动Django,征文执行但在过程中遇到了一个问题,连接之前能正常使用的卡住接口按新方法部署后一直在报超时,后面排查发现当项目代码执行到使用Mysqlclient创建数据库连接时就会卡住。解决

网上找了一圈发现了一个解决方案:


在这里插入图片描述


但使用时会报错,猿创方法不好使,征文执行后面查阅pymysql的连接github:https://github.com/PyMySQL/mysqlclient/pull/285发现作者移除了上述的方法:


在这里插入图片描述


移除的原因作者也做了解释:


在这里插入图片描述


一句话概括:waiter不能完全解决gevent阻塞的问题,所以对此建议使用pymysql。卡住

二、解决解决方案

因此我只好将代码中的所有mysqldb连接替换为了pymysql连接的方式,得以解决问题:

import pymysqlfrom pymysql.cursors import DictCursordb_con = pymysql.connect(......).cursor()

可能还有其他的三方库或方案来解决此问题,但由于改动成本的原因还是选择了替换为pymysql。

三、pymysql和Mysqlclient区别

PyMySQL和Mysqlclient提供相同的功能——它们都是数据库连接器。
区别在于Mysqlclient是C扩展,PyMySQL是纯Python的实现,由此可以看出Mysqlclient的性能会由于PyMySQL,但由于Mysqlclient不支持gevent,所以在涉及到需要使用gevent时,还是得使用PyMySQL。


四、为什么要使用gunicorn+gevent

由于Python全局解释器锁的存在,Python的多线程更像是一种伪多线程,甚至就几乎等于Python是个单线程的程序。
所以在使用多线程时回发现CPU并不会被打满,因为在同一时刻,Python只会有一个线程在运行。所以为了提高Django的并发性能,需要采用多进程的方式来弥补这个问题,gunicorn是基于unix系统的一个 Python 的 WSGI HTTP 服务器,使用它可以很方便的管理我们的后端服务,它也兼容很多其他的框架。

另外使用gevent能更好对性能提升,gevent是python的一个并发框架,以协程(微线程)greenlet为核心,使用了epoll事件监听机制以及诸多其他优化而变得高效,Gevent 通过 Cython 调用 libev 来实现一个高效的 event loop 调度循环。同时类似于 Event,Gevent 也有自己的 monkey_patch,在打了补丁后,完全可以使用 python 线程的方式来无感知的使用协程,减少了开发成本:


在这里插入图片描述


gunicorn+gevent组合是比较广泛的部署方案,小伙伴们在遇到性能瓶颈时可以尝试一下。

未经允许不得转载:敬贤礼士网 » 猿创征文|python gevent 执行MySQLdb/mysqlclient连接卡住解决方案