非同期IOをつかったHTTPリクエストの処理 aiohttp

非同期IOを使うことでシングルプロセス、シングルスレッドでも効率的に複数のHTTPリクエストの処理を行う。

サーバー側の準備

はじめに動作確認用に複数のリクエストを処理できるHTTPサーバプログラムを用意する。

このサーバープログラム自体も非同期IOで記述することで複数のリクエストを処理するサーバーを記述できるのだが、サーバー側とクライアント側で非同期IOの説明すると、今回の論点がぼやけてくるので、ひとまずリクエストを受け付けると3秒待ってからレスポンスを返すマルチスレッドなサーバーを用意した。このプログラムの説明は本題ではないので省略。

これを起動して、別の端末からcurlで同時に3リクエストを送ってみると、3秒後に3つのレスポンスが返る。

$ python wsgi-server.py
$ seq 1 3 | xargs -P 3 -I{} curl "localhost:8000/{}"
Hello World/1
Hello World/2
Hello World/3

非同期IOによるHTTPリクエスト

サードパーティライブラリのaiohttpを使用すると、非同期なHTTPClientをかんたんに記述できる。

import aiohttp
import asyncio
import time


async def get_request(session, no):
    response = await session.get(f'http://localhost:8000/{no}')
    content = await response.text()
    print(f"{time.strftime('%X')} - {response.status} {content}", end='')


async def main():
    tasks = []
    print(f"{time.strftime('%X')} - Start")
    async with aiohttp.ClientSession() as session:
        for n in range(3):
            tasks.append(get_request(session, n+1))
        await asyncio.gather(*tasks)
    print(f"{time.strftime('%X')} - Finish")

asyncio.run(main())

実行結果

18:03:56 - Start
18:03:59 - 200 Hello World/3
18:03:59 - 200 Hello World/2
18:03:59 - 200 Hello World/1
18:03:59 - Finish
関連記事:

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)