티스토리 뷰

Photo by Paweł Czerwiński on Unsplash

 

TL;DR

 

- Go언어의 default http client timeout 없다. Request 보내서 response 올때까지 무한정 기다린다.

- 따라서 custom 하게 timeout 설정한 http client 생성해서 사용하자

 

모범 답안

 

playground: https://play.golang.org/p/CdazCatBjrS

- 여기서 실행은 되지 않는다. 코드만 참고하자

- 실행은 별도로 PC에서 테스트하거나 https://repl.it 사이트에서 테스트하자

 

1) c 라는 timeout 설정이 들어가있는 http.Client 생성한 다음, HTTP request 보내면

2) httptest.NewServer() 생성된 테스트 서버가 1분이나 지나서 보낼 응답을 기다리지 않고 time out 걸린다는 것이다.

 

모범답안 분석

 

http.Client 3개의 timeout 설정할 있는데 예제에서는 http.Client Timeout: 3 * time.Second 걸려서 timeout 걸렸다.

개의 timeout 설정을 하나씩 챙겨보자

 

1) http.Client Timeout - 코드: https://bit.ly/3qeyuik

 

- 클라이언트로 request 보내고 기다리는 시간을 말한다. 보통은 이것만 설정해줘도 충분하다

- 연결 시간, 리디렉션 시간, 그리고 매우 중요하게도 response body 읽는 시간을 모두 합친 시간이다.

- , response return 받더라도 타이머가 계속 돌아간다는 것이다

 

- Timeout 값을 설정하지 않았을 경우의 zero value timeout 없다는 것이다.

- Client 내부의 Transport에게 cancel 요청할 수도 있다. (그만해!)

 

2) net.Dialer Timeout - 코드: https://bit.ly/388EW4m

 

TCP 연결이 되고 위에서 HTTP request response 오가게 되는데, 연결을 위한, 마치 전화를 거는 것과 같은, Dialing 이후 연결이 되기까지 기다리는 Timeout 시간이다.

- 만약 여러 IP dialing 하면 각각의 dialing 대기시간의 합이 된다

- 여기서 Timeout 설정하는 것과 상관없이 OS에서 TCP dialing Timeout 두기도 하는데 보통 3 정도이다.

 

3) http.Transport TLSHandshakeTimeout - 코드: https://bit.ly/3kIvJVm

 

참고링크: https://www.leafcats.com/202

 

HTTPS 보안통신을 한다는 것은 결국 SSL/TLS 연결 위에서 HTTP 통신을 한다는 것으로 보면 된다. 만약 FTP SSL/TLS 위에서 동작한다면 SFTP 된다. 암호화된 연결을 하려면 처음에 handshake 과정이 필요한데 Timeout 시간을 설정할 있다.

 

1) 2) 3) 종합해보면 2) 안에 3) 포함이 되고, 1) 안에 2) 포함이 된다

 

4) net.Dialer KeepAlive - 코드: https://bit.ly/2OkUJG6

 

덤으로 KeepAlive 까지 알아보자. 참고링크: https://hamait.tistory.com/341

 

- 주된 목적은 어느 한쪽이 끊겼는데 연결을 유지하는 것을 방지하는 것이다.

- TCP 네트워크 연결이 유지되도록 해주는 keep-alive probe 간의 인터벌 시간이다. default 15초마다

- 만약 네트워크 프로토콜이나 OS 이걸 지원하지 않는다면 무시된다.

- 위에 언급한데로 default 15초이며, 음수값을 넣으면 disable 된다.

 

 

문제있는 녀석

 

playground: https://play.golang.org/p/qmrfyRCl6Qp

 

custom하게 timeout 설정된 http.Client 생성하는 대신에 default http client 사용하는 http.Get() 함수를 이용했다.

default http client Timeout 필드가 설정되어 있지 않으며 zero value 일때에 무한히 기다리게 된다.

예제에서는 1 뒤에야 response 받게 되지만 실제 production에서 user 한없이 기다릴 수는 없는 것이다.

 

즉, 서비스에는 문제가 발생하는데, 에러도, 로그상의 기록도, CPU나 메모리상의 문제도 없는 상태에서 멘붕이 오게 되는 것이다.

 

- request 보내는 서버가 일시적으로 죽었거나, 이상 서비스를 하지 않는 경우를 생각해보면 된다.

- user 경우는 보통 response 받아서 원하는 작업을 해야 하는데 이유도 모른채 무한정 기다리게 되는 것이다.

 

 

다음 포스팅에는 context 패키지를 활용하는 방법을 정리해보겠다

 

참고 링크:  https://medium.com/@nate510/don-t-use-go-s-default-http-client-4804cb19f779

반응형
반응형
잡학툰 뱃지
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
글 보관함