aiodns не может связаться с DNS-серверами при работе в терминале OS X
Следующий фрагмент кода асинхронно выбирает несколько общедоступных DNS-серверов. Если скрипт выполняется в PyCharm, он работает отлично и разрешает все указанные средства распознавания с очень небольшим количеством ошибок (~14 ошибок в 1078 запросах).
Однако, если я запускаю точно такой же сценарий в терминале OS X, только первые ~280 запросов aiodns являются успешными, а остальные возвращают aiodns.DNSError(11, "Не удалось связаться с DNS-серверами")(~834 ошибки в 1078 запросах).
Копировать вставить resolvers_short
список из https://pastebin.com/wSYtzebZ
Этот код является частью моего проекта с открытым исходным кодом на https://github.com/MMquant/DNSweeper/blob/master/DNSweeper.py
import asyncio
import aiodns
#resolvers_short = [fill resolvers from link]
class Fetcher(object):
def __init__(self):
self.loop = asyncio.get_event_loop()
def get_records(self, names, query_type, resolvers):
coros = [self._query_sweep_resolvers(names, query_type, resolver) for resolver in resolvers]
tasks = asyncio.gather(*coros, return_exceptions=True)
records = self.loop.run_until_complete(tasks)
return records
async def _query_sweep_resolvers(self, name, query_type, nameserver):
resolver = aiodns.DNSResolver(
nameservers=[nameserver],
timeout=5,
tries=3,
loop=self.loop
)
try:
result = await resolver.query(name, query_type)
except aiodns.error.DNSError as e:
result = e
return {'ns': nameserver,'name': name ,'type': query_type, 'result': result}
def errors_count(results):
count = 0
for result in results:
if type(result['result']) is aiodns.error.DNSError:
count += 1
return count
if __name__ == '__main__':
fetcher = Fetcher()
results = fetcher.get_records('www.flickr.com', 'A', resolvers_short)
# print(results)
errors = errors_count(results)
# In 1078 resolvers
# If script executed in PyCharm there are only ~14 aiodns response errors on average
# If script executed in terminal there are ~834 aiodns response errors where majority are
# DNSError(11, 'Could not contact DNS servers')
print(errors)
pass
Я не знаю, как продолжить отладку.
Это модули, которые я использую:
aiodns==1.1.1
pycares==2.3.0
1 ответ
Я обнаружил, что OS X допускает только 256 TCP-соединений одновременно. Я увеличил его, отредактировав мягкий предел дескрипторов файлов
$ ulimit -S -n
256
$ ulimit -S -n 50000
$ ulimit -S -n
50000
Я дополнительно добавил следующий код, чтобы динамически устанавливать мягкое ограничение открытых дескрипторов файлов из программы:
import resource
new_soft_limit = 50000
(rlimit_nofile_soft, rlimit_nofile_hard) = resource.getrlimit(resource.RLIMIT_NOFILE)
resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft_limit, rlimit_nofile_hard))