Я изучаю проблему с приложением Python, запущенным на машине Ubuntu с 4G ОЗУ. Инструмент будет использоваться для аудита серверов (мы предпочитаем рулон наших собственных инструментов). Он использует потоки для подключения к большому количеству серверов, и многие из TCP-соединений терпят неудачу. Однако, если я добавлю задержку в 1 секунду между началом каждого потока, то большинство соединений будут успешными. Я использовал этот простой script для изучения того, что может произойти:
#!/usr/bin/python
import sys
import socket
import threading
import time
class Scanner(threading.Thread):
def __init__(self, host, port):
threading.Thread.__init__(self)
self.host = host
self.port = port
self.status = ""
def run(self):
self.sk = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.sk.settimeout(20)
try:
self.sk.connect((self.host, self.port))
except Exception, err:
self.status = str(err)
else:
self.status = "connected"
finally:
self.sk.close()
def get_hostnames_list(filename):
return open(filename).read().splitlines()
if (__name__ == "__main__"):
hostnames_file = sys.argv[1]
hosts_list = get_hostnames_list(hostnames_file)
threads = []
for host in hosts_list:
#time.sleep(1)
thread = Scanner(host, 443)
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
print "Host: ", thread.host, " : ", thread.status
Если я запустил это с помощью time.sleep(1), прокомментировавшего, скажем, 300 хостов, многие из подключений терпят неудачу с ошибкой тайм-аута, тогда как они не тайм-аут, если я ставлю задержку на одну секунду. я попробовал приложение на другом дистрибутиве Linux, работающем на более мощной машине, и было не так много ошибок подключения? Это связано с ограничением ядра? Есть ли что-нибудь, что я могу сделать, чтобы заставить соединение работать без задержки?
UPDATE
Я также пробовал программу, которая ограничивала количество потоков, доступных в пуле. Уменьшая это до 20, я могу заставить все подключения работать, но он проверяет только 1 хост в секунду. Так что, что бы я ни пытался (помещаясь в сон (1) или ограничивая количество одновременных потоков), я не могу проверять более 1 хоста каждую секунду.
UPDATE
Я нашел этот question, который кажется похожим на то, что я вижу.
UPDATE
Интересно, может ли написать это с помощью скручивания? Может ли кто-нибудь показать, что мой пример будет выглядеть как написанный с использованием скрученного?