Python에서 여러 Request 동시에 보내기
비동기식 동작을 대응하기 전까지는, 파이썬만큼 완벽한 프로그래밍 언어도 없습니다.
자바스크립트를 사용하는 많은 개발자 분들이, 콜백 지옥에 대해 불평하면서도, 막상 비동기 호출을 해야 하는 경우에는 금방 자바스크립트에 감사하게 됩니다.
최근에 여러 요청을 한 번에 보내야 하는 작업이 필요했습니다. 또한 그 요청들의 응답을 한 변수에 모아야 했습니다.
1. 일반 요청
10개의 요청을 순차적으로 보내면, 총 11.285초가 걸립니다.
더 많은 요청을 보내면, 비례해서 더 긴 시간이 걸릴 것입니다.
어떻게 문제를 해결했는지 보시죠!
2. 동시 GET request
첫 번째, 두 번째 줄은 필요한 파이썬 패키지를 임포트 한 곳이고,
네 번째 줄은 request를 요청할 함수입니다.
7번째 줄은 우리가 동시에 요청을 보낼 10개의 URL을 list에 담아 두었습니다.
9-10 번째 줄이 가장 중요한 부분인데, “ThreadPoolExecutor”란 비동기식으로 사용할 수 있는 스레드들의 묶음이라고 생각하시면 됩니다. 그래서 코드에서 보시는 바와 같이, 동시에 동작할 수 있는 worker의 숫자를 지정할 수 있습니다.
하지만, worker를 많이 넣는 다고 해서 꼭 더 좋은 성능이 보장되는 것은 아닙니다. (이 답변 참조)
10번째 줄에서, 인자로 넣은 get_url과 list_of_urls 때문에 보통 많은 분들이 헷갈려하시는데, 간단하게 말해서 각각의 URL을 함수에 매핑한다고 보시면 됩니다.
다음과 같이.
get_url(url1)
get_url(url2)
...
get_url(url10)
이제 코드를 실행해보겠습니다.
이론적으로는, 가장 길게 걸린 요청 시간이 전체 요청 시간과 같습니다.
만약 10개의 스레드가 완전히 독립적으로 동작을 한다면, (각 스레드가 각 CPU 코어에 걸려서 동작을 하는 이상적인..) 1개의 요청과 10개의 요청의 시간 차이는 없을 것입니다.
3. 동시 POST request
그런데, get_url 함수에 어떻게 두 개 이상의 인자를 넣을 수 있을지 헷갈리실 수도 있습니다.
이때는 리스트를 구성하는 각각의 원소를 아래 코드처럼 tuple로 구성하시면 됩니다.
11번째 줄에서 보시는 바와 같이, 각각의 원소는 URL과 form_data라는 dict변수로 구성되어 있습니다.
4번째 줄에서 args [0]은 튜플의 첫 번째 원소인 url을 의미하고, args [1]는 튜플의 두 번째 원소인 form_data를 의미합니다.
마지막 테스트
Happy coding!