Поскольку tornado-es
— это всего лишь HTTP-клиент, он использует AsyncHTTPClient
. в ESConnection
. Новое TCP-соединение устанавливается при каждом запросе, если не указан заголовок Connection: keep-alive
.
conn = ESConnection()
conn.httprequest_kwargs['headers'] = {'Connection': 'keep-alive'}
Я не проверял, но должно работать. Я использовал аналогичную настройку в ruby (с http-клиентом patron), и он работает хорошо.
Следующее
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, вы можете создать его в приложении, поскольку приложение доступно для каждого запроса (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) или как оптимизация на высоконагруженном сервисе.
И вам придется написать пулер, приложение-шлюз к es
subprocess1
\ (http, zmq, ...)
\
> pooler (some queue and tornadoes api) - http -> elastisearch
/
/
subprocess2
Подпроцессы могут связываться с пулером через HTTP, ØMQ (есть много примеров, даже пулер) или некоторая реализация IPC (сокеты, .. .).
07.03.2016
http_server = tornado.httpserver.HTTPServer(MyApp)
http_server.bind(8888)
http_server.start(tornado.options.options.processes)
tornado.ioloop.IOLoop.current().start()
Возможно ли использовать ваш пример в нескольких подпроцессах? 07.03.2016RuntimeError: Cannot run in multiple processes: IOLoop instance has already been initialized. You cannot call IOLoop.instance() before calling start_processes()
. 07.03.2016