커넥션 만드는 기준
src ip, src port, dest ip, dest port
성능
구조적 성능저하
커넥션 맺기 위하여 핸드세이크시 패킷을 주고받는 과정
slow start
네트워크가 감당할 수 있는 수준보다 더 많은 데이터를 보내는걸 피하는 노력
1,2,4 또는 10 window size로 시작해서 ack를 받을 떄 마다 1MSS(maximum segment size)씩 window size를 증가시킨다. RTT마다 window size가 2배되는 셈
마냥 무한으로 제한되지 않고 아래의 조건에 해당할경우 제한된다.
- packet loss가 감지 될때
- 받는 쪽에서 제한
- slow start threshold 도달하기 전까지
확인 응답 지연
프로토콜 부하를 줄이기 위해 N개의 ack 응답을 하나의 응답으로 합친다. 하지만 앱 성능을 낮출 수 있다. RFC 1122에 따르면, 최대 500ms까지 ack response를 지연시킬 수 있다고 한다. 하지만, 최대 사이즈의 세크먼트를 스트림으로 보낼 시 ack 응답은 매 segment 마다 보내야한다. ack 지연은 TCP receive window를 최신화 할 수 있게 하고 ack와 함께 빠르게 응답을 보낼 수 있게 해준다. telnet 프로토콜 같은 경우, 지연 ack는 3배정도 서버에서 보내는 응답 수를 줄여준다.
https://en.wikipedia.org/wiki/TCP_delayed_acknowledgment
네이글 알고리즘
데이터가 1바이트라도 tcp 스택으로 전송 가능하다. TCP 세그먼트는 40바이트 정도 되기에 1바이트 데이터를 위해 커넥션을 생성하고 데이터를 보내기에는 비효율적이다. 네이글 알고리즘은 패킷을 전송하기 전에 많은 양의 데이터를 한개의 덩어리로 합친다. 크기가 작은 http 메시지는 패킷을 채우지 못하기 때문에, 앞으로 생길지 생기지 않을지 모르는 추가적인 데이터를 기다리며 지연될 것이다.
확인 응답 지연과 함께 쓰일경우 형편없이 동작한다. 네이글 알고리즘은 확인 지연 응답이 도착할 때까지 데이터를 전송을 멈추고 있는 반면, 확인응답 지연 알고리즘은 확인응답을 최대 500ms 지연시킨다.
http server는 tcp_nodelay 파라미터를 이용해 네이글 알고리즘을 비활성화 시킬 수 도 있다.
pseudocode
if there is new data to send then
if the window size ≥ MSS and available data is ≥ MSS then
send complete MSS segment now
else
if there is unconfirmed data still in the pipe then
enqueue data in the buffer until an acknowledge is received
else
send data immediately
end if
end if
end if
time_wait의 누적과 포트 고갈
커넥션을 종단에서 끊으면 종단에서는 커넥션의 ip주소와 포트번호를 메모리에 기록해 놓는다. 이 정보로 같은 주소와 포트 번호를 사용하는 새로운 tcp 커넥션이 일정 시간 동안에는 생성되지 않게 한다.
순차적인 트랜잭션 처리 지연
해결 방안
- 병렬 커넥션
- 여러개 동시에
- 대역이 좁을 때 효과를 보지 못한다.
- 메모리 소모가 많아 자체 성능 저하 초래
- http 서버마다 제한된 병령 커넥션 사용
- 지속 커넥션
- 커넥션 재활용
- slow start 최소화
- 잘못 관리되어 있을 경우, 커넥션이 쌓여 불필요한 소모를 발생
- 병렬과 같이 사용하면 효과가 높다.
- 파이프라인 커넥션
- 공유 커넥션을 통한 병렬요청
- 여러개의 요청은 응답이 도착하기 전에 큐에 쌓이고, 요청이 서버로 전달되면 그다음 요청이 출발하는 로직
- 지속커넥션이 전제조건이다.
지속 커넥션 유지 방법 2가지
1) http1.0/+ keep-alive (http1.1에서는 사용하지 않는다)
요청에 connection: keep-alive 헤더 포함하고 응답에도 connection: keep-alive가 있어야 한다.
응답에 timeout 파라미터를 추가할 수 있다. 이건 커넥션이 얼마나 유지될것인지를 의미한다. 하지만 이대로 동작한다는 보장은 없다. max 파라미터 또한 응답에 추가될 수 있다. max는 커넥션이 몇 개의 트랜잭션을 처리 할지 나타낸다. 역시 이것도 명시한대로 동작한다는 보장은 없다.
2분동안 5개의 추가 트랜잭션을 처리 가능한 예
Connectrion: Keep-Alive
Keep-Alive: max=5, timeout=120
2) http1.1 사용
지속커넥션 기본으로 활성화되어 있다. 끊을려면 connection:close를 명시해야 한다. 해당 해더가 없으면 유지하는것으로 간주한다. 클라이언트와 서버는 언제든지 끊을 수 있다. 영원히 유지하지 않는다. 마치 타짜의 파트너처럼...
커넥션은 언제끊을까?
클라이언트, 프록시, 서버 어디서든 마음대로 끊을 수 있다.
에러가 있는 상황에서는 예상치 못한 이유로 어디서든 끊길 수 있다.
chatgpt에 물어보니 명쾌한 답변을 줬다. 납득할 만한 내용들만 간추려 보겠다.
timeout
어느 곳이든 idle timeout을 구현했을 거다. 일정 시간이 지날동안 데이터가 오고가지 않는다면 자동으로 커넥션은 끊길거다. 아주 기본 중에 기본이다.
error
위에 언급한 에러
system resource constraints
어디든 내부자원 고갈로 인하여 커넥션을 끊을 수 있다.
'IT' 카테고리의 다른 글
[docker] 이미지 받고 실행하기 / 빌드 후 실행하기 (1) | 2024.06.03 |
---|---|
[linux] lsof command (0) | 2024.06.03 |
stream 이해 (0) | 2024.05.03 |
package-lock.json (0) | 2024.05.03 |
npx 개념 (0) | 2024.05.03 |