一个请求到达tornado后如何被处理

September 15, 2017

异步非阻塞的tornado能够让同一台服务器接受更多的连接,服务更多用户,但对于每个用户来说,原本要等10秒才出现的浏览结果,现在至少还需要10秒,甚至可能还会慢一点,因为同样的硬件,现在有更多请求被接入进来。 ... Read more

nginx 499 Recv-Q

October 16, 2016

不知道标题应该怎么写才可以描述清楚这个问题。我们有一个服务,提供一些数据给自己用,后端连着Oracle和MSSQL数据库,由Nginx作为反向代理,Tornado作为后端服务查询写入数据。 一开始记得是开了8个Tornado进程,运行了挺长时间没发现问题,最近发现在调用接口是经常得到status code 499,这不是标准的code,而是nginx自己用的,用来表示客户端主动断开连接的状况。客户端在我们这里其实是python的requests库,比如我们需要刷新会员积分,会用requests请求接口,获得会员积分信息,调用时在requests的timeout参数中加入连接超时和读超时限制,一般连接超时设置到3.05s,读超时设置到27s。一般出现499时都是read timeout。 一开始我以为是8个Tornado不够,导致大量请求挤压在那里,超过27s,客户端断开。于是我增加一倍的Tornado进程,发现竟然没问题。后来我又增加到20个Tornado进程,不过实际根本不需要这样做,因为后来,在20个进程的情况下,依然出现大量499。 登陆到服务器上后,用netstat看了一下tcp连接情况,有很多连接状态是CLOSE_WAIT,并且Recv-Q基本都不为0,如果重启一下Tornado,一切又恢复正常,应该又可以用十几天。这个服务中途不会重启,这次遇到问题后我看了下这些进程都运行了12天,或许每天深夜重启一下是个很好的办法,但我仍想知道到底是怎么导致这样的结果。 因为这个接口都是我们自己调用,而且调用量大不到哪去,按理说4个Tornado+Nginx足够应对,暂时没有更具体的信息支持我继续研究,现在我减少Tornado进程到4个,过几天再看看效果。 最近又出现过几次499。这次梳理了一下,出现499是因为客户端(requests库)认为等了很久都没得到响应,超过了自己设定的timeout就主动断开了,nginx作为中间人当然知道,因为nginx一边接着客户端的请求,一边找后端要响应,现在客户端要求断开,nginx把499写到了日志中,此时,nginx应该让后端别继续做了,因为你即便得到结果,客户端也断开了,所以你(后端)还是干点别的去吧。 最近出现499都是调用某个特定方法时,超时,之后就会频繁出现499,目前做法是把这个方法的结果缓存了(在redis中),每次都从缓存中读取,定期再刷新缓存,过一阵子看看还会不会有问题。 过了一阵子,没出现问题,看来确实是这个方法导致的。这个方法需要连接SQL Server查询一些信息,估计是使用的python库(freetds和pymssql)不够好?

tornado 2

August 21, 2015

write some subclasses of RequestHandler and mapped these with routers, pass these routers to Application, run Application. from tornado.ioloop import IOLoop from tornado.web import RequestHandler, Application, url class HelloHandler(RequestHandler): def get(self): self.write("Hello, world") def make_app(): return Application([ url(r"/", HelloHandler), ]) def main(): app = make_app() app.listen(8888) IOLoop.current().start() Tornado supports strings, bytes, and dictionaries as response, you can use Template to building strings and bytes, also you can write response by hand. ... Read more

tornado 1

August 16, 2015

UPDATE on 2017-03-27 async means the library or API will call you in the future, there are some styles of async, callback, placeholder, etc. non-blocking means you must query result by yourself, using select, poll, etc. They look like call very quickly, because they always return before all codes are executed. UPDATE on 2017-03-29 In nearly all cases, any function that calls a coroutine must be a coroutine itself, and use the yield keyword in the call. ... Read more

© 2018 | Follow on Twitter | Hucore theme & Hugo