由于tornado-es 只是一个HTTP 客户端,它在ESConnection 中使用AsyncHTTPClient。 每个请求都会建立新的 TCP 连接,除非指定了 Connection: keep-alive 标头。
conn = ESConnection()
conn.httprequest_kwargs['headers'] = {'Connection': 'keep-alive'}
我没有测试过,但它应该可以工作。我在 ruby 中使用了类似的设置(使用patron http 客户端),效果很好
接下来的事情
AsyncHTTPClient 对每个 ioloop 的最大并发请求数 (fetch) 有限制。每个达到限制的请求都只是在内部排队。
您可能想要增加全局限制:
AsyncHTTPClient.configure(None, max_clients=50)
或者用自己的限制分隔客户端(force_instance):
from tornadoes import ESConnection
from tornado.httpclient import AsyncHTTPClient
class CustomESConnection(ESConnection):
def __init__(self, , host='localhost', port='9200', io_loop=None, protocol='http', max_clients=20):
super(CustomESConnection, self).__init__(host, port, io_loop, protocol)
self.client = AsyncHTTPClient(force_instance=True, max_clients=max_clients)
最后
要重用相同的 ESConnection,您可以在应用程序中创建它,因为应用程序可用于每个请求 (RequestHandler)
from tornado.web import Application, RequestHandler
from tornadoes import ESConnection
class MainHandler(RequestHandler):
def get(self):
yield self.application.es.search('something')
class MyApp(Application):
def __init__(self, *args, **kwargs):
super(MyApp, self).__init__(*args, **kwargs)
self.es = ESconnection()
if __name__ == "__main__":
application = MyApp([
(r"/", MainHandler),
])
application.listen(8888)
tornado.ioloop.IOLoop.current().start()
多进程
其实没有简单的方法。常见的方法是池化,主要用于需要持久连接的情况,如数据库(pgbouncer 用于 postgres)或作为高负载服务的优化。
你还得写一个pooler,一个es的网关应用
subprocess1
\ (http, zmq, ...)
\
> pooler (some queue and tornadoes api) - http -> elastisearch
/
/
subprocess2
子进程可以通过 HTTP、ØMQ(甚至是 pooler 有很多示例)或 IPC(sockects,...)的某些实现与 pooler 通信。