Форум сайта python.su
Все привет, нужна помощь сообщества, осваиваю потихоньку асинхронность в python и есть задача написать проверку DNS серверов.
Использую сейчас следующий код (пожалуйста, не обращайте внимание на форматирование и качество кода, это тестовый вариант, потом будет приведен в порядок):
[code python]
#!/usr/bin/env python
import dns.resolver
from pprint import pprint
import random
import time
import asyncio
from datetime import datetime
DNS_RESOLVER = dns.resolver.Resolver()
name_server = ['192.168.5.254']
import platform
print(platform.python_version())
hosts = [
'microsoft.com',
'amazon.com',
'facebook.com',
'twitter.com',
'google.com',
'youtube.com',
'instagram.com',
'linkedin.com',
'wordpress.org',
'pinterest.com',
'wikipedia.org',
'wordpress.com',
'blogspot.com',
'apple.com',
'adobe.com',
'tumblr.com',
'youtu.be',
'amazon.com',
'goo.gl',
'vimeo.com',
'flickr.com',
'microsoft.com',
'yahoo.com',
'godaddy.com',
'qq.com',
'bit.ly',
'reddit.com',
'w3.org',
'baidu.com',
'nytimes.com',
't.co',
'europa.eu',
'buydomains.com',
'wp.com',
'statcounter.com',
'www.miitbeian.gov.cn',
'jimdo.com',
'blogger.com'
]
def random_delay():
return int(random.random() * 10)
format_len=max(hosts, key=len)
import async_timeout
async def resolve_dns(record, delay=0):
print(f"Run dns_query for host: {record:<20s} with delay: {delay}".format(record, delay))
try:
await asyncio.sleep(delay)
with async_timeout.timeout(10):
answer = DNS_RESOLVER.query(record, "A")
rcode = dns.rcode.to_text(answer.response.rcode())
print("HOST: {0:<20s}, rcode: {1}, delay: {2}".format(record, rcode, delay))
except Exception as e:
print("Host: {0:<20s} has resolving issue: {1}".format(record, e))
# raise
else:
pass
finally:
pass
def main():
print("Run main function")
DNS_RESOLVER.timeout = 3
DNS_RESOLVER.nameservers = name_server
pprint(vars(DNS_RESOLVER), indent=2)
start = time.time()
tasks = []
loop = asyncio.get_event_loop()
try:
tasks = [
loop.create_task(resolve_dns(host, random_delay()))
for host in hosts
]
loop.run_until_complete(asyncio.gather(*tasks))
finally:
loop.close()
end = time.time()
print("Total time: {}".format(end - start))
if __name__ == "__main__":
print(f"{__file__} executed")
main()
[/code]
[code python]Run dns_query for host: buydomains.com with delay: 8
Run dns_query for host: wp.com with delay: 6
Run dns_query for host: statcounter.com with delay: 3
Run dns_query for host: www.miitbeian.gov.cn with delay: 6
Run dns_query for host: jimdo.com with delay: 5
Run dns_query for host: blogger.com with delay: 5
Host: wordpress.com has resolving issue: The DNS operation timed out after 30.002588987350464 seconds
Host: goo.gl has resolving issue: The DNS operation timed out after 30.00293493270874 seconds
Host: qq.com has resolving issue: The DNS operation timed out after 30.002574920654297 seconds
Host: bit.ly has resolving issue: The DNS operation timed out after 30.00347328186035 seconds
Host: reddit.com has resolving issue: The DNS operation timed out after 30.00317406654358 seconds
[/code]
Отредактировано InventoR (Март 17, 2019 18:44:26)
Офлайн
а дайте ссылку на модуль для dns котоырй вы используете.
Офлайн
Вот этот модуль:
http://www.dnspython.org/examples.html
но на сколько вижу он не поддерживает asyncio, соответственно наверное мне лучше поискать реализацию где уже есть поддержка async
Офлайн
Если ничего не напутал
import asyncio import logging import async_timeout import aiodns hosts = [ 'microsoft.com', 'amazon.com', 'facebook.com', 'twitter.com', 'google.com', 'youtube.com', 'instagram.com', 'linkedin.com', 'wordpress.org', 'pinterest.com', 'wikipedia.org', 'wordpress.coms', 'blogspot.com', 'apple.com', 'adobe.com', 'tumblr.com', 'youtu.be', 'amazon.com', 'goo.gl', 'vimeo.com', 'flickr.com', 'microsoft.com', 'yahoo.com', 'godaddy.com', 'qq.com', 'bit.ly', 'reddit.com', 'w3.org', 'baidu.com', 'nytimes.com', 't.co', 'europa.eu', 'buydomains.com', 'wp.com', 'statcounter.com', 'www.miitbeian.gov.cn', 'jimdo.com', 'blogger.com' ] async def resolve_dns(resolver, record, record_type='A', timeout=10): try: with async_timeout.timeout(timeout): fields = await resolver.query(record, record_type) if fields: for field in fields: logger.debug(f'Record: {record}, Address: {field.host}, TTL: {field.ttl}') else: logger.debug(f'Record {record} contains no fields.') except aiodns.error.DNSError as e: logger.error(f'Got error while querying {record} with type {record_type}. Error: {e}') except asyncio.TimeoutError: logger.error(f'Got timeout while querying {record} with type {record_type}.') async def main(): resolver = aiodns.DNSResolver(nameservers=['8.8.8.8']) broken_resolver = aiodns.DNSResolver(nameservers=['72.66.115.13']) tasks = [resolve_dns(resolver, host) for host in hosts] broken_tasks = [resolve_dns(broken_resolver, host) for host in hosts] for future in asyncio.as_completed(broken_tasks + tasks): await future if __name__ == '__main__': logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(name)s - [%(levelname)s] - %(message)s') logger = logging.getLogger() event_loop = asyncio.get_event_loop() event_loop.run_until_complete(main())
Офлайн
aiscyСпасибо огромное,
Если ничего не напутал
Офлайн
Я именно это и предполагал. И дал верную наводку.
Офлайн