[풀스택] 기말고사 Summary

2023. 7. 21. 00:29ComputerScience/FullStackProgramming

 

 

 

 

1. gRPC

- 함수를 호출했으나, 내 컴퓨터에 없는 함수를, 네트워크를 통해 호출하여, return 값을 돌려주는 것 

- Static linking: 실행 파일 생성 시 필요한 라이브러리를 모두 포함하여 생성

- Dynamic linking: 동적 링킹, 함수가 호출되는 시점에 동적으로 링킹을 한다 
-> 
필요할 때 디스크에 있는 파일을 메모리에 올려서 사용한다. 

- 정적 링킹보다 실행 파일의 크기가 작고, 실행 시 적은 메모리를 차지함. 

 

- 원격 함수 호출 RPC – remote procedure call

- DLL은 동일한 컴퓨터 내의 작업 // RPC는 네트워크로 연결된 다른 컴퓨터의 함수를 호출하는 과정 

- Stub 함수 밑에 RPC protocol을 깐다. 클라이언트와 서버는 복잡한 과정을 모른 채, stub func을 호출함

 

- gRPC – 구글이 개발

- 1. Protocol buffer 2. HTTP/2를 사용한다. 

- 기존 RESTful API와 가장 큰 차이점 – REQ, REP패턴이 아닌, 비동기적으로 스트리밍 양방향 지원

+ 흐름제어, 차단, 타임아웃 등 부가 기능도 제공

- 운영체제와 언어에 독립적이라는 장점

 

* RPC의 개선 버전, gRPC

- 클라이언트  서버 아키텍처

- stub – 통신을 통해 원격지로 보내는 것

- protocol buffer에 기반한 형태로 표현된 request, reply 
// 
주고 받는 데이터의 형태가 protocol buffer에 의해 변형됨 

 

* gRPC vs REST API 

// http1.1 -> http2 + gRPC // JSON -> proto buffer

1. 규칙 – restful 반드시 지켜야하는 것은 아님 (자유분방), .proto는 규칙이 매우 엄격함

2. protocol – restful HTTP1,2,3 모두 지원, gRPC only HTTP/2

3. payload – 정보를 실어 나르는 주체. Proto buffer(작고, binary, 사람이 읽을 수 X) 
/ JSON(large, human readable) 

4. Streaming – gRPC client, server, bi-directional 모두 제공, restful은 스트리밍 개념이 없다. 끊임없이 req, rep를 주고 받으며 흉내내는 것은 가능 

5. Browser support – gRPC는 웹 브라우저에서 동작하지 않음. 앱과 서버, 서버와 서버 간 통신을 위한 목적.

Restful은 지원O

6. security – 둘 다 TLS // gRPC는 암호화가 필수 + Client Code generation – 자동으로 생성해준다. 

 

# 첫번째, Unary RPC – 가장 간단한 형태, 1:1 request, response 

- .proto file안에 정의된 single request를 보내고, single response를 가져오는 간단한 프로그램

- 일반적인 함수 호출처럼 동작한다 // 원격지의 서버와 주고 받고 싶은 데이터 및 함수를 표현하는 것

- rpc RpcFunc (request) returns (response) 

-> RpcFunc 원격지에서 호출할, 호출 당할 함수 이름 // 입력 parameter request / response return

 

1. 원격 호출 함수 작성

- my_func -> 서버 쪽에서 원격으로 호출당할 함수를 정의하는 것 (제곱하여 Return)

: 내가 서버 입장에서 제공할 함수를 작성 // application grpc가 뭔지 모른다. 

 

2. protocol buffer 구성 (.proto 파일 작성) -> 일종의 언어

- service Myservice -> 이 내부에 중요한 한 줄 rpc MyFunction(MyNumber) returns (MyNumber)

- 내가 상대방에게 호출할 함수는 myFunc, 이를 제 3의 방식으로 프로토 버퍼가 표현하는 코드

 

- message MyNumber -> int 32, 정확하게 정수 표현, 서로 주고 받을 데이터의 형식을 정의함 

 

3. gRPC class 자동 생성 -> 자동으로 생성된 파일을 어느 위치에 저장할 지 지정

: grpc_tools.protoc 을 통해 자동으로 클래스 파일들을 생성함 

1) message class 파일 - .MyNumber -> 내가 정의한 이름 그대로 가져와서 코드 저장해준다. 

2) client/server class 파일 – .MyServiceServicer -> 서버용 코드 
                         - .MyServiceStub -> 
클라이언트용 코드 

 

4. gRPC 서버 작성 

- 병렬 처리를 위한 futures import, 자동 생성해준 class import, 원격 호출 당할 함수도 import 

- 자동 생성된 base class, MyServiceServicer base derived class를 만듦 

- 아까 생성한 myfunc servicer 안에 들어가 있음 -> 작업된 MyNumber response return 

 

- 서버를 띄우는 행위  동시다발적으로 비동기 처리를 할 것 (알아서 프로그램이 해줌, 나는 params만 설정)

- 우리가 위에서 만든 MyServiceServicer gRPC 서버와 연결 

 

5. gRPC 클라이언트 작성

- protoc (proto compiler)가 자동으로 만들어진 class import

- gRPC 통신 채널을 연다 -> 이 채널을 사용하여, 자동 생성된 파일의 MyServiceStub 함수를 호출해, stub을 생성함

- gRPC를 통해 내가 서버로 보낼 값을 만들고,  request parameter, 
stub
을 사용하여, 원격 함수를 호출함 / 응답 결과를 print / 4*4 = 16 나옴

 

+ 개발 파일 확인

- 원격 호출 대상 파일  원격에서 호출 당할 파일은 이거 하나였음 (제곱 기능 한 줄)

- 프로토버퍼 정의 파일 (.proto) – method 함수는 service, 데이터는 message로 정의

- 자동 생성된 message class 파일, 자동 생성된 하나의 파일 내부에 client, server 용 각각 정의되어 있는 것 

- 서버 파일 / 클라이언트 파일 

 

# 두번째, bidirectional streaming gRPC 

- 양방향으로 주고 받기 가능, 정보를 끊임없이 주고 받는다. 한번에 딱 다 보내는 것이 X

- collection data type element들을 띄엄띄엄 보낸다. 

 

* proto 파일 정의 예제

- rpc RpcFunc (stream request) return (stream response)

 

1. proto buffer 파일 구성 

- package bidirectional – 양방향으로 바뀜

- service Bidirectional {

  rpc GetServerResponse (stream Message) returns (stream Message) {} 

} 

- input output 모두 스트림으로 정의, rpc로 호출할, 호출 당할 함수 이름은 GetServerResponse

 

2. 서버 개발

- 필요한 파일 import, 자동으로 생성되는 base class BidirectionalServicer를 바탕으로 우리의 derived class 생성

- 클라이언트로부터 받은 것을 서버가 그대로 보냄 

- 받아서 보내고, 받아서 보내는 stream to stream (하나 하나 돌려줌) / 스트리밍의 시작은 클라이언트

 

3. 클라이언트 개발

- 통신 channel을 연다, 내가 만든 채널을 proto compiler가 만들어준 BidirectionalStub에 넣어, stub 객체를 만든다. //  stub을 통해 서버로 메세지를 전달함

- 내가 서버에게 호출할 GetServerResponse 의 입력 parameter (, request) generate_message를 넣어준다. 

- 우리가 주고 받을 데이터 형태, message를 만들어주는 함수 make message 

- 이 호출 결과를 받는 list element -> 고정된 리스트가 아니라, 내가 작업을 하며 채워나가는 리스트 의미

: 이러한 경우, return 대신 yield를 사용한다! 

: return은 완성된 하나의 값을, 한 번에 보낼 때 사용 // yield는 메세지를 하나씩 돌려주는 것 

 

* Original RPC에는 이러한 기능 X, gRPC에서 새롭게 등장한 stream 개념 ex) 영상통화

 

# 3. Client Streaming gRPC – 클라이언트가 서버쪽으로 끊임없이 보내는 스트리밍 

- rpc RpcFunc (stream request) returns (response) 

- ex) 클라이언트(센서)가 센서 값을 서버로 올리는 경우 

 

+ Unix 철학  하나의 프로그램의 결과 값이, 다른 프로그램의 입력 값으로 줄 수 있다 – stream 개념

- 끊임없이 강물처럼 줄줄이 보내는 것 

 

- proto buffer 구성 // package clientstreaming

- service ClientStreaming {

  Rpc GetServerResponse(stream Message) returns (Number) {} 

} 

- message – Message string, Number int32

 

- 서버 개발

- 클라이언트로부터 받아야 할 값이 여러 개 (request_iterator)

-> 받을 때 마다, count를 증가시킴 – 5를 다 받고 나면, 받은 개수 5 return 

 

- 클라이언트 개발 

- 클라이언트가 서버로 보낸다는 문구를 출력, 값을 보낼 때, 스트리밍을 위해 return이 아니라 yield

- request 보낼 때는 stream이지만, 서버로부터 받은 response는 한 번에 오는 것 (스트리밍 아님) 

-> response 값 하나만, 한 번에 받아 출력

 

- 실행 결과 – HTTP 메소드라면, 하나하나 총 5 POST/PUT을 보냈어야 했는데, (이러면서 계속 TCP 연결을 열고, 끊음) 지금은 한 번에 심플하게 처리 가능 

 

# 4. Server streaming gRPC

- 서버가 클라이언트로 끊임없이 스트리밍 하는 것

- rpc RpcFunc (request) returns (stream response)

-> 이렇게 스트림이라고 명시하면 스트림이 되고, 아무 말 없으면 스트림이 아닌 것

 

- proto buffer 구성 / package – serverstreaming

- service ServerStreaming {

  Rpc GetServerResponse (Number) returns (stream Message) {}

} 

- message – Message – string, Number – int32

 

-> 즉 서버가 하나 이상의 문자열을 스트림으로 보낼 것

 

- 서버 개발 

- 자동 생성된 파일 import, 문자열을 받아 message로 만듦, 이를 list로 만들고, 클라이언트에게 yield message 

- 이때, return 값을 받는 애는 비동기적으로 작업함

- 5개를 한 번에 보내는 것이 X, 하나 보내고, 하나 보내고 ing -> yield 

-> , 비동기적으로 결과를 돌려줘야 할 때, return이 아니라 yield 사용

 

- client 개발

- 5라는 값으로 Number를 만들고, 이를 서버로부터 호출하고자 하는 함수 GetServerResponse에 데이터를 담아 보낸다. 

- 클라이언트는 이 끊없는 yield를 어떻게 받을까? 

-> 반복문으로 꺼내어 하나씩 출력, 클라이언트는 신경 쓸 필요 X

- response가 리스트라는 전제 하에, 그에 따른 결과가 들어왔다면 하나씩 처리되는 것 

// restful API는 이런거 안 됨

 

* 우리가 이렇게 4가지 gRPC 패턴을 배운 것

1. Unary

2. bidirectional streaming

3. client streaming / server streaming

 

이러한 streaming이 기존 rpc 대비 gRPC의 장점이자 특징

 

* Protocol Buffer의 이해 

- RPC를 사용하는 입장에서 proto buffer 파일은, 사용하는 언어와 무관하게 클라이언트와 서버가 주고 받는 데이터의 형태, 호출할 함수를 정의한 것 

- 한 컴퓨터에서 다른 컴퓨터로 네트워크를 통해 끊임없이 값을 주고 받을 때, 
  
서로 언어가 달라도, OS가 달라도 주고 받을 수 있도록, 2001년에 구글이 개발한 것

- serialization format and library, IDL compiler  서버와 클라이언트가 사용하는 코드를 자동 생성 

 

+ 복잡한 객체들을 단순한 0101 바이트로 내보내기 위한 전환 ==  serialization

- 정보를 주고 받는 개념, 언어와 운영체제와 상관 없이, 독립적으로 데이터를 표현한 것

+ IDL도 결국 언어이다 – interface description language

 

* Protobuf의 동작 원리

- 개발자는 gRPC를 쉽게 사용하고, low, hardware 처리는 protocol buffer가 모두 덮어줌

 

- Protocol Buffer binary encoding 동작

- 정의한 객체들이 0101로 변환된 모습

+ 1337 2byte로 표현, 뒤집어진 방식을 사용, little endian vs big endian // 프로세스마다 다름

- Type Length Value -> TLV 

- 모든 데이터를 이러한 방식으로 변환한 것  하드웨어, 원초적으로   33바이트

 

* gRPC의 장점

1. Performance – 1) ProtoBuf (프로토콜 버퍼) – 효율적인 binary message format

- 매우 빠르게 serialize, 프로토 버퍼는 작고 빠르다. JSON은 파싱 과정이 훨씬 큼

+ small message payload -> 무선, 모바일 환경에서 유리  
// 2) HTTP/2 
기반

- 2-1) binary framing and compression – 비트 단위로 정보를 보내어 사람이 읽을 수 없음 + 정보를 압축함

-> 통신 링크를 아끼고, CPU를 더 쓰는 것 (성능 저하의 원인이 되기도 함) 

- 2-2) Multiplexing – 단일 TCP연결에서 request 보낸 순서와 상관 없이 response가 올 수 있다. 1.1의 대표적인 단점, Head Of Line Blocking을 해결한다. 

+ HTTP/2 서버 간 통신의 대표적인 예시가 gRPC인 것이지, 과거 1.1로 하던 다른 일들도 2가 모두 지원함

 

2. Code generation 

- Proto file – 서버와 클라이언트 개발팀이 이 protofile만 공동으로 작업하면 됨 // 개발 시간 단축

+ 자동으로 base class 코드 생성 

- 아주 명확한 프로토파일에 따라 규격을 정한 것

 

3. Strict specification 

- 기존 restful API, REST는 철학 -> HTTP에는 올바른 정답 같은 건 없음

- gRPC는 철학 같은 개념이 아님. 

- 명확한 규정을 정하는 입장  정당성을 논의할 필요 X

- 개발자들 간 정할 것들에 대해 시간을 줄여준다. 

 

4. Streaming 

- HTTP/2를 기반으로 모든 가능한 경우 다 제공 

- Unary (no streaming), Server streaming, Client streaming, Bi-directional streaming

- 과거 RPC Unary만 가능, gRPC는 스트리밍이 된다. -> 큰 장점 

: 시분할적으로 여러 개의 값을 보낼 때 

 

5. 추가 기능 – Deadline/timeout, Cancellation도 가능하다 

- 클라이언트가 서버를 얼마나 기다려줄 수 있는지, 이 데드라인 값을 서버로 넘길 수 있다. -> 스케줄링

- 클라이언트 입장에서 서버에게 요청을 취소할 수도 있음 (서버에서 값이 안 올 때) 

 

* gRPC 권장 사용 시나리오

- microservices – light weight, 서버 투 서버 통신 

- bi-directional streaming (real-time communication에서 사용)

- Polyglot – 쪼개어 작은 프로그램들이 각자의 컴퓨터에서, 각자의 언어로 돈다  굉장히 다양한 언어를 지원하는 gRPC가 적합 // for multi-language environment

- serialized with ProtoBuf, a lightweight message format

- IPC – between apps on the same machine. 

 

+ microservice 적용 예시

- 앞의 대장, 외부와 연결된 부분은 RESTful, 뒤쪽 서버 내부는 모두 gRPC

 

* gRPC의 단점

1. limited browser support – 웹 브라우저를 통해 할 수 없음 

- 사용자는 URL만 주고, 크롬 브라우저가 알아서 HTTP1.1 or HTTP/2, 3을 결정한다. 

- impossible to directly call a gRPC service from a browser

 

2. Not human readable – 사람이 읽으려면 별도의 도구가 필요하다. HTTP1.1의 장점이 사라진 것

 

** ZMQ request response 패턴보다, gRPC 성능이 확실히 낮음 

1. HTTP/2는 암호화가 default (필수는 아니지만 거의 다 사용) -> 보안에 대한 처리 -> 성능 저하

2. 변환 + 압축 과정 protocol buffer의 처리 -> 성능 저하

 

-> 목적에 부합하는 도구, 요구 사항에 맞는지 분석할 수 있는 능력이 중요하다. 

 

 

 

 

 

2. HTTP2 

* 가장 많은 기말고사 문제 출제

 

* HTTP1.1의 문제점

1. Head of line blocking: 서버는 요청 받은 순서대로 응답을 보내야 한다. 중간에 문제 발생 시, 후속 요청들은 모두 지연됨

2. Fat message headers: 헤더에 많은 메타 정보가 저장, 매 요청 시 중복된 헤더를 전송, 쿠키 정보도 매 요청 시 헤더에 포함되어 전송 // human readable + 너무 많은 정보가 붙음

3. limited priorities: HTTP1.1은 우선 순위 개념이 없다. 화면을 채우는 모든 정보가 동일한 우선순위

4. Client-driven Transmission: 클라이언트가 서버에 요청을 해야만 통신이 가능. 서버는 요청 없이 정보 전달 X

 

- 구글 SPDY: 전송 지연을 줄이는 것 목표로 만들어진 오픈소스 (2009)

- 현재 전 세계 웹사이트의 50% HTTP2 사용 중

 

* HTTP2의 목표

- 줄어든 지연 시간 

- 응답 다중화 지원

- HTTP 헤더 압축 -> 프로토콜 오버헤드 최소화

- 요청 별 우선순위 지정

- 서버 푸시

 

* Binary Framing Layer

- 더이상 human readable text 기반 전송X -> 새로운 binary framing 계층의 도입

- 바이너리 형식, 비트 형태로 인코딩 함

 

- 스트림: 메세지의 상위 개념, 구성된 연결 내에서 전달되는 바이트들의 양방향 흐름, 하나 이상의 메세지가 전달될 수 있음

- 메시지: response, request 메세지에 매핑되는 프레임의 전체 시퀀스, 하나의 메세지가 여러 개의 프레임으로 쪼개져서 보내진다. 

- 프레임: HTTP/2에서 통신의 최소 단위. 각 최소 단위에는 하나의 프레임 헤더가 포함됨 -> 프레임이 속하는 스트림을 식별함

 

- 클라이언트와 서버 사이에 하나의 TCP 연결을 뚫고, 동시에 N개의 스트림을 연다. 스트림들은 병렬 처리 가능, 순서를 독립적으로 부여할 수 있다. 

- 병렬처럼 보이지만 사실 줄은 하나 -> 각 스트림이 점유하는 시간을 조정

- 하나의 스트림 내부에서는 순차적으로 전송됨

- 헤더가 별도의 프레임으로 가장 먼저 도착한다. 

 

* 모든 통신은 단일 TCP 연결을 통해 수행됨, 양방향 스트림의 수는 제한 X

- 각 스트림에는 고유 식별자와 우선 순위 정보가 있다. 

- 프레임은 통신의 최소 단위, 각 프레임의 헤더에 삽입된 스트림 식별자를 통해, 프레임을 재조립 가능

 

* HTTP/2의 가장 큰 특징 2가지 

1. 동시다발적으로 주고 받기 위해 stream 개념 도입

2. 하나의 큰 메세지가 점유하는 것을 방지하기 위해 frame 개념 도입

 

# 요청 및 응답 다중화

 

* HTTP/1.1 문제 재확인

- 클라이언트가 병렬 요청을 수행하려는 경우, 여러 TCP 연결이 사용됨 

- HTTP1.1은 연결 당 한 번에 하나의 응답만 전달되도록 보장함

- Head of Line Blocking 문제 (앞의 문제로, 뒤가 막히는 것) + TCP 연결의 비효율적인 사용 초래 (서버 부하)

 

* 전체 요청 및 응답 다중화를 지원함 

- 클라이언트와 서버가 HTTP 메세지를 독립된 프레임으로 세분화

 이 프레임을 인터리빙(끼워 넣기) 한 후, 다른 쪽에서 재조립 // 다양한 스트림들이 섞여 있다. 

- 요청 순서와 상관 없이, (섞여서) 동시 다발적으로 처리 가능.

 

* HTTP/2 바이너리 프레이밍 계층의 다중화 효과 

- 여러 요청/응답을 하나도 차단하지 않고, 병렬로 인터리빙 할 수 있다.

- 단일 TCP 연결을 사용하여, 병렬적으로 전달 가능

- 불필요한 지연 시간 제거, 페이지 로드 시간을 줄임

: 결론적으로, HOL blocking을 해결할 수 있으며, 여러 TCP 연결 없어도 병렬 처리를 할 수 있다. 

 

# 스트림 우선 순위 지정

 

- 여러 스트림의 프레임을 다중화 하는 것이 가능해지자, 인터리빙되고 전달되는 순서가 중요해짐 

-> 스트림이 가중치(weight)와 종속성(dependency – 순서 부여)을 갖도록 허용함 

- 클라이언트가 우선 순위 지정 트리를 구성 -> 클라이언트가 선호하는 응답 수신 방식 나타냄 

- 서버가 이 정보를 사용하여, 스트림 처리의 우선 순위를 지정함

- 응답 데이터가 있는 경우, 서버는 우선 순위 높은 응답이 최적으로 전달되도록 대역폭 할당함 (무선 통신의 경우 의미가 크다.) 

 

* 스트림 종속성 (dependency)

- 자신 보다 높은 우선순위의 스트림의 식별자를 상위 요소로 참조하는 방식 

- 식별자 생략  스트림이 루트 스트림에 종속됨 (내가 루트)

- 상위 요소 스트림에 리소스가 먼저 할당되어야 함을 나타냄 

 

* 스트림 자원 할당

- 동일한 level의 스트림 사이에서는, 가중치에 비례하여 리소스가 할당됨

- ex) A = 12, B = 4 -> AAA B AAA B AAA B AAA B (인터리빙, 끼워넣기, 비율 고려)

- 종속성이 있다면, 가중치는 중요하지 않음 (무조건 상위 애가 더 높은 우선권)

- 동일한 level: 먼저 할당 받는 것은 아님 - 가중치에 따라 할당의 비율이 달라지는 것

 

* 스트림 우선 순위 지원의 효과

- 브라우저 성능 개선에 중요 (여러 리소스 유형이 존재할 때)

- 클라이언트 개발자가 언제든지 종속성, 가중치 변경 가능

 

- 주의 사항: 클라이언트의 요청을 참조하되, 서버가 무조건 해주는 것은 아니다. 서버에게 강요할 수 없음

- 따라서, 특정한 처리나 전송 순서를 보장하지는 않음

 

# 단일 TCP 연결 

- 모든 HTTP/2 연결은 영구적  값비싼 TLS 핸드셰이크가 줄어듦 (암호 관련 연결 설정  상당히 많은 시간) 

- 대부분의 HTTP 전송은 수명이 짧고 폭주 burstness // 반면 TCP는 수명이 긴 대량 데이터 전송에 최적화

- HTTP/2 : 동일한 TCP 연결을 재사용  더 효율적인 사용, 프로토콜 오버헤드를 대폭 줄임

+ 더 적은 TCP 연결을 사용  메모리와 처리량 줄어듦

-> 따라서 2는 네트워크 지연 시간이 줄어들 뿐만 아니라 처리량이 개선되고 운영 비용이 줄어듦

 

# 흐름 제어

 

- 사용자가 동영상을 일시 중지 -> 서버로부터 동영상 전달을 중지 or 차단

: 쓸모 없는 컨텐츠를 보내고, 클라이언트가 처리하는 것을 모두 없앰

- 프록시 서버가 업스트림 속도에 맞게 다운스트림 데이터 전달 속도를 조절

 

HTTP/2 흐름 제어 특징 

- 흐름 제어를 구현하기 위한 특정 알고리즘 지정 X (개발자가 알아서 함, 빌딩 블록을 사용하여 사용자 설정)

- 특정 리소스의 일부만 가져온 뒤, 수신 버퍼 사이즈를 0으로 만들어 버퍼링을 안할 수 있음 

-> 특정 이미지의 미리보기나 최초 스캔

 

HTTP/2 흐름 제어 동작 원리 (원리는 TCP 흐름 제어와 같다)

- 흐름 제어는 양방향  각 스트림과 전체 연결에 원하는 창 크기를 설정

: stream level에서 윈도우 크기를 주고 받으며 flow control

- 각 수신단은 자체의 초기 연결과 스트림 흐름 제어 Window (바이트 단위, 버퍼 크기)를 알림 

 

- 흐름 제어는 비활성화 될 수 없다 (중단만 가능, 끌 순 없다. 무조건 사용)

- 클라이언트와 서버가 SETTINGS 프레임을 교환 -> 양쪽 방향에서 흐름 제어 창 크기를 설정

: 기본값은 64KB, 최대 창 크기 2GB -> application level에서 쏠 수 있는 양이 매우 늘었다. 

 

- 흐름 제어는 홉 방식이다. (hop by hop) 

: 중개자(프록시)가 프록시와 서버, 프록시와 클라이언트 각각에 대한 흐름 제어가 가능하다.

- 프록시 서버가 전면에 등장

 

# 서버 푸시

- 클라이언트가 명시적으로 요청하지 않아도, 서버가 추가적인 리소스를 푸시할 수 있음 

- 나중에 요청할 것을 미리 보내, 지연 시간을 줄여보자 

 

- PUSH_PROMISE frame을 보낸다 (헤더만 담긴) -> 이후, 각각의 pushed 리소스는 스트림이다.

- 클라이언트는 RST_STREAM으로 거절할 수도 있다. (이미 리소스가 캐시에 있거나 등등) 

- 클라이언트가 푸시 스트림의 개수를 조절할 수 있다. (flow control window도 조절 가능) 

- but 구글이 만든 크롬 브라우저에서 삭제됨

 

# 헤더 압축

 

- HTTP1.1 – 주고 받는 데이터 대비 너무 큰 헤더 -> 압축  HPACK

* 허프만 코딩  과거와 현재의 차이 기반 압축 기술 

: 바뀌지 않은 값들은 인덱스만 전달, 달라진 값만 주고 받는 허프만 코딩 방식

 

- HTTP1.1: 두 개의 요청 헤더에 중복 값을 그냥 중복 전송

- HTTP/2: 중복된 헤더는 index 값만 전송, 중복되지 않은 헤더 정보의 값은 허프만 인코딩하여 전송

: 차이가 있을 때, 달라진 값(작은 비트)만 보내는 기법

-> 과거 이력에 대한 테이블을 미리 만들어, 클라이언트와 서버가 갖고 있는다. 

 

- static table: 자주 주고 받는, 대부분 사용하는 값들은 미리 static으로 만들어 갖는다.

- dynamic table: 처음에는 empty, 메세지를 주고 받으며 채워나가는 테이블

 

// HTTP/2 개발 환경

- 언어가 지원하지 않는다. 다른 라이브러리로 바꾸기 매우 어렵다. 

- GO: 언어가 표준 라이브러리로 HTTP2 제공 (standard)

- strong, static typing, C와 유사, 서버 개발을 위한 언어

 

* TLS 기반 – localhost Server에 대한 임시 인증서를 자체 발행 (RSA 암호화 방식)

- 코드에 암호화 절차, TLS 관련 코드가 있다. 

- HTTP 여러 버전에 대한 처리 -> client.Transport를 변경하여 처리 가능 

 

 

 

 

 

3. WebRTC

- 웹 브라우저 기반의 real time communication / 오디오, 비디오 기반의 서비스 / P2P 기술 by 구글 

 

- ZMQ dirty P2P -> too heavy / 서버 하나도 없는 것, 모든 IP address에 대해 연결, OS도 힘든 일

- peer 2 peer – 중앙집중화 된 서버 없이, 나를 제외한 모든 동등한 peer(node)와 연결하여, 서로 자원을 공유함

- peer to peer와 달리 client – server 구조 -> 각 클라이언트들이 서버에게 request, 중앙 서버가 리소스 제공 

 

* block chain 기술 – P2P 기술을 기반으로, 체인 형태의 연결고리 기반 분산 데이터 저장 환경

- 임의 조작이 불가능, 변화가 발생 시, 모든 사용자가 생성된 block을 나눠 가짐 / 중앙 집중화 된 서버 X

- 타인의 거래에 내 노트북 자원이 사용됨 / 이동통신  비용, 이득이 없다. 

 

- WebRTC – real time communication 서비스 / 애플, 구글, 모질라 등 모두 웹 브라우저에 도입함 

- 본인이 필요한 기능을 크롬 브라우저에서 호출하여 사용하면 됨 / 화면 구성만 하면 브라우저가 알아서 다 함 

- GIPS 소속 개발자가 개발 -> 구글이 인수, 2011 WebRTC로 개명한 후, 오픈소스 공개 / IETF 통한 표준화

 

* WebRTC의 목적  중간자 없이 브라우저 간 오디오나 영상을 주고 받을 수 있다. 소프트웨어 설치도 필요 X

 

- 대표적인 3개의 API

1) RTCPeerCommunication() – 서로 지원 가능한 방식을 nego하는 것, 연결 설정 관련된 함수

2) getUserMedia() – 녹음, 녹화 등 비디오와 오디오를 내보내기 위해 데이터 get

3) RTCDataChannel() – 데이터들을 실어나르는 것 

 

* WebRTC에는 3개의 기술이 따라붙는다 -> 시험 문제 출제! 

* ICE (Interactive Connectivity Establishment) 

- 브라우저가 peer를 통한 연결이 가능하도록 하게 해주는 프레임워크 

- private IP NAT/PAT를 통과하며 public IP로 변환됨   public IP를 어떻게 알 수 있을까? -> ICE로 해결

- ICE는 이러한 작업을 수행하기 위해, STUN서버와 TURN 서버를 사용함

 

* STUN (Session Traversal Utilities for NAT) - NAT를 통과하기 위한 STUN 서버 

- NAT 뒤의 두 peer 간 연결이 필요 / 요청자의 Public IP address를 알려주는 것

+ symmetric NAT – STUN서버에 의해 public IP 알아낸다고 모두 연결되는 건 X, 이를 위해 TURN이 필요

 

* TURN (Traversal Using Relays around NAT) 

- NAT가 있는 곳에서 릴레이(트래픽)를 제공하여 통신을 한다. 

- peer  M:N 정보를 직접 주고 받지 않게, 신뢰할 수 있는 TURN 서버에게만 방화벽을 뚫고, 정보를 보내면 TURN 서버가 대신 뿌려주는 역할 

- , TURN 서버는 트래픽을 주고 받는 용도로 사용 

 

+ SDP – Session Description Protocol - 해상도, 형식, 암호화 등 컨텐츠의 연결을 설명하기 위한 표준 

- session describe 한다면, (통신한다면) 주고 받는 미디어의 포맷을 합의하는 것 

 

- 네트워크를 타고 p2p 구현 시, NAT/PAT + 방화벽 등의 문제로 직접 주고 받을 수 없다.

- 연결을 위한 서버들이 필연적으로 등장 

1) STUN을 거쳐 public IP를 얻어 연결 설정  2) TURN 서버로 트래픽을 주고 받음 

- peer 간 데이터는 직접 송수신하는 것이 기본 구조

 

1) Signaling 서버를 통해 SDF를 주고 받는다 (나는 이런 미디어 지원 할 수 있어 – offer / 너는? – answer) 

2) ICE (STUN + TURN) 서버를 통해 통신 관련 정보를 주고 받는다. 

-> 이러한 signaling 서버, STUN + TURN 서버  구글이 알아서 관리 

 

* WebRTC 주요 구성요소 

- NAT – network address translation – 연결된 인터넷 디바이스에 사설(private) IP 부여 

- ICE – interactive connectivity establishment – ICE라는 우산 아래, STUN, TURN 서버가 있다. –p2p 간 다이렉트 통신을 위한 기술로, 통신을 위한 최적의 경로 탐색

- STUN – session traversal utilities for NAT – 기기의 public IP를 찾고, p2p 연결을 방해하는 요소 탐지

- TURN – traversal using relays around NAT – STUN 서버를 이용한 연결이 실패한 경우, 오디오 비디오 등을 릴레이 (트래픽 전달)

- SDP – session description protocol – p2p로 서로 주고 받는 데이터에 대해 이해할 때 사용 

- signaling server – 기기 사이의 연결을 생성하는 역할 

 

+ WebRTC UDP 위에서 구현된다. 

- SRTP – real time으로 오디오, 비디오 데이터를 실어나르는 것

 

* WebRTC의 장점 

- near real time -> low latency – 중간에 서버를 경유하지 않아, 지연 시간이 매우 줄어듦 (매우 빠름) 

- glass to galss latency – 카메라에서 촬영  화면으로 나오는 것 까지의 지연 시간 – 500ms

- WebRTC HTML5 – 할 일이 많아졌다 / 브라우저가 강력해진 것 

- 표준화 된 오픈소스 (IETF로부터 표준화 됨)

 

+ Simulcasting

- HTTP live streaming – 끊임없는 HTTP request – 네트워크 상황에 맞추어, 서버에서 가져올 파일의 해상도를 조절한다. 한 순간에는 하나의 파일만 가져온다.

- simulcasting / WebRTC는 모든 해상도를 보낸다 / client가 알아서 갈아타면 됨  선택은 받는 사람이 

 

* WebRTC의 단점

- Scalability  하나의 WebRTC session에 대해, 50명 이내로 있는 것이 적절하다. (제한됨) 

- 50 이상일 경우, live streaming server에 전달하고, 서버를 사용하여 뿌려야 함  즉 서버가 도입됨 

+ 사용자 수가 늘어나도 부담, 지원할 해상도가 늘어도 부담

+ 화질 상 문제가 있다고 하는데, 이건 크게 X

 

- 구글은 WebRTC을 오랜 시간 개발, 표준화를 주도, WebRTC를 위해 오픈소스 VP8 코덱 개발 및 오픈소스화

- 구글 meet, 유튜브 라이브 채팅 기술에서도 WebRTC를 사용함 

- 모질라 – firefox 웹 브라우저는 초창기 2013년부터 음성 영상 표준 WebRTC 지원

- 시스코 – Webex WebRTC 표준 사용

 

- 웹 브라우저 위에서 자바 스크립트가 기본이지만, 다른 언어도 지원 / 파이썬, 다트도 가능 

 

- SOLID – 팀 버나스 리 경  내가 원한 세상은 이런 게 아니다 (구글, 메타가 돈을 버는 구조, WWW 상업화)

- 인스타에 사진 업로드 시, 더이상 내 것이 아님 / 내 정보는 공인된 저장 공간에만 저장 / 다른 곳에는 링크 / 내가 거절하면 볼 수 없다  내 허락 받아 

- 폰에 SOLID – 이동 통신 요금 문제 / 구현 시 구글 드라이브, 드롭박스 사용  자가당착 

 

 

 

 

 

4. QUIC & HTTP3

* 현대 통신 프로토콜 패러다임 

1) application layer 2) opensource 3) UDP based new transport protocol

 

* QUIC / HTTP3 출현 배경

- 기존 TCP의 문제점을 QUIC에서 UDP를 사용하여 개선

- 나아가 TLS 암호화   3자가 볼 수 없도록 하였다. 

 

* TCP의 단점

- slow start

- loss 발생 시 급감  톱니바퀴 모양의 그래프

- head of line blocking – 한 줄에서 에러가 발생하면, 모두 영향을 받음 

             - HTTP2도 여전히 해결하지 못한 문제점 (TCP 사용하니까) 

 

* QUIC 

- UDP 기반의 새로운 transport protocol 

- TLS 필수  신뢰성을 제공한다. 

 

* QUIC connection 

- QUIC 연결은 두 QUIC 엔드 포인트 사이의 대화

- 연결 설정의 지연 시간을 줄여준다. 

- 데이터를 보낼 때, 하나 이상의 stream을 만들어 사용

 

* QUIC Connection ID

- IP address와 별개의, Connection ID가 있다. 

- 모바일 환경에서 IP address는 바뀌더라도, (카페에서 wifi – 실외에서 이동 통신, 셀룰러) 

Connection ID가 유지된다면, 서비스 연결이 유지된다! 

 

* Stream based Transport 

- 하나의 연결로 다수의 병렬 스트림을 전송

- 서로 다른 스트림은 순서 없이 전달 가능

- QUIC은 연결과 스트림 모두에서 흐름 제어 제공

- stream에 대한 우선 순위 존재 

 

** QUIC의 특장점: 지연 시간 감소

- TCP 3 way handshake vs QUIC 0-RTT, 1-RTT handshake

- 이른 데이터 (early data) 지원

- QUIC 연결 설정 안에 TLS 연결 설정을 포함하여, 더 빠른 연결이 가능하다.

- 기존에 연결한 클라이언트 -> 해당 연결의 특정 parameter 캐시하여, 서버와 0-RTT 연결 가능

             - 연결 설정이 시작하자마자, 데이터를 보낼 수 있다.

             - 0-RTT – 상대방에게 오는 것을 기다리는 시간이 없다. 

 

* URL – 새로운 URL 체계를 만들지 않고, 기존 체계 유지

- 초기 연결은 TCP를 통해 수행된다. (HTTP1.1 or 2)

- 서버는 다시 연결하여, 3를 시도할 수 있다고 클라이언트에게 알릴 수 있다. 

 

* Alt-svc (alternative service) 

- 서버가 Alt-svc: h3 = “:50781” 를 응답에 포함하여, 50781 UPD 포트에서 HTTP3를 사용할 수 있음을 나타내는 의미로 클라이언트에게 전달

 

* HTTP/3 frame

- HEADERS – 압축된 single HTTP 헤더를 보냄

- DATA – 이후 바이너리 데이터 컨텐츠 frame들을 보냄

- GOAWAY – 마지막으로 연결 종료 시 메세지

 

- QPACK 에 의해 headers 프레임이 압축된다. 

-> HTTP/2 HPACK과 유사하다. 

 

* 우선순위 제어 – HTTP2와 동일한 방식

- 종속된 stream은 부모 먼저

- 동일한 level -> 가중치에 따라 리소스를 할당 받는다. 

 

* Server PUSH 푸쉬

- 서버 푸쉬: 클라이언트가 보낸 적 없는 요청에 대한 효율적인 응답

- 서버가 요청에 푸시로 응답한 것 처럼 보이는 PUSH_PROMISE 프레임을 보낼 수 있다. 

- 클라이언트가 푸쉬 취소하고 싶다면, 서버에 CANCEL_PUSH 프레임을 보냄

 

* HTTP/2  HTTP/3의 유사점

- connection이 있고, stream을 제공한다.

- 서버 푸시를 지원한다.

- 헤더 압축을 제공한다. (QPACK, HPACK – 유사)

- 스트림을 이용하여, 하나의 연결을 통해 멀티플랙싱 제공 

- 스트림에 우선순위를 정함

 

* HTTP/2  HTTP/3의 차이점

- QUIC 덕분에 연결 설정 시 더 빠르다. 

- TLS 필수  암호화되지 않은 버전이 없다. 

+ 클라이언트로부터 Alt-svc 헤더 응답이 먼저 있어야 한다. 

 

* QUIC의 단점 

1. 커널 안에 없다 –> QUIC에는 표준 API가 없다. 

-> 기존 라이브러리에서 다른 것으로 바꾸기 매우 어렵다. (Locked in) 

2. UDP 프로토콜이 TCP만큼 최적화 되어있지 않아, QUIC 프로토콜 성능 개선 연구 중

- HTTP/3 HTTP/2 대비 같은 트래픽 기준, 2배의 CPU 필요하다는 보고

 

* QUIC 현황

- 구글, 유튜브, 메타, 네이버 // 서버 – nginx // 브라우저  크롬, firefox, safari, edge