博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
tornado+sqlalchemy+celery,数据库连接消耗在哪里
阅读量:7012 次
发布时间:2019-06-28

本文共 2756 字,大约阅读时间需要 9 分钟。

  随着公司业务的发展,网站的日活数也逐渐增多,以前只需要考虑将所需要的功能实现就行了,当日活越来越大的时候,就需要考虑对服务器的资源使用消耗情况有一个清楚的认知。

     最近老是发现数据库的连接数如果几天不重启服务器,就经常会发现有很多sleep很久的数据库连接,对数据库服务器的性能有较大的影响。所以需要知道我们的数据库连接到底是在哪里被创建的,什么时候会被复用,什么时候会被释放。
     测试的时候使用的代码,适当进行调整,可帮助梳理清楚场景。

from sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import (sessionmaker)from sqlalchemy import create_engineimport time## []括起来的参数,这边就是做一个占位符engine = create_engine("mysql+{driver}://{username}:{password}@{server}/{database}?charset={charset}"\    .format(        driver   = [MYSQL_DRIVER],        username = [MYSQL_USERNAME],        password = [MYSQL_PASSWORD],        server   = [MYSQL_MASTER_SERVER],        database = [DB_NAME],        charset  = [DB_CHARSET]    ),    pool_size    = 20,    max_overflow = 100,    pool_recycle = 7200,    echo         = False  # 调试模式,开启后可输出所有查询语句)DBSession = sessionmaker(bind=engine)session=DBSession()engine.execute("select 1;")time.sleep(10)session.execute("select 1;")engine.execute("select 1;")# session.close()time.sleep(10)session1=DBSession()session1.execute("select 1;")# session1.execute("select 1;")engine.execute("select 1;")

    就是在上面的这一部分代码的测试,可以对以下的问题给出一些个人理解:

1.什么时候创建新的数据库连接的?
   A.engine.excute
   B.session.excute
   C.session.query
2.什么时候关掉sqlachemy里面的连接(其实是将可用的数据库连接丢回到sqlachemy的连接池里面去):
   A.engine的excute执行完成时
   B.session.close()/session.commit()/session.rollback()
   C.engine定义里面设置的pool_recycle时间到期,如果某一个session长期占有,没有close,在这个到期了之后就会被回收回去;
3.什么时候关掉数据库连接:
   A.python3进程关掉,比如kill或者重启服务器的时候;
   B.数据库连接的sleep时间超过wait_timeout的时候;比如在一个http请求里面,先用了一次session.query,然后休眠了10秒钟,这个时候我们的数据库的wait_timeout如果设置为5秒,在query执行完成之后,数据库就会显示连接进入sleep状态,超过5秒就会被关掉。这个时候,如果我们如果需要继续用这个session来进行查询的话,就会提示“MySQL connection not available”
    所以,为了不产生比较多的数据库连接,导致无谓的资源消耗,就是一定要注意尽量少创建新的,使用完了以后,一定要注意丢回到连接池中;当然还要保证,数据库的wait_timeout时间不能低于engine的pool_recyle时间,否则会出现mysql连接不可用的提示。
    在tornado里面,可以在base的on_finish方法里面将本次请求产生的session关掉;
    使用celery的时候也需要注意,可以在函数执行的末尾关掉本次创建的session,也可以写装饰器;并且需要注意,对函数异常也要进行捕获。
本次的测试过程使用到的一些知识:
    ①.查询数据库的连接超时设置:show variables like '%wait_timeout%';
    ②.查询数据库的最大可用连接数:show variables like '%max_connections%';
    ③.设置数据库的连接超时:set wait_timeout=28800;||set global wait_timeout=5;(这个global参数待查)
    ④.查看当前连接的使用情况:show status like 'Threads%';
    ⑤.查看所有的数据库连接情况:show full processlist;
    ⑥.lsof -i :3306 查看数据库的端口[3306]现在运行的情况
不过,后续还是需要把sqlachemy 官网推荐的web如何使用session的英文撸一撸。。。http://docs.sqlalchemy.org/en/latest/orm/session_basics.html#session-faq-whentocreate
然后还有一个疑惑,是在使用⑥的时候,有发现有一些celery程序有出现closewait的状态。
      tcp连接有3次握手,断开连接有4次握手。closewait状态的产生,其实就是如果A是主动断开的一方,那么在B这边显示就会是CloseWait状态。
      所以celery出现closewait,那就说明是mysql先关闭了连接,但是,celery和MySQL的连接,也是,一个是使用的是db_config里面的engine,回收时间是7200,mysql的wait_timeout是28800,按道理不会出现数据库中关掉了,但是celery里面没关掉的情况。。。
      可能是我还是有哪里没有弄的很透彻。。。

 

转载于:https://www.cnblogs.com/summery91/p/6209664.html

你可能感兴趣的文章
java中的==、equals()、hashCode()源码分析
查看>>
HDU 3613 Best Reward 正反两次扩展KMP
查看>>
zepto.js 源码解析
查看>>
HTTP状态码大全
查看>>
使用ASP.NET Web API 2创建OData v4 终结点
查看>>
MyBatis简单的增删改查以及简单的分页查询实现
查看>>
Android快捷支付SDK Demo resultStatus={4001};memo={參数错误};result={}问题
查看>>
urllib2中自定义opener
查看>>
Hadoop快速入门
查看>>
MySql_安装及简单命令
查看>>
CSDN markdown 编辑器 第四篇 LaTex语法
查看>>
mongodb 初学 索引
查看>>
每日一小练——二项式系数加法解
查看>>
django中的setting全局变量的导入
查看>>
常见的几种Flume日志收集场景实战
查看>>
一次误报引发的DNS检测方案的思考:DNS隧道检测平民解决方案
查看>>
Python操作SQLAlchemy之连表操作
查看>>
什么是架构师?
查看>>
layer.alert自定义关闭回调事件
查看>>
LESS IS MORE
查看>>