Tornado [Erro 24] Muitos arquivos abertos [duplicado]
Esta pergunta já tem uma resposta aqui:
Tornado “erro: [erro 24] Muitos arquivos abertos” erro 1 respostaEstamos executando um serviço Tornado 3.0 em um sistema operacional RedHat e obtendo o seguinte erro:
[E 140102 17:07:37 ioloop:660] Exception in I/O handler for fd 11
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/tornado/ioloop.py", line 653, in start
self._handlers[fd](fd, events)
File "/usr/local/lib/python2.7/dist-packages/tornado/stack_context.py", line 241, in wrapped
callback(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/tornado/netutil.py", line 136, in accept_handler
connection, address = sock.accept()
File "/usr/lib/python2.7/socket.py", line 202, in accept
error: [Errno 24] Too many open files
Mas não conseguimos descobrir o que isso significa.
Nosso código Tornado é o seguinte:
import sys
from tornado.ioloop import IOLoop
from tornado.options import parse_command_line, define, options
from tornado.httpserver import HTTPServer
from tornado.netutil import bind_sockets
import tornado
sys.path.append("..")
from tornado.web import RequestHandler, Application
from shared.bootstrap import *
from time import time
from clients import ClientFactory
from shared.configuration import Config
from shared.logger import Logger
from algorithms.neighborhood.application import NeighborhoodApplication
import traceback
define('port', default=8000, help="Run on the given port", type=int)
define('debug', default=True, help="Run application in debug mode", type=bool)
class WService(RequestHandler):
_clients = {}
def prepare(self):
self._start_time = time()
RequestHandler.prepare(self)
def get(self, algorithm = None):
self.add_header('Content-type', 'application/json')
response = {'skus' : []}
algorithm = 'neighborhood' if not algorithm else algorithm
try:
if not algorithm in self._clients:
self._clients[algorithm] = ClientFactory.get_instance(algorithm)
arguments = self.get_arguments_by_client(self._clients[algorithm].get_expected_arguments())
response['skus'] = app.get_manager().make_recommendations(arguments)
self.write(response)
except Exception as err:
self.write(response)
error("Erro: " + str(err))
def get_arguments_by_client(self, expected_arguments):
arguments = {}
for key in expected_arguments:
arguments[key] = self.get_argument(key, expected_arguments[key])
return arguments
def on_connection_close(self):
self.finish({'skus':[]})
RequestHandler.on_connection_close(self)
def on_finish(self):
response_time = 1000.0 *(time() - self._start_time)
log("%d %s %.2fms" % (self.get_status(), self._request_summary(), response_time))
RequestHandler.on_finish(self)
def handling_exception(signal, frame):
error('IOLoop blocked for %s seconds in\n%s\n\n' % ( io_loop._blocking_signal_threshold, ''.join(traceback.format_stack(frame)[-3:])))
if __name__ == "__main__":
configuration = Config()
Logger.configure(configuration.get_configs('logger'))
app = NeighborhoodApplication({
'application': configuration.get_configs('neighborhood'),
'couchbase': configuration.get_configs('couchbase'),
'stock': configuration.get_configs('stock')
})
app.run()
log("Neighborhood Matrices successfully created...")
log("Initiating Tornado Service...")
parse_command_line()
application = Application([
(r'/(favicon.ico)', tornado.web.StaticFileHandler, {"path": "./images/"}),
(r"/(.*)", WService)
], **{'debug':options.debug, 'x-headers' : True})
sockets = bind_sockets(options.port, backlog=1024)
server = HTTPServer(application)
server.add_sockets(sockets)
io_loop = IOLoop.instance()
io_loop.set_blocking_signal_threshold(.05, handling_exception)
io_loop.start()
É um script muito básico, basicamente ele pega o URL, processa-o nomake_recommendation
função e envia de volta a resposta.
Tentamos definir um tempo limite de tornado de 50 ms através doio_loop.set_blocking_signal_threshold
funcionar, pois às vezes o processamento do URL pode demorar tanto.
O sistema recebe cerca de 8000 solicitações por minuto e funcionou bem por cerca de 30 minutos, mas depois disso começou a emitir o "erro de muitos arquivos" e quebrou. Em geral, as solicitações demoravam cerca de 20 ms para serem processadas, mas quando o erro começou a ocorrer, o tempo consumido aumentou para segundos, de repente.
Tentamos ver quantas conexões a porta 8000 tinha e ela tinha várias conexões abertas, todas com o status "ESTABELECIDO".
Há algo errado no nosso script Tornado? Acreditamos que nossa função de tempo limite não está funcionando corretamente, mas, pelo que pesquisamos até agora, tudo parece estar bem.
Se você precisar de mais informações, por favor me avise.
Desde já, obrigado,