Tornado常见问题与解决方案

1.用python tornado 作为后端框架
echarts 各种图表展示后端的各种数据
其实很简单
<code>self.render('index.html',data=data)</code>
你以为这样就完事了么????然而不是这样的,tornado render出来的数据是str
但是echarts需要的数据为json,所以这里需要改造一下echarts
原有echarts代码:
<code>$.get("./static/life-expectancy.json", function (data)</code>
需改造为:

<code>$.getJSON("./static/life-expectancy.json", function (data)</code>这里感谢jquery提供的强大代码库

2.tornado连接mysql,用torndb的一个小坑:
    get就是取一行数据,返回Row类,其实就是dict
    tornado 是异步的,所以查询mysql的时候,单条异步连接
    可以用类似    get();    query();    insert();    update();    这样的方式,

    但是在get中,完成查询,一定要写close,因为在建立一次连接后,没有断开连接,就继续进行下一次的连接,就会导致连接失败,类似(mysql has gone,或者con't connect on xxxxxx)

3.事情是这样的,服务端使用 tornado 提供 api 接口给客户端使用,存储使用 mysql ,使用 tormysql 连接 MySQL 数据库查询,前天下午时服务器网络突然断了, 15 分钟后回复,可是 api 接口还是无法使用

查看服务器状态,网络正常,负载正常,服务正常,于是去查看 nginx 日志,发现 99%的请求都 504 超时了,查看 mysql 服务器, cpu 负载接近 100%,命令行进 mysql show processlist 查看,将近 400 个查询正在运行,大量处于 statistics 状态,每个查询时间明显高了不少,但也还是有查询正常返回了,并未超过请求超时时间,为什么 nginx 显示几乎所有请求都超时了呢? 
想不明白于是果断重启试试,重启不一会 504 超时又慢慢上升,不一会几乎所有的请求均超时无返回,如此数次还是无法正常启动,最后不得不关掉大部分借口再慢慢放开服务才起来,为此导致借口听着服务达数小时。 
事后对 mysql 负载虽然满了,查询很慢却还是有返回,但请求几乎都超时甚是不接,于是仔细查看日志,终于发现原来网络异常后,客户端一直在重试,网络正常后,瞬间过来的并发高了十几倍,由于 tornado 异步 IO 高并发的特性,并未出现访问拒绝,而是接受了所有的请求,并都产生了 mysql 查询发往数据库,所有 mysql 瞬间并发查询十分高导致负载上升,每个查询耗时高达数秒,同时 tornado 在使用 tormysql 查询超过最大连接数后并进入队列等待,慢慢的,队列等待时间超过请求超时时间, nginx 返回 504 超时,但在队列中的查询还是继续发往 mysql ,因为客户端为收到正常返回,所以再次发起重试,又再次增加了查询队列的长度,最终所有请求在队列中等待 mysql 查询的时间都超过了请求超时时间,所以也就出现了 mysql 负载很高但几乎所有请求都超时的情况。 
tornado 使用异步 io 确实实现了超高并发的支持,但也正是因为如此,但其依赖的后端服务超过负载后缺少快速失败的特性,其能同时接受大量请求的特性会使得在等待后端服务过程中出现循环超时,最终出现服务不可用情况,
又再次对 mysql 进行了测试,原来是有一个查询 join 了三张表, 400 并发导致直接耗尽了 cpu ,单表有索引查询还是过万的,不过重点还是 tornado 在使用异步 mysql 驱动过程中对突然升高的并发超过 mysql 负载时缺少快速失败机制
是的,以前一直想高并发高并发的,没想过超过 mysql 查询数后的快速失败策略,学习到了,现在果断调低了连接池最大连接数, TorMySQL 应该有个队列等待超时策略才是

猜你喜欢

转载自blog.csdn.net/miantian180/article/details/79379360