September 15, 2017

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

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

October 16, 2016

nginx 499 Recv-Q

不知道标题应该怎么写才可以描述清楚这个问题。我们有一个服务,提供一些数据给自己用,后端连着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)不够好?

August 21, 2015

tornado 2

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

August 16, 2015

tornado 1

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

Powered by Hugo & Kiss.