[파이썬] aiohttp와 `asyncio` 태스크 관리

aiohttp와 asyncio

aiohttp는 Python에서 비동기 웹 애플리케이션을 개발하기 위한 빠르고 강력한 라이브러리입니다. 이를 통해 쉽게 비동기적으로 HTTP 요청을 처리하고 웹 서버를 구축할 수 있습니다. 그러나 aiohttp를 사용할 때, 주의해야 할 중요한 측면 중 하나는 asyncio 작업 관리입니다.

asyncio의 장점

asyncio는 Python 3.4이상에서 기본 제공되는 라이브러리로, 비동기식 코드 작성을 가능하게 합니다. 이를 통해 단일 스레드에서 여러 작업을 병렬로 실행할 수 있으며, I/O 바운드 작업에서 뛰어난 성능을 발휘합니다. 아래는 asyncio를 활용한 간단한 예제입니다.

import asyncio

async def process_request(url):
    # 비동기 작업을 처리하는 코드 작성
    pass

async def main():
    urls = ['http://example.com', 'http://example.org', 'http://example.net']
    tasks = [process_request(url) for url in urls]
    await asyncio.gather(*tasks)

if __name__ == '__main__':
    asyncio.run(main())

aiohttp와 asyncio의 함께 사용

aiohttpasyncio를 함께 사용하면, 비동기 웹 애플리케이션을 쉽게 개발할 수 있습니다. 아래 예제는 aiohttp를 사용하여 비동기식으로 웹 요청을 보내는 간단한 코드입니다.

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        html = await fetch(session, 'http://example.com')
        print(html)

if __name__ == '__main__':
    asyncio.run(main())

위의 코드에서 fetch 함수는 aiohttp.ClientSession을 사용하여 비동기로 웹 요청을 수행합니다. main 함수에서는 async with 문을 사용하여 aiohttp.ClientSession을 관리하고, fetch 함수를 비동기적으로 호출합니다.

asyncio 태스크 관리

asyncio를 사용할 때 주의해야 할 점은 대기 중인 태스크를 적절히 관리하는 것입니다. 대부분의 비동기 코드에서는 여러 개의 asyncio 태스크를 만들고 실행하게 됩니다. 이러한 태스크들을 효율적으로 관리하는 것이 중요합니다.

예를 들어, 동시에 10개의 웹 요청을 만들 수 있다고 가정해 봅시다. 이 짧은 예제에서는 10개의 웹 요청에 대한 응답을 기다리는 동안 CPU가 대기 상태에 있을 수 있습니다. 이런 경우에서는 CPU 시간을 잘 활용하기 위해 asyncio.gather 또는 asyncio.wait와 같은 함수를 사용하여 대기 중인 태스크를 실행하는 것이 좋습니다.

import aiohttp
import asyncio

async def fetch(session, url):
    async with session.get(url) as response:
        return await response.text()

async def main():
    async with aiohttp.ClientSession() as session:
        urls = ['http://example.com', 'http://example.org', 'http://example.net']
        tasks = [fetch(session, url) for url in urls]
        # 모든 태스크를 비동기적으로 실행
        responses = await asyncio.gather(*tasks)
        for response in responses:
            print(response)

if __name__ == '__main__':
    asyncio.run(main())

위의 예제에서는 fetch 함수를 3번 호출하고, 모든 태스크를 비동기적으로 실행한 후, 응답을 출력합니다. asyncio.gather 함수를 사용하여 여러 태스크를 동시에 실행하고 결과를 한꺼번에 받아옵니다.

결론

aiohttp를 사용하여 비동기 웹 애플리케이션을 개발할 때, asyncio 태스크 관리는 중요한 요소입니다. 적절한 태스크 관리를 통해 비동기 코드의 성능을 최적화하고, 여러 작업을 병렬로 실행할 수 있습니다. 반드시 asyncio.gather 또는 asyncio.wait와 같은 함수를 사용하여 대기 중인 태스크를 실행하는 것을 잊지 마세요.