- 부하 테스트를 진행하면서 겪었던 이슈들에 대한 내용 정리
TIME WAIT 관련
- RPC call 연결 중 서버에서 TIME WAIT 관련 프로세스가 많이 찍힌 것을 확인, 서버에선 아래 예시 명령어론 2초마다 Established 또는 time wait 프로세스 카운트를 확인할 수 있음
watch -n 2 "netstat -an | egrep 'ESTABLISHED|TIME_WAIT' | wc -l"
- time wait는 클라이언트가 서버에게 close 요청을 하는데 서버에서 응답 패킷을 받지 못하고 대기하는 상태를 말한다
- 그런데 문제는 이 대기상태의 시간이 짧지 않다는 것.. Linux 서버 기준으론 1분...
- 여러 원인이 있겠지만 요청에 대한 커넥션을 매번 생성하고 닫고하면 부하가 쏟아질때 그만큼의 대기 프로세스가 생길 수 있음, 현재 예시로 들면 golang에선 아래와 같이 코드를 넣어줄 수 있음
// 그냥 httpclient를 바로 셋해줄 수도 있지만 아래와 같이 transport 옵션을 사용하여 커넥션 풀 설정을 넣어줄 수 있음
proxy := httputil.NewSingleHostReverseProxy(u)
proxy.Transport = &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: time.Duration(Context.KENHttpDialTimeoutSec) * time.Second,
KeepAlive: time.Duration(Context.KENHttpDialKeepAliveSec) * time.Second,
DualStack: true,
}).DialContext,
ForceAttemptHTTP2: true,
// 커넥션 풀 갯수 세팅
MaxIdleConns: Context.KENHttpMaxIdleConns,
// 커넥션 풀 유지 갯수, 이 수가 적으면 MaxIdleConns를 뺀만큼의 커넥션을 계속 생성하게 됨
MaxIdleConnsPerHost: Context.KENHttpMaxIdleConnsPerHost,
IdleConnTimeout: time.Duration(Context.KENHttpIdleConnTimeoutSec) * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
}
- 그런데 코드를 잘못 작성하다 보면 httpclient 같은 경우에 매번 생성을 해줄수도 있는데, 이는 처음 서버 실행시 딱 한번만 생성하고 재사용되도록 하는 것이 좋다
- 그리고 Response를 다 읽도록 스트림 처리를 해야 커넥션 반납이 된다는데... 이건 테스트가 안되어서인지 잘 모르겠다...
EntityUtils.consume(HttpEntity)
- 또 해당 옵션들로도 수정이 안되면 커널 자체에서 수정을 해야 한다는데.. 커널에서 reuse 옵션을 켜야 커넥션 이 반환된다고 함, 기본 mac에선 옵션이 켜져있는데 쿠버네티스에선 꺼져있다고 함
# 커널에서 reuse 옵션을 키는 명령어
sysctl -w net.ipv4.tcp_tw_reuse="1"
too many open file 에러 관련
Temporary error when accepting new connections: accept tcp4 0.0.0.0:8551: accept4: too many open files
- 부하 테스트를 진행하다 보면 too many file 관련 에러를 볼 수 있는데 이는 서버의 open file 설정을 확인해야 한다
# 하나는 소프트, 하나는 하드 옵션
ulimit -a
ulimit -aH
- open files 수가 있고, max user process가 있는데 둘의 차이가 조금 있다
- max user processes : 서버에서 최대로 생성할 수 있는 쓰레드 (프로세스) 갯수
- open files : 쓰레드 내 소켓에 대한 최대 갯수
- 소프트, 하드 옵션에 따라 값이 다를수도 있는데 이는 왜 그런지, 어떻게 변경해야 하는지는 따로 정리하겠음
- 아무튼 open file을 수정할려면 아래 경로에서 수정해주면 됨
- 계정을 적어주면 그 계정 내 수행된 프로세스에서만 설정이 먹힐꺼고 전체로 할려면 와일드카드로 하면 될 듯?