티스토리 뷰

회사에서 파이썬을 이용한 간단한 프로젝트를 하던 도중, aiohttp를 사용하면서 이상한 점을 하나 발견했습니다.

http 요청 작업시에 메인 쓰레드를 제외한 여러개의 쓰레드가 추가로 사용되는 것이었는데요,

 

파이썬의 비동기 작업은 기본적으로 싱글 쓰레드 위에서 비동기 코루틴을 이용해 구현되는게 정상인데, 이게 무슨 일인가 싶어 aiohttp쪽 코드를 뒤져보았습니다.

 

해답은 DNS Resolver 코드에 있었는데요, aiohttp/resolver.py 코드를 보면 아래와 같은 구문이 있습니다.

DefaultResolver = AsyncResolver if aiodns_default else ThreadedResolver

aiodns_default가 False인 경우, DNS Resolving을 위해 멀티 쓰레드를 활용(asyncio의 executor겠죠?)하도록 되어 있는데, 이 aiodns_default는 항상 False 입니다. 따라서 http 요청 작업시 마다 쓰레드가 추가로 사용됐던 것이였죠.

 

이유는 여기에 나와있는데, aiodns가 아직 표준 DNS API를 대체할 수 없기 때문이라고 합니다. 

 

그렇다면, AsyncResolver를 사용하기 위해선 어떻게 해야할까요? 우선 aiodns 패키지를 설치한 뒤, 기존의 코드를 아래처럼 수정하면 됩니다.

resolver = aiohttp.AsyncResolver()
connector = aiohttp.TCPConnector(resolver=resolver, family=socket.AF_INET)
async with aiohttp.ClientSession(connector=connector) as session:
	# blah blah...

이제 여러분의 프로그램은 더이상 DNS Resolving을 위해 추가적인 쓰레드를 사용하지 않습니다!

댓글