猿创作随笔 | 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 pymysql
    from pymysql.cursors import DictCursor
    
    db_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组合是比较广泛的部署方案,小伙伴们在遇到性能瓶颈时可以尝试一下。

    物联沃分享整理
    物联沃-IOTWORD物联网 » 猿创作随笔 | python gevent执行MySQLdb/mysqlclient连接卡住的解决方法

    发表评论