aiodns не может связаться с DNS-серверами при работе в терминале OS X - PullRequest
0 голосов
/ 19 декабря 2018

Следующий фрагмент кода асинхронно выбирает несколько общедоступных 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 Ответ

0 голосов
/ 19 декабря 2018

Я обнаружил, что 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))
...