상권's

TIL 48 (IP Packet, TCP/UDP, Cache, 프록시, CDN, 개인프로젝트1) (2021.11.29) 본문

~2022 작성 글/TIL

TIL 48 (IP Packet, TCP/UDP, Cache, 프록시, CDN, 개인프로젝트1) (2021.11.29)

라마치 2021. 11. 29. 16:44
-오늘의 코플릿 2021.11.29-
문제
좌표평면 상의 다양한 점들을 입력받아 가장 가까운 두 점 사이의 거리를 리턴해야 합니다.
입력
인자 1: points
배열을 요소로 갖는 배열points.length는 40,000 이하points[i]는 number 타입을 요소로 갖는 배열points[i].length는 2points[i]의 요소는 차례대로 좌표평면 위의 y좌표, x좌표points[i][j]는 0 이상 10,000 이하의 정수
출력
number 타입을 리턴해야 합니다.
주의사항
points는 y좌표나 x좌표 등으로 정렬되어 있지 않습니다.두 점 사이의 거리를 계산하는 함수 calculateDistance가 주어집니다. 두 점 간 거리는 반드시 이 함수를 이용해서 계산해야 합니다.함수 calculateDistance는 소수점 계산을 피하기 위해 두 점 사이의 거리에 100을 곱한 후 반올림하여 정수 부분만 취합니다. 최단 거리도 이 기준으로 판단합니다.
Advanced
가장 가까운 두 점 사이의 거리를 구하는 효율적인 알고리즘(O(N * logN))이 존재합니다.
힌트
효율적인 알고리즘은 병합 정렬(merge sort)과 비슷하게 분할 정복(divide and conquer) 알고리즘을 사용해야 합니다. 어떻게 나눠야 할 지, 나누었을 때 놓치는 부분은 없는 지 유의하면서 고민해 보시기 바랍니다.
  // 간단하게 생각한다면 for문을 이용해서 하나씩 돌면서 거기들을 모아서 최소값을 리턴하면 된다.
  // 분할정복을 이용해야 한다.
  // 그렇다면 어떤 것을 기준으로 나눠야할까?

오늘 문제도 코드 구현에 많은 어려움이 있어서 레프런스를 학습한 이후에 추가적으로 올리도록 하겠습니다.


IP 와 IP Packet

클라이언트와 서버 간 통신을 할 때, IP(인터넷 프로토콜) 주소를 컴퓨터에 부여해서 이를 이용해 통신합니다.

 

위키백과에서는 패킷은 '정보 기술에서 패킷 방식의 컴퓨터 네트워크가 전달하는 데이터의 형식화된 블록이다.'라고 정의하고 있습니다.

 

IP Packet은 이러한 패킷에 출발지와 도착지의 IP 등의 정보를 담은 것으로, 즉 전송 데이터와 출발지 IP, 도착지 IP 등의 정보로 구성되어 있습니다.

 

클라이언트와 서버는 IP Packet을 이용해서 요청과 응답을 주고 받을 수 있습니다. 이러한 IP 프로토콜에는 비연결성과 비신뢰성이라는 한계가 있습니다.

 

먼저 비연결성은 패킷을 받을 대상이 없거나 서비스 불능 상태여도 패킷이 전송된다는 점입니다.

 

비신뢰성은 중간에 있는 서버가 데이터를 전달하던 중에 장애가 생겨서 패킷이 소실되더라도 클라이언트는 파악할 방법이 존재하지 않습니다.

 

추가적으로, 전달 데이터의 용량이 클 경우 패킷 단위로 데이터를 나눠서 전송하게 되는데, 서버에서 받을 때 클라이언트가 의도치 않은 순서로 도착을 할 수 있습니다.


TCP/IP Packet

 

위에서 학습했던 IP 프로토콜은 OSI 7 계층에서 네트워크 계층에 위치를 하고 있으면, TCP 프로토콜은 전송 계층으로, 한 단계 높은 계층에 위치하고 있어 IP 프로토콜의 한계를 보완할 수 있습니다.

 

TCP/IP Packet 생성 순서

채팅 프로그램에서 메시지를 보낼 때를 예로 들어서 보면,

먼저, HTTP 메시지가 생성되면 Socket 라이브러리를 통해 전달 -> 

* 네트워크 소켓(Socket)이란,

프로그램이 네트워크에서 데이터를 송수신할 수 있도록, '네트워크 환경에 연결할 수 있게 만들어진 연결부'

TCP 세그먼트 생성(TCP 정보 생성, 메시지 데이터 포함) ->

IP Packet 생성 -> 이더넷 프레임 워크에 포함되어 서버로 전송

TCP 세그먼트에는 IP Packet의 IP 정보를 보완할 수 있는 출발지, 목적지 PORT, 전송 제어, 검증 정보 등의 정보가 포함되어 있습니다. 

 

TCP(Transmission Control Protocol) 특징

-연결 지향 - TCP 3 way handshake 

클라이언트는 서버에 접속을 요청하는 SYN 패킷을 보냄 ->

서버는 SYN요청을 받고 클라이언트에게 요청을 수락한다는 ACK 와 SYN가 설정된 패킷을 발송함 ->

클라이언트가 서버에게 ACK을 보내면 이 이후로부터 연결이 성립되며 데이터를 전송 가능

만약 서버가 꺼져있다면 클라이언트가 SYN을 보내고 서버에서 응답이 없기 떄문에 데이터를 보내지 않음

현재에는 최적화가 이루어져 3번 ACK을 보낼때 데이터를 함께 보내기도 합니다.

* SYN은 Syncronize, ACK는 Acknowledgment의 약자

 

-데이터 전달 보증

데이터 전송이 성공적으로 이루어진다면 응답을 돌려준다.

-순서 보장

패킷이 순서대로 도착하지 않는다면, TCP 세그먼트에 있는 정보를 토대로 다시 패킷 전송을 요청할 수 있다.(비신뢰성 보완)

-신뢰할 수 있는 프로토콜

 


 

UDP(User Datagram Protocol) 특징

-비 연결지향

-데이터 전달 및 순서가 보장되지 않지만, 단순하고 빠름

-신뢰성보다는 연속성이 중요한 서비스에서 자주 사용됨.


HTTP 특징

- 클라이언트 서버 구조클라이언트가 서버에 요청을 보내면 서버는 그에 대한 응답을 보내는 구조

 

- 무상태 프로토콜(Stateelss), 비연결성(Connectionless)Stateless 서버가 클라이언트의 상태를 보존하지 않음이를 통해서 서버 확정성이 높아지나, 로그인이 필요한 서비스의 경우, 상태 유지를 위해 브라우저 쿠키, 서버 세션, 토큰 등을 이용해서 상태를 유지 해야 합니다.

Connectionless 실제 요청을 주고 받을 때만 연결을 유지하고 응답을 주고 나면 TCP/IP 연결을 끊음

최소한의 자원으로 서버가 유지 되지만, 트래픽이 많고, 큰 규모의 서비스 운영시 한계를 보입니다.추가적으로 웹 브라우저로 사이트를 요청하면 HTML, CSS, 자바스크립트 등 많은 자원이 다운로드 되는 데, 이때마다 연결하고 끊고 하는 것은 비효율적이기 때문에 HTTP 지속 연결을 통해서 연결이 이뤄진 뒤 자원들을 요청하고 모든 자원에 대한 응답이 돌아오면 연결을 종료할 수 있습니다

 

- HTTP 메세지

 

- 단순함, 확장 가능

 

HTTP 주요 헤더

 

요청(Request)에서 사용되는 헤더

From: 유저 에이전트의 이메일 정보

일반적으로 잘 사용하지 않음

  • 검색 엔진에서 주로 사용
  • 요청에서 사용

Referer: 이전 웹 페이지 주소

  • 현재 요청된 페이지의 이전 웹 페이지 주소
  • A → B로 이동하는 경우 B를 요청할 때 Referer: A 를 포함해서 요청
  • Referer 를 사용하면 유입경로 수집 가능
  • 요청에서 사용
  • referer는 단어 referrer의 오탈자이지만 스펙으로 굳어짐

User-Agent: 유저 에이전트 애플리케이션 정보

  • 클라이언트의 애플리케이션 정보(웹 브라우저 정보, 등등)
  • 통계 정보
  • 어떤 종류의 브라우저에서 장애가 발생하는지 파악 가능
  • 요청에서 사용
    • user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/ 537.36 (KHTML, like Gecko) Chrome/86.0.4240.183 Safari/537.36

Host: 요청한 호스트 정보(도메인)

  • 요청에서 사용
  • 필수 헤더
  • 하나의 서버가 여러 도메인을 처리해야 할 때 호스트 정보를 명시하기 위해 사용
  • 하나의 IP 주소에 여러 도메인이 적용되어 있을 때 호스트 정보를 명시하기 위해 사용

Origin: 서버로 POST 요청을 보낼 때, 요청을 시작한 주소를 나타냄

  • 여기서 요청을 보낸 주소와 받는 주소가 다르면 CORS 에러가 발생한다.
  • 응답 헤더의 Access-Control-Allow-Origin와 관련

Authorization: 인증 토큰(e.g. JWT)을 서버로 보낼 때 사용하는 헤더

  • “토큰의 종류(e.g. Basic) + 실제 토큰 문자”를 전송
    • Authorization: Basic YWxhZGRpbjpvcGVuc2VzYW1l

응답(Response)에서 사용되는 헤더

Server: 요청을 처리하는 ORIGIN 서버의 소프트웨어 정보

  • 응답에서 사용
    • Server: Apache/2.2.22 (Debian)
    • Server: nginx

Date: 메시지가 발생한 날짜와 시간

  • 응답에서 사용
    • Date: Tue, 15 Nov 1994 08:12:31 GMT

Location: 페이지 리디렉션

  • 웹 브라우저는 3xx 응답의 결과에 Location 헤더가 있으면, Location 위치로 리다이렉트(자동 이동)
  • 201(Created): Location 값은 요청에 의해 생성된 리소스 URI
  • 3xx(Redirection): Location 값은 요청을 자동으로 리디렉션하기 위한 대상 리소스를 가리킴

Allow: 허용 가능한 HTTP 메서드

  • 405(Method Not Allowed)에서 응답에 포함
    • Allow: GET, HEAD, PUT

Retry-After: 유저 에이전트가 다음 요청을 하기까지 기다려야 하는 시간

  • 503(Service Unavailable): 서비스가 언제까지 불능인지 알려줄 수 있음
    • Retry-After: Fri, 31 Dec 2020 23:59:59 GMT(날짜 표기)
    • Retry-After: 120(초 단위 표기)

캐시 전용 헤더

캐시(cache)는 컴퓨터 과학에서 데이터나 값을 미리 복사해 놓는 임시 장소를 가리킵니다. 캐시는 캐시의 접근 시간에 비해 원래 데이터를 접근하는 시간이 오래 걸리는 경우나 값을 다시 계산하는 시간을 절약하고 싶은 경우에 사용합니다.

 

캐시 검증 헤더와 조건부 요청 헤더

출처

 

Last-Modified

Last-Modified 응답은 HTTP 헤더에 서버가 알고있는 가장 마지막 수정된 날짜와 시각을 담고 있습니다. 이는 저장된 리소스가 이전과 같은지 유효성 검사자로 사용됩니다. ETag 헤더보다는 덜 정확하지만, 이는 대비책으로 사용됩니다. 조건 요청은 If-Modified-Since 또는 If-Unmodified-Since (en-US) 헤더로 이와 같은 필드를 사용하여 만들어집니다.

예제

Last-Modified: Wed, 21 Oct 2015 07:28:00 GMT

 

If-Modified-Since

If-Modified-Since HTTP 요청 헤더는 조건부 요청으로 서버는 지정된 날짜 이후 수정 된 경우에 200  과 함께 요청된 리소스를 돌려 줍니다. 만약 수정되지 않는 리소스에 대한 요청시, 리소스 없이 304  응답을 하게 됩니다. 이전 요청의 Last-Modified 응답 헤더는 마지막으로 수정 한 날짜를 포함합니다.If-Modified-Since If-Unmodified-Since (en-US) 와는 다르게 GET 또는 HEAD 에서만 쓸수 있습니다.

서버가 If-None-Match를 지원하지 않는 한 If-None-Match (en-US) 를 함께 사용시 무시 됩니다.

가장 일반적인 사용예로, ETag 가 없는 캐시된 엔티티로 업데이트 합니다.

예제

If-Modified-Since: Wed, 21 Oct 2015 07:28:00 GMT

Last-Modified & If-Modified-Since 정리

캐시 유효 시간이 초과해서 서버의 데이터가 갱신되지 않으면 304 Not Modified + 헤더 메타데이터만 응답(용량이 적어진다.)

클라이언트는 캐시에 저장되어 있는 데이터 재활용


ETag

ETag HTTP 응답 헤더는 특정 버전의 리소스를 식별하는 식별자입니다. 웹 서버가 내용을 확인하고 변하지 않았으면, 웹 서버로 full 요청을 보내지 않기 때문에, 캐쉬가 더 효율적이게 되고, 대역폭도 아낄 수 있습니다. 허나, 만약 내용이 변경되었다면, "mid-air collisions" 이라는 리소스 간의 동시 다발적 수정 및 덮어쓰기 현상을 막는데 유용하게 사용됩니다.

만약 특정 URL 의 리소스가 변경된다면, 새로운 ETag 가 생성됩니다. ETag 는 지문과 같은 역할을 하면서 다른 서버들이 추적하는 용도에 이용되기도 합니다. ETag 를 비교하여 리소스가 서로 같은지의 여부를 빠르게 판단할 수 있지만, 서버에서 무기한으로 지속될 수 있도록 설정할 수도 있습니다.

 

예시

ETag: "33a64df551425fcc55e4d42a148795d9f25f89d4"
ETag: W/"0815"

If-None-Match 출처

서버보고 ETag가 달라졌는 지 검사해서 ETag가 다를 경우에만 컨텐츠를 새로 내려주라는 뜻입니다.

If-None-Match: W/"3bf2-wdj3VvN8/CvXVgafkI30/TyczHk"

만약 ETag가 같다면 서버는 304 Not Modified를 응답해서 캐시를 그대로 사용하게 합니다.


Cache-Control 캐시 지시어(directives)

Cache-Control : max-age

캐시 유효 시간(초 단위)

 

Cache-Control : no-cache

데이터는 캐시해도 되지만, 항상 origin 서버에 검증하고 사용

캐시 서버 요청을 하면 프록시 캐시 서버에서 origin 서버에 요청을 함. 검증 후 304가 응답이 됨.

만약 origin 서버에 접근이 불가능하더라도 200 ok를 응답

 

Cache-Control : no-stroe

데이터에 민감한 정보가 있으므로 저장하면 안됨

 

Cache-Control : must-revalidate

캐시 만료 후 최초 조회 시 origin 서버에 검증해야함

origin 서버 접근 실패 시 반드시 오류가 발생함 - 504 (Gateway Timeout)

 

Pragma: no-cache

HTTP 1.0 하위 호환

 

Cache-Control : public

응답이 public 캐시에 저장되어도 됨

 

Cache-Control : private

응답이 해당 사용자만을 위한 것으로, private 캐시에 저장해야 함(기본값)

 

Cache-Control : s-maxage

프록시 캐시에만 적용되는 max-age

 

Age : 60 (HTTP 헤더)

origin 서버에서 응답 후 프록시 캐시 내에 머문 시간(초)

 

확실한 캐시 무효화 응답을 하기 원하면

Cache-Control : no-cache, no-store, must-revalidate

Pragma: no-cache

 


프록시란, 클라이언트와 서버 사이에 대리로 통신을 수행하는 것을 가리켜 ‘프록시(Proxy)’, 그 중계 기능을 하는 서버를 프록시 서버라고 합니다.

 

클라이언트, 혹은 반대로는 서버가 다른 네트워크에 간접적으로 접속 할 수 있기 때문에, 보안, 캐싱을 통한 성능, 트래픽 분산 등의 장점을 가집니다.


Content Delivery Network

콘텐츠를 좀더 빠르고 효율적으로 제공하기 위해 등장한 서비스

 

CDN의 특징

-원본을 복사해 저장할 여러 개의 캐시 서버로 구성

-콘텐츠를 요청받은 경우 데이터를 전달하기 가장 유리한 캐시 서버에서 관련 콘텐츠를 제공

-제공할 콘텐츠를 가지고 있으며 위치상으로 가장 가까운 캐시 서버가 우선순위를 가짐

해당 데이터 센터가 전달해야할 콘텐츠를 가지고 있지 않다면, 다른 데이터센터가 해당 콘텐츠를 가지고 있는지 확인

-> 콘텐츠가 없는 데이터센터를 제외한 나머지 중 지리적으로 가장 가까운 데이터 센터를 선택 -> 

모든 데이터센터가 콘텐츠를 가지고 있지 않다면 원본이 저장된 원본 서버에서 콘텐츠를 제공 & 콘텐츠를 요청한곳과 가장 가까운 데이터 센터에 저장

 

CDN이 다룰수 있는 콘텐츠의 종류

정적 콘텐츠

동영상, HTML 파일과 같이 변화가 거의 없는 콘텐츠와 더불어 뉴스 기사 등 개인화 되지 않은 대중적인 콘텐츠.

이런 콘텐츠들은 변화가 거의 없기때문에 CDN의 캐시 센터에 저장하는것이 적합

 

동적 콘텐츠

위치, IP 주소등 접근할때 마다 내용이 바뀌거나, 사용자 마다 다른 내용을 보여주는 콘텐츠

콘텐츠가 바뀔 때마다 캐시 서버에 바뀐 콘텐츠가 전파되어야 함 -> 공통적인 부분을 캐시 서버에 저장

 

CDN의 이점

DDoS공격에 대해 어느정도 대응이 가능

분산 서비스 거부 공격(Distributed Denial of Service attack, DDoS)는 서버의 수용량보다 훨씬 많은 요청을 보내 서버를 사용 불가능하게 만듬. DDoS 공격으로 인해 센터 중 하나가 사용 불가능하더라도 다른 센터에서 콘텐츠를 제공 받을 수 있음

로딩속도 감소로 인한 사용자 경험 향상

트랙픽 분산으로 인한 트래픽 관련 비용 절감

 

CDN이 서버를 분산하는 방식

Scattered방식

최대한 빠른 응답속도를 목표

세계 곳곳에 비교적 낮은 성능의 데이터 센터를 구성하고 연결

-> 데이터센터의 수가 많기 때문에 데이터 센터 유지 비용이 높음. 클라우드 제공자는 관리비용을 사용자에게 전가

-> 높은 사용 요금, 수요가 적은 지역에 데이터 센터를 세워야 할때 유리

 

Consolidated방식

데이터 센터들을 통합하여 운용하는 방식으로 고성능의 데이터 센터들을 운용

-> 데이터 센터의 수가 줄어듦으로 데이터 센터의 관리 및 유지 비용을 절감 -> 사용자 부담 감소

연결 수요가 많은 지역에 데이터 센터를 설립해야 한다면 적절한 방식

 

이 두가지의 방식 중 반드시 한가지 방식만 사용하는 것은 아닙니다. 필요에 따라 Scattered 혹은 Consolidated 방식을 선택하여 사용합니다. 


오늘 프로젝트를 위해서 데이터베이스에 테이블을 먼저 만들었습니다

외래키 설정을 하기 위해서 migrations 파일을 만들었고, migrate 해줬습니다.

 

앞 번에 과제 때문에 테이블을 새로 만들고 migrate 를 한 적이 있었는데, 오늘 처음으로 migrate 에 의해서 테이블이 새로 만들어지는 것을 보게 되었습니다.

SequelizeMeta라는 테이블이 생기게 되는데 여기에는 migrate 했던 파일들이 들어가 있습니다. 그래서 여기에 해당하지 않는 새로운 migration 파일만 migrate가 되는 것을 알게 되었습니다. 

 

외래키를 설정해주는 데 계속 누락을 하고 실수를 하는 바람에 constratint 파일이 많아졌습니다. 수정이 가능하다면 조금 더 편하게 이용할 수 있을텐데라는 아쉬움을 가지고 있습니다.

 

혹시나 몰라서 테이블을 삭제도 해보니깐 migrate 가 새롭게 진행되는 것을 알 수 있었습니다. 이걸로 수정할 수 있지 않을까 싶기도 한데 기존의 migrate 적용 자체가 삭제되는 건 아니라서 외래키 설정을 이름을 바꿔서 한 다음에 외래키 조회해서 삭제를 해줬습니다. 

 

가장 큰 걱정은 최근에 migrate한 외래키 제약을 잘 못 삭제했는데.. 이거랑 sequelizeMeta 테이블 삭제한 거랑.. 이후에 큰 문제가 발생하지 않았으면 하는 바람입니다. 그리고 확실히 프로젝트를 하니깐 많은 것을 배우게 되는 것 같습니다.

 

설정한 제약 확인하는 방법

select * from information_schema.table_constraints;

select * from information_schema.table_constraints where table_name = '테이블명';

외래키 삭제하는 방법

alter table 테이블명 drop foreign key 확인한 제약조건명;

 

sequelize의 공식문서에서 보니깐 해당 테이블이 만들어진다는 것을 확인할 수 있었습니다!

 

Running Migrations 출처

Until this step, we haven't inserted anything into the database. We have just created the required model and migration files for our first model, User. Now to actually create that table in the database you need to run db:migrate command.

npx sequelize-cli db:migrate

This command will execute these steps:

  • Will ensure a table called SequelizeMeta in database. This table is used to record which migrations have run on the current database
  • Start looking for any migration files which haven't run yet. This is possible by checking SequelizeMeta table. In this case it will run XXXXXXXXXXXXXX-create-user.js migration, which we created in last step.
  • Creates a table called Users with all columns as specified in its migration file.
Comments