现象:

在本地利用Flask自带的WSGI服务进行调试没有问题后,通过Gunicorn进行部署。

但是在一晚上没有访问之后,第二天再次访问会出现500(Internal error)。

原因:

通过追踪日志文件,发现是Sqlalchemy连接Mysql的断开问题

2006, "MySQL server has gone away (BrokenPipeError(32, 'Broken pipe'))"

此问题来自于Mysql的连接(Session)在一段时间(默认为8小时,所以在我这里体现为第二天)没有响应后会自动断开,而SQLAlchemy并不会监测到Session的断开所以在尝试使用旧Session的时候会出现此错误。查看mysql的日志,也可以看到它确实会主动放弃过期session:

Aborted connection 112225 to db。。。。。。。。。。。。。。。(Got an error reading communication packets)

解决方案:

既然是因为Sqlalchemy的Session过期问题,所以当然要解决过期,Stack Overflow上找了不同的解决方案,主要分为几种:

1.增加mysql的wait_timeout让mysql不要太快放弃连接。

假如你的服务访问还算频繁,不太会出现长时间无连接。那么增加此变量从而避免短时间无连接造成的abort是可以的,但是假如超出时间,早晚还是会崩溃。具体到自己的Mysql的此设置为多少可以通过此命令查看(wait_timeout):

show variables like '%timeout%';
+-----------------------------+----------+
| Variable_name | Value |
+-----------------------------+----------+
| connect_timeout | 10 |
| delayed_insert_timeout | 300 |
| innodb_flush_log_at_timeout | 1 |
| innodb_lock_wait_timeout | 50 |
| innodb_rollback_on_timeout | OFF |
| interactive_timeout | 28800 |
| lock_wait_timeout | 31536000 |
| net_read_timeout | 30 |
| net_write_timeout | 60 |
| rpl_stop_slave_timeout | 31536000 |
| slave_net_timeout | 3600 |
| wait_timeout | 28800 |
+-----------------------------+----------+

2.在创建Engine的时候通过设定 pool_recycle让Sqlalchemy的session pool定期回收过期Session

可能被mysql抛弃了的session,所以应该要比你的mysql wait_timeout小)来保证Session的有效性。

e = create_engine("mysql://scott:tiger@localhost/test", pool_recycle=3600)
'''
pool_recycle=-1: this setting causes the pool to recycle
connections after the given number of seconds has passed. It
defaults to -1, or no timeout. For example, setting to 3600
means connections will be recycled after one hour. Note that
MySQL in particular will disconnect automatically if no
activity is detected on a connection for eight hours (although
this is configurable with the MySQLDB connection itself and the
server configuration as well).
'''

!注意,如果是云服务提供商,可能对这个断开的时间限制有不同的设定,比如pythonanywhere的设置是5分钟:

Using SQLAlchemy with MySQL

SQLAlchemy needs to some extra arguments to work on PythonAnywhere:

engine = create_engine('mysql+mysqldb://...', pool_recycle=280)

The RDS service disconnects clients after 5 minutes (300s), so we need to set the pool_recycle to something lower than that, or you'll occasionally see disconnection errors in your logs.

新浪云的设置则更加短,只有30秒:

MySQL gone away问题

MySQL连接超时时间为30s,不是默认的8小时,所以你需要在代码中检查是否超时,是否需要重连。

对于使用sqlalchemy的用户,需要在请求处理结束时调用 db.session.close() ,关闭当前session,将mysql连接还给连接池,并且将连接池的连接recyle时间设的小一点(推荐为60s)。

3.重建Session??(来自StackOverflow)

这个问题中的最高票答案说,在每一个你需要使用SqlAlchemy的地方实例化一个Session。

但是在我在实际操作中,通过查看Session id发现,两次实例的ID一致,也就是说明Session()只是从session pool里面取回来旧的Session,那么这个Session早晚会过期.事实也证明,这个方法并没有解决我的服务中mysql gone away的问题。所以这个答案我持保留态度。

4.SQlAlchemy官方:设置pool_pre_ping=True

官方文档其实对于myslq断链的问题,官方除了设置pool_recycle之外还建议在创建Engine的时候设置pool_pre_ping=True也就是在每一次使用Session之前都会进行简单的查询检查,判断是Session是否过期。

engine = create_engine("mysql+pymysql://user:pw@host/db", pool_pre_ping=True)

详细可见参考网站。

但是以上几个方法我都尝试过后,依然会重现该问题,最后看到这篇文档中说:

To use SQLAlchemy in a declarative way with your application, you just have to put the following code into your application module. Flask will automatically remove database sessions at the end of the request or when the application shuts down:

from yourapplication.database import db_session

@app.teardown_appcontext
def shutdown_session(exception=None):
db_session.remove()

终于,mysql has gone away不见啦! 也就是每一次请求结束,Flask都会关闭Session.(TODO: 测试此方法是否低效率。)

Reference:

Avoiding “MySQL server has gone away” on infrequently used Python / Flask server with SQLAlchemy

Connection Pooling¶

SQLAlchemy in Flask

http://docs.sqlalchemy.org/en/latest/core/pooling.html#dealing-with-disconnects

https://mofanim.wordpress.com/2013/01/02/sqlalchemy-mysql-has-gone-away/

"Mysql has gone away"的几种可能的更多相关文章

  1. mysql中模糊查询的四种用法介绍

    下面介绍mysql中模糊查询的四种用法: 1,%:表示任意0个或多个字符.可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示. 比如 SELECT * FROM [user] ...

  2. MySQL数据库分表的3种方法

    原文地址:MySQL数据库分表的3种方法作者:dreamboycx 一,先说一下为什么要分表 当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,我想有可能会死在那儿了.分表的目 ...

  3. <经验杂谈>Mysql中字符串处理的几种处理方法concat、concat_ws、group_concat

    Mysql中字符串处理的几种处理方法concat.concat_ws.group_concat以下详情: MySQL中concat函数使用方法:CONCAT(str1,str2,-) 返回结果为连接参 ...

  4. mysql myisam转innodb的2种方法

      mysql myisam转innodb的2种方法 mysql中的myisam和innodb有什么区别.一个好比便利店,一个好比大型购物中心,他们是为了适应不同的场合而存在的.当流量比较小,我们可以 ...

  5. MySQL中MyISAM和InnoDB两种主流存储引擎的特点

    一.数据库引擎(Engines)的概念 MySQ5.6L的架构图: MySQL的存储引擎全称为(Pluggable Storage Engines)插件式存储引擎.MySQL的所有逻辑概念,包括SQL ...

  6. java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)

    转载地址:http://www.devba.com/index.php/archives/4581.html java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明); ...

  7. mysql 中添加索引的三种方法

    原文:http://www.andyqian.com/2016/04/06/database/mysqleindex/ 在mysql中有多种索引,有普通索引,全文索引,唯一索引,多列索引,小伙伴们可以 ...

  8. (转)java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明)

    java向MySQL插入当前时间的四种方式和java时间日期格式化的几种方法(案例说明);部分资料参考网络资源 1. java向MySQL插入当前时间的四种方式 第一种:将java.util.Date ...

  9. 导致“mysql has gone away”的两种情况

    导致“mysql has gone away”的两种情况 By Cruise 1.  wait_timeout参数 在开发代理server时, 我使用了jdbc连接数据库,并采用长连接的方式连接数据库 ...

  10. MySQL的读写分离的几种选择

    MySQL的读写分离的几种选择 MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践 原址如下: http://heylinux.com/archives/1004. ...

随机推荐

  1. typescript import 全局node_modules报错

    项目里面有一个node_modules的包太大,每次放到docker里面都要下载半天,大大减少了部署效率. 所以考虑将这个node包全局安装到docker的基础镜像中,那么代码里面直接引用全局包就可以 ...

  2. 【题解】 CF11D A Simple Task

    [题解] CF11D A Simple Task 传送门 \(n \le 20\) 考虑状态压缩\(dp\). 考虑状态,\(dp(i,j,O)\)表示从\(i\)到\(j\)经过点集\(O\)的路径 ...

  3. Eclipse javax.servlet.jsp.PageContext cannot be resolved to a type 错误解决办法

    不要 直接将jsp-api.jar拷贝到lib目录下,而是通过外部jar包引用.项目 右键->Properties->Libraries->Add External JARS-选择 ...

  4. 创建spring管理的自定义注解

    转自: http://blog.csdn.net/wuqiqing_1/article/details/52763372 Annotation其实是一种接口.通过Java的反射机制相关的API来访问A ...

  5. MySQL——多版本并发控制

    核心心知识点: (1)MVCC的优点和缺点 (2)MVCC的工作机制 之前在提及幻读的时候,提到过InnoDB的多版本并发控制可以解决幻读问题. 大多数MySQL的事务性存储引擎,例如InnoDB.F ...

  6. 在maven 中部署SSM项目找不 Spring ContextLoaderListener 的解决办法

    1.项目使用技术:maven的项目使用了Spring MVC+Spring +Mybatis+Tomcat搭建一个项目. 2.报错信息: Error configuring application l ...

  7. 20145239杜文超 《Java程序设计》第1周学习总结

    20145239<Java程序设计>第1周学习总结 教材学习内容总结 第一周. 通过教材简单的了解了java的历史.因为之前看过视频,所以有一个大致明了的认识. 识记了Java三大平台:J ...

  8. joomla搬家之后打不开 首页404错误

    joomla 安装好之后, 网站打不开,首页404错误,后台能够正常访问,数据库连接正常.应该是 nginx配置的问题.该如何修改配置呢?随便一个链接点进去都是404,找不到页面,URL的形式如下: ...

  9. 左侧浮动html网页模板

    左侧浮动html网页模板是一款左侧导航菜单随网页滚动的html网站模板. 地址:http://www.huiyi8.com/sc/10617.html

  10. html5常用模板下载网站

    html5常用模板下载网站 开创者素材.站长素材.模板之家 推荐葡萄家园素材网,他们网页模板栏目有个HTML模板,很多静态源码.应该是你所需要的. html静态页面模板 还是服饰素材啊 朋友 设计云 ...