본문 바로가기

QA 업무

비동기 처리 로직 (Asynchronous Processing Logic)

비동기 처리 로직 (Asynchronous Processing Logic)

작업이 동시에 수행되도록 하는 프로그래밍 방으로, 요청을 보내고 응답을 기다리지 않고 다른 작업을 진행할 수 있게 해줍니다. 이는 특히 성능 최적화응답 시간 감소에 효과적입니다.

1. 동기 처리와 비동기 처리의 차이점

동기 처리(Synchronous Processing) : 요청을 보내고 응답을 받을 때까지 대기합니다. 예를 들어, API 요청을 보내면 서버에서 응답이 올 때까지 기다린 뒤 다음 작업을 진행합니다. 한 작업이 완료되어야만 다음 작업이 실행됩니다.

비동기 처리(Asynchronous Processing) : 요청을 보내고 응답을 기다리지 않고 바로 다음 작업을 진행할 수 있습니다. 여러 작업이 병렬로 실행되며, 응답이 오는 순서에 관계없이 처리됩니다.

 

2. 비동기 처리의 장점

응답 시간 단축: 서버가 다른 요청을 처리하거나 *I/O 작업을 수행하는 동안 기다리지 않고 다른 작업을 처리할 수 있어 전체 응답 시간이 줄어듭니다.

자원 활용 최적화: 비동기 처리 방식은 CPU, 메모리 등의 자원을 효율적으로 사용하므로 더 많은 요청을 동시에 처리할 수 있습니다.

사용자 경험 개선: 사용자 입장에서 시스템이 빠르게 반응하고, 지연 시간이 줄어드는 효과가 있습니다.

 


*I/O 작업이란?

입력(Input)과 출력(Output)을 처리하는 컴퓨터 시스템의 작업을 의미합니다.

이 작업은 데이터를 프로그램이나 외부 장치(예: 파일 시스템, 네트워크, 디스크, 입력 장치 등)와 주고받는 과정입니다.

 

I/O 작업의 종류

- 디스크 I/O: 데이터를 하드디스크나 SSD와 주고받는 작업입니다. 예를 들어, 파일을 읽거나 쓰는 작업이 이에 해당합니다.

- 네트워크 I/O: 네트워크를 통해 데이터를 송수신하는 작업입니다. 예를 들어, 서버와 클라이언트 간의 데이터 전송, 웹 페이지 로딩 등이 네트워크 I/O 작업입니다.

- 키보드, 마우스 입력: 사용자로부터 입력을 받는 I/O 작업입니다.

- 출력 장치 I/O: 모니터, 프린터 등과 같은 출력 장치에 데이터를 전달하는 작업입니다.

 

특징

블로킹 I/O: I/O 작업이 완료될 때까지 프로그램이 대기하는 방식입니다.

예를 들어, 파일을 읽고 있는 동안 프로그램은 파일이 끝날 때까지 멈춥니다.

 

논블로킹 I/O: I/O 작업이 완료되기 전에 프로그램이 계속 실행되는 방식입니다. 주로 비동기식 작업에서 사용됩니다.

I/O 작업은 시스템의 성능에 중요한 영향을 미치기 때문에 효율적인 I/O 처리 방법이 중요합니다.

예를 들어, 대량의 데이터 처리나 실시간 시스템에서는 I/O 성능이 시스템 전체 성능을 좌우할 수 있습니다.


 3. 예시: API 요청 비동기 처리

import asyncio
import aiohttp

# 비동기 함수 정의
async def fetch_data(url):
    async with aiohttp.ClientSession() as session:
        async with session.get(url) as response:
            result = await response.json()
            print(result)

# 여러 API 호출을 비동기로 실행
async def main():
    urls = [
        'https://api.example.com/data1',
        'https://api.example.com/data2',
        'https://api.example.com/data3'
    ]
    tasks = [fetch_data(url) for url in urls]
    await asyncio.gather(*tasks)

# 비동기 함수 실행
asyncio.run(main())

 

 

설명: 위 코드에서는 Python의 asyncio와 aiohttp 라이브러리를 사용하여 비동기로 API 요청을 보냅니다.

fetch_data 함수비동기 요청을 보내며, 응답을 기다리는 동안 다른 요청을 동시에 진행할 수 있습니다.

asyncio.gather는 모든 비동기 작업을 병렬로 실행하여 시간을 절약합니다.


asyncio 라이브러리

Python에서 비동기 프로그래밍을 위한 라이브러리로, async/await 구문을 사용하여 동시 실행 코드를 작성할 수 있게 해줍니다.

이를 통해 I/O 작업(예: 네트워크 요청, 파일 처리 등)을 효율적으로 처리하면서 프로그램의 성능을 향상시킬 수 있습니다.

 

주요 개념

비동기 프로그래밍 (Asynchronous Programming):

비동기 프로그래밍은 여러 작업을 동시에 처리할 수 있게 해주며, 각 작업이 완료될 때까지 기다리지 않고 다른 작업을 처리하는 방식입니다. 특히 I/O 작업처럼 외부 자원과의 상호작용에서 발생하는 대기 시간을 줄이는 데 유용합니다.

 

이벤트 루프 (Event Loop):

asyncio의 핵심은 이벤트 루프입니다. 이벤트 루프는 비동기적으로 실행되는 작업들을 관리하고, 각 작업이 완료되기를 기다리는 동안 다른 작업을 실행하여 효율성을 높입니다.

 

코루틴 (Coroutine):

코루틴은 async def로 정의되는 함수로, 비동기 실행을 지원합니다. await 키워드를 사용하여 다른 비동기 작업을 기다리거나 실행을 일시 중단하고, 나중에 다시 시작할 수 있습니다.

 

태스크 (Task):

태스크는 코루틴을 감싸서 이벤트 루프에서 동시에 실행할 수 있도록 만들어주는 객체입니다. asyncio.create_task()로 코루틴을 태스크로 만들어 관리할 수 있습니다.

 

논블로킹 I/O (Non-blocking I/O):

asyncio는 논블로킹 I/O를 지원하여, I/O 작업이 완료될 때까지 다른 작업을 기다리지 않고 다른 작업을 수행할 수 있도록 합니다.

예를 들어, 파일을 읽거나 네트워크 요청을 보낼 때 다른 작업을 동시에 처리할 수 있습니다.

 

예시 코드:

import asyncio

async def fetch_data():
    print("데이터 가져오는 중...")
    await asyncio.sleep(2)  # 2초 동안 대기 (I/O 작업을 모사)
    print("데이터 가져옴!")

async def main():
    task1 = asyncio.create_task(fetch_data())
    task2 = asyncio.create_task(fetch_data())
    await task1
    await task2

# 이벤트 루프 실행
asyncio.run(main())

 

위 예시에서 fetch_data()는 2초간 대기하는 코루틴으로, 두 개의 fetch_data 작업을 비동기적으로 동시에 실행합니다.

await asyncio.sleep(2)는 I/O 작업을 기다리는 동안 다른 작업을 실행할 수 있게 해주죠.

 

사용 사례

웹 크롤링: 여러 웹 페이지를 동시에 비동기적으로 요청하여 데이터를 가져오는 작업.

네트워크 서버: 동시에 여러 클라이언트의 요청을 처리해야 하는 서버.

파일 I/O: 여러 파일을 읽거나 쓸 때, 한 파일의 작업이 끝날 때까지 기다리지 않고 다른 파일을 처리하는 경우.

 

장점

효율적인 I/O 처리: 비동기적으로 작업을 처리하여 대기 시간을 최소화하고 시스템 자원을 효율적으로 사용합니다.

높은 성능: 동시 실행이 가능하여, 많은 양의 작업을 빠르게 처리할 수 있습니다.

asyncio는 비동기 프로그램을 작성하는 데 매우 유용한 도구로, 특히 I/O 작업에 강력한 성능을 발휘합니다.


4. 웹 애플리케이션에서 비동기 처리 사례

상품 목록 조회 기능: 사용자가 상품 목록을 요청하면, 비동기 API 호출을 사용해 다양한 카테고리의 상품 정보를 동시에 가져옵니다. 이를 통해 전체 응답 시간을 단축할 수 있습니다.

결제 처리: 결제 요청 후, 결제 상태를 확인하는 작업을 비동기로 처리하여 서버의 부하를 줄이고, 빠르게 응답할 수 있습니다.

정리

비동기 처리 로직은 특히 서버의 응답 지연을 줄이고, 더 많은 요청을 효율적으로 처리할 수 있게 도와줍니다. 이를 통해 시스템의 성능을 향상시키고, 병목 현상을 줄일 수 있습니다. JMeter와 같은 성능 테스트 도구를 활용하면 비동기 처리 로직 적용 전후의 성능 개선 효과를 쉽게 검증할 수 있습니다.