반응형
Python을 하다보면 가장 많은 오류를 볼 수 있는 부분이 Max retries 오류이다.
HTTPConnectionPool(host='localhost', port=8080): Max retries exceeded with url: /xxx (Caused by NewConnectionError('<urllib3.connection.HTTPConnection object at 0x00000000>: Failed to establish a new connection: [Errno 61] Connection refused'))
이는 2가지 경우인데 자신의 Connection Pool이 꽉 차서 나타나거나, 반대로 상대방이 요청을 거부하는 경우이다.
보통 HTTPAdapter의 Retry 옵션을 구성해서 사용하는데 세밀하게 설정할 수 있다.
Retry 설정
def requests_retry_session(
retries=10, # 재시도 횟수
backoff_factor=2, # 재시도시 대기 시간, 재시도 횟수가 올라갈 때 제곱으로 시간이 올라간다.
status_forcelist=(500, 502, 504), # 재시도에 추가할 HTTP Status, 500, 502, 504 에러시 기본적으로 Retry를 하지 않는다.
session=None, # 세션이 함께 함수에 넘어오는지 확인
):
session = session or requests.Session()
retry = Retry(
total=retries,
read=retries,
connect=retries,
backoff_factor=backoff_factor,
status_forcelist=status_forcelist,
)
adapter = HTTPAdapter(max_retries=retry)
session.mount('http://', adapter)
session.mount('https://', adapter)
return session
#사용
requests_retry_session.get('https://asecurity.dev')
다만 위 HTTPAdapter를 조정하게 되면, 전체 세션에 영향을 주게된다. 따라서 sleep을 활용하는 것을 추천한다.
재시도 함수
지정된 status code가 아닌 경우 50초까지 return을 통해 다시 실행하도록 한다.
def http_request(method, url, data=None, headers=None, num_of_seconds_to_wait=3):
"""HTTP Request 정리"""
try:
res = requests.request(method,
url,
verify=False,
data=data,
headers=headers,
timeout=15
)
if res.status_code not in (200, 204, 202):
if random_num_of_seconds <= 50: # 50초가 넘어가면 멈춘다.
random_num_of_seconds = random.randint(num_of_seconds_to_wait, num_of_seconds_to_wait + 3)
time.sleep(random_num_of_seconds)
return http_request(method, url, data, headers=headers,
num_of_seconds_to_wait=num_of_seconds_to_wait + 3)
else:
raise Exception(f'Your request failed with the following error: {res.status_code}')
except Exception as e:
logging.warning(f'Http request failed with url={url}\tdata={data}')
logging.warning(e)
raise e
return res
반응형
'Python' 카테고리의 다른 글
Python - 타입 비교 type, isinstance (0) | 2024.03.14 |
---|---|
Python - Linting, 소스 분석, 코드 최적화 flake8 (0) | 2024.03.14 |
Python - 동적 리스트(dynamic list) 해결 ValueError: too many values to unpack (0) | 2024.03.14 |
Django - Database Migration Command 요약 정리 (0) | 2024.03.14 |
Django - 메일 주소 표준화, 자동 교정하기 email (0) | 2024.03.14 |