Поскольку tornado-es
является только клиент HTTP, он использует AsyncHTTPClient
в ESConnection
. Новое TCP-соединение производится по каждому запросу, если не указано заголовок Connection: keep-alive
.
conn = ESConnection()
conn.httprequest_kwargs['headers'] = {'Connection': 'keep-alive'}
Я не тестировал, но он должен работать. Я использовал подобную установку в рубине (с patron клиента HTTP), и он работает хорошо
Следующая вещь
AsyncHTTPClient
имеет ограничение на максимальное число одновременных запросов (fetch
) в ioloop. Каждый запрос, который попадает в предел, просто находится внутри очереди.
Вы можете увеличить глобальное ограничение:
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 вы можете создать в приложении, так как приложение доступно с каждым запросом (Reque stHandler)
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, приложение шлюза эс
subprocess1
\ (http, zmq, ...)
\
> pooler (some queue and tornadoes api) - http -> elastisearch
/
/
subprocess2
подпроцессы могут взаимодействовать с Pooler через HTTP, ØMQ (есть много примеров, даже Пулера) или некоторые реализации IPC (sockects , ...).
Привет @kwarunek и большое спасибо за ваш ответ. Я полностью понимаю, что вы сказали, и работает отлично. Единственное, что я не понимаю, - это если можно использовать его с несколькими подпроцессами. Внутри моего основного я реализовал механизм, из которого я получаю из командной строки, сколько подпроцессов запускается, таким образом: 'http_server = tornado.httpserver.HTTPServer (MyApp) '' http_server.bind (8888) '' http_server.start (tornado.options.options.processes) '' tornado.ioloop.IOLoop.current(). Начать() ' Возможно ли использовать ваш пример в нескольких подпроцессах? – alauri
Я попытался запустить свой Tornado с двумя подпроцессами, и я получил эту ошибку: 'RuntimeError: не может работать в нескольких процессах: экземпляр IOLoop уже инициализирован. Вы не можете вызвать IOLoop.instance() перед вызовом start_processes() '. – alauri
Я добавил примечание о многопроцессорности. – kwarunek