-
[python] CLOSE_WAIT 해결 방법 with TimeoutIteratorProgramming Language/Python 2021. 5. 7. 11:20반응형
- tcp 연결된 소켓의 상태가
CLOSE_WAIT
상태에서 처리되지 못하고 계속 소켓을 잡고 있는 상황이 발생하여 해당 내용을 정리한다
0. 용어
- end, end-point : aplication, user 등 연결에서 한 쪽 끝 프로세스
- tcp 상태
1. 개념 정리
- CLOSED : 연결이 없음
- LISTEN : Passive open, SYN을 기다리는 상태
- SYN-SENT : SYN을 보내고 ACK를 기다리는 상태
- SYN-RECEIVED(SYN-RCVD) : SYN+ACK을 보내고 ACK를 기다리는 상태
- ESTABLISHED : 커넥션이 생성된 상태, 데이터를 전송할 수 있다.
- FIN-WAIT-1 : 첫 FIN이 보내진 상태, ACK를 기다리고 있다.
- CLOSE-WAIT : 첫 FIN을 받고 ACK를 보낸 상태, OS 는 프로그램의 연결 종료를 기다리고 있다.
- 문제는 프로그램이 실제로 socket 을 close 하지 않아서 발생
- TCP 튜닝 이슈가 아님 - TCP 튜닝을 해도 소용없다는 것
- 프로그램이 connection 을 계속 유지하면 CLOSE_WAIT 상태는 프로세스가 내려가기 까지 영원히 유지됨
- 따라서, 해당 연결을 유지하는 application 을 확인 해야함.
- FIN-WAIT-2 : 첫 FIN에 대한 ACK를 받은 상태, 2번째 FIN을 기다리고 있다.
- LAST-ACK : 2번째 FIN을 보내고 ACK를 기다리는 상태
- CLOSED : 양쪽이 동시에 닫기로 한 상태
- TIME-WAIT : CLOSED 상태로 가기전에 MSL 의 2배가 지날 때 까지 기다린다 - 상대 가 ACK 를 받았는지 확신하기 위해서
- MSL(the maximum segment lifetime) : 동일 연결이 생성 되지 않도록 대기하는 상태
2. CLOSE_WAIT 문제
- 각 어플리케이션마다 장시간 block 이 되는 코드가 있어서 발생하는 문제
- 각자의 방법으로 해결이 필요
- 아래는 iterator 를 사용하여 발생한 block 에 대한 처리 내용
- flask 로 개발한 RESTful API 의 동작에서 결과를 장시간 내보내지 못하고 처리/대기 하는 iterator 가 있어, 요청 user 가 연결을 끊어도 서버에서는 CLOSE_WAIT 상태로 연결이 남아있는 이슈가 발생
- user 는 여러번 해당 요청을 하여 결국 서버입장에서는 해결하지 못한 동작을 CLOSE_WAIT 상태로 계속 유지 중이고, 자원이 그만큼 낭비 됨에 따라 서버가 점차 과부화가 됨
- 해결을 위해서 iterator 에 timeout 시간을 적용 했고, 해당 시간안에 처리되지 못하는 동작은 실패로 응답을 할 수 있도록 처리
- 아래는 python 의 iterator 에 timeout 을 적용하여 간단하게 테스트한 코드
import time from iterators import TimeoutIterator # 3초 마다 숫자를 리턴하는 iterator 함수 def my_iter(): for i in range(100): time.sleep(3) yield i # sentinel : timeout 이 발생 했을 때 리턴되는 값, default = object() a = TimeoutIterator(my_iter(), timeout=1, sentinel='TIMEOUT') for res in a: # default 값 사용시 리턴되는 값을 체크하는 방법 # if res == a.get_sentinel(): if res == 'TIMEOUT': # timeout 이 발생하면 여기서 체크되어 break 됨 print('time error') a.interrupt() # 여기서 interrupt 를 하지 않으면 코드가 멈춘 상태로 유지됨 -> python exit 을 하지 못함 break print(res) print('last')
Reference
- pypi iterators : https://pypi.org/project/iterators/
- tcp 정리문서 : https://benohead.com/blog/2013/07/21/tcp-about-fin_wait_2-time_wait-and-close_wait/
- stackoverflow : stackoverflow.com/questions/15912370/how-do-i-remove-a-close-wait-socket-connection
- user 로그? : https://web.archive.org/web/20170113135705/http://unix.derkeiler.com/Mailing-Lists/SunManagers/2006-01/msg00367.html
반응형'Programming Language > Python' 카테고리의 다른 글
[psycopg2] postgresql oid 에 대한 텍스트 가져오는 쿼리 (0) 2021.11.15 [Python] PLY (Python Lex-Yacc) 정리 - Yacc (0) 2021.04.28 [Python] PLY (Python Lex-Yacc) 정리 - Lex (0) 2021.04.28 문자열 암호화 / 복호화 with Python (0) 2021.02.01 RST (reStructuredText) & Sphinx 문법 정리 (0) 2019.12.09 - tcp 연결된 소켓의 상태가