1. 문제의 발단
- OSI 7 계층의 네트워크들을 더욱더 자세하게 알아본다.
- 기본적인 메커니즘은 이해를 한 상태에서 보아야 이해가 된다.
- 전반적인 HTTP/네트워크의 디테일한 부분에 대해 다루고 있다.
2. 인터넷 프로토콜
- 클라이언트가 요청을 보내고, 서버에서 응답을 줄 때, 어떻게 다양한 컴퓨터들을 거쳐서 정보를 주고받을 수 있을까?
- 먼저, IP주소를 통해 위치를 파악하고, 패킷(Packet)으로 전달하게 된다.
- 패킷(Packet)?
- 통신의 단위이다.
- IP주소에 따른 출발지와 도착지 등의 정보가 들어있다.
- 말하자면, 택배를 보낼 때 송장이라고 생각하면 쉽다.
- 그래서 이곳 저곳의 물류센터들을 돌아서 결국 택배를 구매한 사람에게 정확하게 갈 수 있게 된다.
- 물론, 서버도 패킷을 이용해 응답을 보내준다.
- 하지만 이런식으로 IP 프로토콜을 전계 할 때 한계점이 있다.
- 비연결성 : 패킷을 받을 대상에 문제가 있더라도 일단 전송한다. 즉, 패킷을 보내기 전에 서버의 상태를 알 수 없다.
- 비신뢰성 : 패킷이 중간에 손실될 수 있으며, 전달 순서가 섞일 수 있다. 즉, 패킷을 한번 보내고 나면 이후 상태도 알 수 없다.
3. TCP와 UDP
- 위의 IP프로토콜의 한계점을 보완하기 위해 중간에 단계를 하나 더 집어넣었다.
- IP 패킷을 생성하기 전에 '소켓(Socket)'을 이용해 정보들을 추가해서 보내준다.
- TCP
- TCP 세그먼트 안에는 출발지와 도착지의 PORT, 전송의 순서 등이 들어가 있다.
- 3 way handshake를 사용한다.
- 3 way handshake?
- 3번에 걸쳐서 서버와 클라이언트가 연결이 정상정으로 될 수 있는지를 확인하는 것이다.
- 먼저, 클라이언트가 서버에 접속을 요청하는 SYN(synchronize) 패킷을 보낸다.
- 서버는 요청을 수락하는 ACK(Acknowledgment)와 SYN패킷을 보내준다.
- 클라이언트는 ACK로 다시 응답한다.
- 위의 과정에 문제가 없다면 연결되었다는 것이다.
- 위의 과정으로 서버의 상태를 확인할 수 있으므로, 연결성이 보장되고, 중간에 단계가 꼬이거나 문제가 생기면 그것을 토대로 다시 요청을 보낼 수 있게 되기 때문에 신뢰성도 보장될 수 있다.
- 3 way handshake?
- UDP
- UDP 세그먼트 안에는 IP 프로토콜의 PORT, 간단한 중복이나 오류를 검사하는 '체크섬 필드' 정보 정도만 들어있다.
- TCP보다 훨씬 단순하다.
- 덕분에 빠르다!
- 연결성과 전송 순서는 보장되지 않는다.
4. HTTP
- 우리가 사용하고 있는 그 HTTP 프로토콜을 뜻한다.
- 클라이언트와 서버의 구조로 나누어져 있다.
- 무상태 프로토콜이다.
- 무상태 프로토콜?
- 서버가 클라이언트의 상태를 가지고 있지 않다.
- 즉, 클라이언트는 서버의 상태가 어떨지 모르므로 요청을 보낼 때 모든 사전 정보들을 계속해서 보내주어야 한다.
- 대신에 서버는 무한대로 증설이 가능하다. 클라이언트가 모든 정보를 다 주고 있기 때문에 어떤 서버가 받더라도 상관없이 응답을 줄 수 있기 때문이다.
- 한계: 로그인과 같이 상태를 가지고 있어야 하는 서비스의 경우 만들 수 없다.
- 상태 유지 프로토콜?
- 무상태 프로토콜과 반대로 서버는 클라이언트가 이전에 보내준 상태를 알고 있다.
- 서버가 달라지면 달라진 서버는 그전의 클라이언트가 보내준 상태를 모르기 때문에 서버 증설이 불가능하다.
- 아니면 서버가 달라질 때 서버들끼리 상태 정보를 주고받아야 한다.
- 무상태 프로토콜?
- 서버와 연결을 유지하는 모델과 서버와 연결을 유지하지 않는 모델로 나눠진다.
- 서버와 연결을 유지하는 모델(Connection Oriented)
- TCP/IP는 연결을 유지한다. 비록, 서버와 클라이언트가 정보를 보내지 않더라도 연결은 계속 유지된다.
- 서버의 자원이 계속 소모된다는 단점이 있다.
- 서버와 연결을 유지하지 않는 모델(Connectionless)
- 요청을 주고받고 나면 TCP/IP 연결을 끊어버린다.
- 서버의 자원을 아낄 수 있다.
- HTTP 1.0 이전에는 연결을 유지하지 않는 모델을 이용했다.
- 1초 이하의 빠른 반응을 보여준다.
- 클라이언트의 요청으로 서버에서 처리하는 요청의 개수는 그리 많지 않다는 것을 이용한 방법이 된다.
- 한계
- TCP/IP 연결을 계속 새롭게 맺어줘야 해서 3 way handshacke를 하는 시간이 계속 늘어난다.
- 웹 브라우저에 한번 연결이 될 때 HTML이나 CSS 같은 자료를 한번 받아와서 계속 사용하면 되는데 연결을 끊어버리니 다시 다른 요청을 보낼 때 다시 받아와야 하므로 몹시 비 효율적이다.
- 서버와 연결을 유지하는 모델(Connection Oriented)
5. HTTP의 헤더
- HTTP의 응답과 요청에는 '헤더'가 있다. 내용들은 body에 들어가지만 헤더에 정보들을 추가하여 자세한 설정을 해준다.
- 헤더의 종류
- 표현 헤더(요청과 응답 둘 다 사용하는 헤더)
- Content-Type: 형식
- Content-Encoding: 압축방식
- Content-Language: 언어
- Content-Length: 길이
- 요청에 사용되는 헤더
- Referer: 이전의 웹 페이지 주소
- User-Agent: 클라이언트의 프로그램에 대한 정보(PC인지, 모바일인지 등등)
- Host: 도메인
- Origin: POST 요청 시, 요청이 시작된 주소
- Cookie: 서버로부터 받은 쿠키
- Authorization: 인증 토큰을 서버로 보낼 때, text 형태의 토큰의 정보
- 콘텐츠 협상에 사용되는 헤더 (당연히 요청 시에만 사용 가능)
- Accept: 클라이언트가 선호하는 미디어 타입
- Accept-Charset: 클라이언트가 선호하는 문자 인코딩
- Accept-Encoding: 클라이언트가 선호하는 압축 인코딩
- Accept-Language: 클라이언트가 선호하는 언어
- 협상 순위를 지정할 수 있다.
- EX) Accept-Language: ko-KR;q=1, ko;q=0.9, en-US;q=0.8
- 이처럼 선호하는 순서를 정해서 받아 올 수 없는 경우 대체할 것을 정해줄 수 있다. q=1은 생략이 가능하다.
- 응답에 사용되는 헤더
- Server: 요청을 처리하는 Origin 서버의 소프트웨어 정보
- Data: 날짜
- Location: 리디렉션에 사용될 주소
- Allow: 허용 가능한 HTTP 메서드(GET, HEAD 같은 거)
- Set-Cookie: 브라우저가 서버로 보낼 쿠키
- Rety-After: 다음 요청을 보낼 수 있을 때까지 기다려야 할 대기시간.
- 표현 헤더(요청과 응답 둘 다 사용하는 헤더)
6. 캐시
- 서버에서 데이터를 받아 가져올 때 자주 사용하는 데이터의 전달 비용을 줄이기 위해 사용하는 작고 중요한 저장공간.
- 브라우저에 캐시가 저장될 때 헤더에 'cache-control'로 캐시의 유효시간을 정할 수 있다.
- 유효시간이 지난 캐시는 버려지고, 다시 렌더링 하여 가져온다.
- 유효기간이 지난 캐시를 다시 받아 왔는데 이전의 캐시와 똑같은 정보일 경우
- Last-Modified를 통한 구분
- 헤더의 Last-Modified에는 받아온 캐시의 수정된 날짜가 적혀있다.
- 유효기간이 지난 캐시의 Last-Modified 가 다시 받아올 캐시의 유효기간과 변함이 없다면 작은 용량의 헤더 정보만을 받아와 확인하고 용량이 상대적으로 큰 body는 받아오지 않고, 이전에 있던 캐시를 그대로 사용하면 된다.
- 이때 HTTP 304 Not Modified로 상태 코드를 준다.
- 단점
- 1초 미만의 단위 사용 불가능
- 오직 날짜로만 구분 가능
- ETag
- 캐시 데이터에 태그를 달아서, 태그가 다르면 받아오고 똑같으면 이전의 캐시를 사용한다.
- 캐시를 주는 과정을 모두 서버에서 관리하게 된다. 클라이언트는 그저 태그를 확인하기만 한다.
- 서버에서 사용하는 캐시 지시어
- Cache-Control: max-age: 캐시의 유효기간
- Cache-Control: no-cache: 캐싱한 데이터를 Origin 서버에서 검증한 후 사용
- Cache-Control: no-store: 캐시를 메모리에서만 사용한 후 바로 삭제
- Last-Modified를 통한 구분
- 프락시 캐시(Proxy Cache)
- 프락시 서버? : 클라이언트가 서버에 접속할 때, 중간에 프록시 서버를 거쳐서 우회를 돕는 서버
- 다양한 클라이언트가 프락시 서버를 이용해 데이터를 요청, 응답 받으면 캐시도 프록시 서버에 저장된다. 그렇게 되면 다른 클라이언트들은 그 저장된 캐시를 이용해 더 좋은 경험을 얻게 되는 것이다.
- 이것이 프록시 캐시가 된다.
- 프록시 캐시의 지시어
- Cache-Control: public: public 응답이 public으로 저장
- Cache-Control: private: public에 저장하지 않고, private 캐시에 저장되어 본인만 사용
- Cache-Control: s-maxage: 프록시 캐시 버전의 max-age
- Age: 초(HTTP 헤더): Origin서버의 응답 이후, 프록시 캐시에서 대기한 시간
- 캐시 무효화
- 웹 브라우저는 캐싱을 마음대로 할 수 있다. 하지만 이것을 막을 수 도 있다.
- 캐시 지시어
- Cache-Control: no-cache: 캐싱 한 데이터를 Origin 서버에서 검증한 후 사용
- 원 서버에 접속할 수 없게 되면 이전의 데이터를 다시 보여주게 됨.
- Cache-Control: no-store: 캐시를 메모리에서만 사용한 후 바로 삭제
- Cache-Control: must-revalidate: 캐시의 유효기간이 끝나면 Origin 서버에서 검증한 후 캐시를 받아옴
- 원 서버에 접속할 수 없게 되면 무조건 504 Gateway Timeout 에러를 보여주게 됨.
- 그러므로, 정말 중요한 정보(은행 업무 등)에 관련한 정보를 보호할 때 사용하면 됨.
- Pragma: no-cache: HTTP 1.0에서 사용했던 지시어. 말 그대로 캐싱을 하지 않게 함
- Cache-Control: no-cache: 캐싱 한 데이터를 Origin 서버에서 검증한 후 사용
- 위의 모든 지시어를 다 사용하면 캐싱을 막을 수 있다. 보안에 민감한 정보가 있을 때 사용한다.
'Coding > Today I Learned' 카테고리의 다른 글
2021.09.16(Thu.) <AWS 배포의 큰 그림> (0) | 2021.09.16 |
---|---|
2021.09.14(Tue.) <Git을 이용한 버전관리> (0) | 2021.09.14 |
2021.09.10(Fri.) <취미로라도 알아두면 좋은 컴퓨터 하드웨어> (0) | 2021.09.10 |
2021.09.09(Thu.) <취미로라도 알아두면 좋은 컴퓨터의 기초 이론> (0) | 2021.09.09 |
2021.09.07(Mon.) <HTTPS와 친해지기> (0) | 2021.09.07 |