이 글의 사진과 내용은 공룡책 과 컴퓨터학부 수업인 운영체제 강의자료를 기반으로 작성했습니다.
Concurrency(동시성)을 구현하기 전에, 먼저 Thread
에 대해 알아보자.
Thread
(스레드)란 하나의 프로세스 안에서 독립적으로 실행될 수 있는 개별 실행 단위(Each execution unit)이다.위의 그림처럼 스레드는 단일 실행 프로세스에 대한 새로운 추상화 개념이다.
프로그램은 이처럼 동시에 다중의 스레드를 사용하여 실행된다.
Multi-threaded Process
란 하나 이상의 스레드보다 많은 것을 가진 프로세스를 의미한다.
Context Switching unit
이 thread를 의미하며, 각각의 스레드는 자신만의 실행 상태(PC, register, stack)을 가진다.
그리고 각 스레드의 실행 상태(execution state)는 OS에 의해 관리되는 TCB(Tread Control Block)에 저장된다.
실행하고 있는 T1에서 다른 T2로 Switching이 발생했을 때,
T1의 실행 상태는 TCB에 복사(저장)되어야 하고, T2의 실행 상태는 TCB로부터 복원(저장)되어야 한다.
이때 T1, T2은 주소 공간을 공유한다는 점이다.
Stack
이다왼쪽 그림에서는 싱글 스레드고, 오른쪽 그림은 멀티 스레드다.
멀티 스레드의 경우 몇 개의 스레드가 주소 공간을 공유하기 때문에 하나의 주소 공간만을 사용하는 것을 볼 수 있고, 각각의 스레드들은 개별적인 스택 공간을 갖고 있어서 위와 같이 주소 공간에 Stack 부분이 분산되어 있다.
스레드들은 자신만의 Stack을 가지고 있고 Code, Data, Heap은 공유한다는 점에서 프로세스와 차이점을 지닌다.
Multi-threaded Process
(멀티 스레드)란 하나의 프로세스안에 여러 개의 스레드로 구성하여 하나의 스레드가 하나의 작업을 처리하도록 하는 것이다.
스레드를 사용하는 이유는 크게 2가지다.
첫 번째는 병렬 처리가 간단하다. 단일 프로세스에서 여러 스레드가 각자 하나의 작업을 처리하기 때문에 시간을 절약할 수 있다. 이렇게 단일 프로세스에서 각각의 스레드들이 여러 CPU에서 실행하는 것을 병렬화
라고 하며 이를 구현할 때 스레드를 사용하는 것이 일반적인 방법이다.
두 번째는 I/O로 인해 프로그램 수행이 차단되는 것을 막기 위해서이다. 다양한 유형의 I/O가 수행하는 프로그램이 있을 때, 프로그램의 자식 스레드가 오류가 나거나 긴 작업으로 인해 중단되었을 때 다른 스레드로 Context Switching하여 수행하면 I/O와 다른 작업들을 함께 수행할 수 있다.
하지만, 이런 스레드에서도 문제점이 존재한다.
첫 번째는 실행 순서가 OS 스케줄러에 의해 누가 먼저 수행될지를 모른다는 것이다.
다음 그림을 통해 제대로 이해해보자.
[첫 번째 경우의 수]
1. starts running
2. create thread 1
3. create thread 2
4. running thread 1
5. running thread 2
[두 번째 경우의 수]
1. starts running
2. create thread 1
3. running thread 1
4. create thread 2
5. running thread 2
[세 번째 경우의 수]
1. starts running
2. create thread 1
3. create thread 2
4. running thread 2
5. running thread 1
두 번째는 멀티 스레드에서 공유하는 데이터에 동시에 접근할 때(업데이트 할 때) 문제가 발생한다.
다음 그림을 통해 제대로 이해해보자.
여기서 counter
는 data 영역(전역 변수)라고 가정한다.
왼쪽은 예상된 결과인 counter 값이 12로 나오고, 오른쪽은 예상치 못한 결과인 counter 값이 11로 나오는 것을 확인할 수 있다.
오른쪽에서 2번째 순서인 tmp = tmp + 1
를 끝나고 갑자기 Context Switching이 발생했을 때, 2번에서 counter 값이 업데이트 되지 않았기 때문에 3번에서 counter = 10으로 다시 시작된다.
그래서 4-5번을 거쳐 counter = 11로 끝나고 다시 Tread1로 넘어오면서 counter = 11 로 끝나는 결과를 보여준다.
이렇게 전역 변수와 같이 스레드에서 공유하는 데이터에 접근하는 상황을 Race condition(경쟁 상태)라고 하며,
여기서 전역 변수와 같은 공유되는 값을 Critical section(임계 영역)이라고 하며 위와 같이 임계 영역에 여러 개의 스레드가 동시에 접근하면 원하는 결과를 얻지 못하는 상황이 발생하게 된다.
그리고 임계 영역에 접근하는 스레드들 중에서 어떤 스레드가 먼저 읽었는지
와 같은 접근 순서, 타이밍과 같은 것이 결과에 영향을 끼치는 상태를 Indeterminate(불확실성) 라고 말한다.
Critical section
(임계영역)은 여러개의 스레드가 동시에 접근해서는 안되는, 즉 하나의 스레드만 접근할 수 있는 영역이다.
다수의 스레드가 critical section 접근하면 Race condition(경쟁 상태)의 결과를 가져온다.
만약 어떤 스레드가 critical section에 접근하는 중이라면 다른 스레드가 접근할 수 없도록 atomicity(원자성)을 보장해야 하며, 이를 mutual exclusion(상호 배제)라고 부른다.
REST
(Representation State Transfer)란 자원을 이름으로 구분하여 해당 자원의 상태를 주고 받는 모든 것을 의미한다.
HTTP URI(Uniform Resource Identifier)를 통해 자원을 명시하고, HTTP 메소드(GET, POST, PUT, PATCH, DELETE)를 통해 해당 자원(URI)에 대한 CRUD Operation을 적용하는 것을 의미한다.
CRUD Operation
이란 Create, Read, Update, Delete를 묶어서 읽컫는 말이다.
REST 에서 CRUD Operation 동작 예시는 다음과 같다.(HTTP 메소드와 비교)
Create
: 데이터 생성 <-> POST
Read
: 데이터 조회 <-> GET
Update
: 데이터 수정 <-> PUT, PATCH
Delete
: 데이터 삭제 <-> DELETE
참고) HTTP 메소드에 가면, HTTP 메소드의 종류와 속성을 따로 정리해 두었다.
자원(Resource) : HTTP URI 형태로 나타낸다.
자원에 대한 행위(Verb) : HTTP Method를 나타낸다.
자원에 대한 행위의 내용(Representations) : HTTP Message Pay Load를 타나낸다.
[1] Uniform Interface(인터페이스 일관성)
HTTP 표준에만 따른다면, 안드로이드/IOS 플랫폼이든, 특정 언어나 기술에 종속하지 않고 모든 플랫폼에 사용할 수 있으며, URI로 지정한 리소스에 대한 조작이 가능한 아키텍쳐 스타일을 의미한다.
이러한 범용성을 갖추기 위해 REST API의 HTTP Response Body는 HTML 보다는 JSON, XML 등 여러 플랫폼에서 사용하기 적절한 단순한 텍스트 포맷을 사용한다.
(REST를 이야기 하면, HTTP + JSON을 쉽게 떠올리는데, JSON은 하나의 옵션일 뿐, 메시지 포맷을 꼭 JSON으로 적용해야할 필요는 없다)
[2] Stateless(무상태)
작업을 위한 상태 정보를 따로 저장하지 않고 관리하지 않는다. 즉, 각 요청에 대한 컨텍스트(세션, 로그인 정보)가 서버에 저장되어선 안된다.
세션 정보나 쿠키 정보를 별도로 저장, 관리하지 않기 때문에 API 서버는 들어오는 요청만을 단순히 처리하면 된다.
그래서 서비스의 자유도가 높아지고 서버에서 불필요한 정보를 관리하지 않으므로 구현이 단순해진다.
[3] Cacheable(캐시 처리 가능)
REST의 가장 큰 특징 중 하나는 HTTP라는 기존 웹 표준을 그대로 사용하므로 웹에서 사용하는 기존 인프라를 그대로 활용이 가능하다.
HTTP 프로토콜 기반의 로드 밸런서나 암호화(SSL)은 물론이고 HTTP가 가진 가장 강력한 특징중의 하나인 캐싱 기능을 적용할 수 있다.
HTTP 프로토콜 표준에서 사용하는 Last-Modified
태그나 E-Tag
를 이용하면 캐싱 구현이 가능하다.
[4] Client-Server(클라이언트-서버 구조)
REST 서버는 API를 제공하고, 제공된 API를 이용해서 비즈니스 로직 처리 및 저장을 책임진다.
클라이언트는 사용자 인증이나 컨텍스트(세션, 로그인 정보) 등을 직접 관리하는 구조로 각각의 역할이 확실히 구분되기 때문에 클라이언트와 서버에서 개발해야 할 내용이 명확해지고 서로 간에 의존성이 줄어들게 된다.
[5] Layered System(계층형 구조)
클라이언트는 보통 대상 서버에 직접 연결되었는지 중간 서버를 통해 연결 되었는지를 알 수 없다.
중간 서버는 로드 밸런싱 기능이나 공유 캐시 기능을 제공함으로써 시스템 규모의 확장성을 향상시키는데 유용하다.
클라이언트 입장에서는 REST API 서버만 호출할 수 있는 반면에, 서버는 다중 계층으로 구성될 수 있다.
순수 비즈니스 로직을 수행하는 API 서버와 그 앞단에 사용자인증(보안), 로드 밸런싱, 암호화(SSL) 계층을 추가해서 구조상의 유연성을 둘 수 있다.
그리고 Proxy, Gateway 같은 네트워크 기반의 중간매체를 사용할 수 있게 한다.
장점
HTTP 프로토콜의 표준을 최대한 활용하여 여러 추가적인 장점을 함께 가져갈 수 있게 해준다.
HTTP 표준 프로토콜에 따르는 모든 플랫폼에서 사용이 가능하다.
REST API 메시지가 의도하는 바를 명확하게 나타내기 때문에 의도하는 바를 쉽게 파악할 수 있다.
여러 가지 서비스 디자인에서 생길 수 있는 문제를 최소화한다.
클라이언트와 서버의 역할을 명확하게 분리한다.
단점
REST는 표준이 없어서 관리가 어렵다.
HTTP 메소드 형태가 제한적이다.
웹 브라우저를 통해 테스트해야할 일이 많은 서비스라면, 쉽게 고칠 수 있는 URI보다 Header 정보의 값을 처리해야 하므로 전문성이 요구된다.
구형 브라우저에서 호환되지 않아, 익스플로어와 같은 지원이 안되는 동작이 많다.
REST API
란 REST의 아키텍쳐 스타일을 따르는 API를 의미한다.
API
란 Application Programming Interface 약자로, 다른 소프트웨어 시스템과 통신하기 위해 따라야 하는 규칙을 의미한다.[1] URI는 명사, 소문자를 사용해야 한다.
Bad Example https://devfancy.github.io/Healthy
Good Example https://devfancy.github.io/health
[2] 마지막에 슬래시(/) 포함하지 않는다.
Bad Example https://devfancy.github.io/health/
Good Example https://devfancy.github.io/health
[3] 언더바(_) 대신 가독성을 높이는 하이픈(-)을 사용한다.
Bad Example https://devfancy.github.io/health_club
Good Example https://devfancy.github.io/health-club
[4] 파일 확장자(.png, .jpg)는 URI에 포함시키지 않는다.
Bad Example https://devfancy.github.io/developer.png
Good Example https://devfancy.github.io/developer
[5] 행위를 포함하지 않는다.
Bad Example https://devfancy.github.io/delete/post/1
Good Example https://devfancy.github.io/post/1
RESTful
은 일반적으로 REST라는 아키텍쳐를 구현하는 웹 서비스를 나타내기 위해 사용하는 용어이다.
RESTful API 용어와 REST API 용어는 일반적으로 같은 의미로 사용하나, REST를 사용했다고 모두 RESTful 하다고 볼 수 없다.
REST API의 설계 규칙을 제대로 지킨 시스템을 RESTful하다고 볼 수 있다
만약 모든 CRUD 기능을 REST API 혹은 URI 규칙대로 지키지 않았다면, REST API를 사용했다고 말하지만, RESTful 하지 못한 시스템이라고 말할 수 있다.
RESTful의 목적은 이해하기 쉽고 사용하기 쉬운 REST API를 만드는 것이다.
RESTful한 API를 구현하는 근본적인 목적이 성능 향상에 있는 것이 아니라 일관적인 컨벤션을 통한 API의 이해도 및 호환성을 높여주는 것이 주 목적이다.
성능 향상이 주 목적인 상황에서는 굳이 RESTful한 API를 구현할 필요는 없다.
클라이언트가 서버에게 요청을 전송한다.
서버가 클라이언트를 인증하고 해당 요청을 수행할 수 있는 권한이 클라이언트에 있는지 확인한다.
서버가 요청을 수신하고 내부적으로 처리한다.
서버가 클라이언트에 응답을 반환한다. 응답에는 요청이 성공했는지 여부를 클라이언트에게 알려주는 정보가 포함된다. 또한 클라이언트가 요청한 모든 정보도 포함된다.
REST에 대한 개념을 공부했지만, 아직은 부족한 느낌이 든다.
REST와 REST API, RESTful API에 대한 공부를 추가적으로 더 하면서 해당 블로그를 업데이트를 하자.
이 글은 주디님이 HTTP 진화과정을 바탕으로 정리한 내용입니다.
HTTP
는 World Wide Web에 내제된 프로토콜이다.
World Wide Web(WWW)
는 HTTP라는 프로토콜을 이용해 HTML 파일을 주고 받는 공간을 의미한다.기본적으로 HTTP
는 전송 계층 위에 있는 애플리케이션 계층으로 웹 서비스 통신에 사용된다. 쉽게 말해 인터넷의 멀티미디어 배달부다.
이런 HTTP
가 어떻게 진화되었는지 알아보자.
원-라인 프로토콜
HTTP/0.9
는 단순한 클라이언트-서버 구조를 따른다.
요청 : 단일 라인으로 구성
리소스 경로 : GET
메소드만 가능
<!-- HTTP request -->
GET /mypage.html
<!-- HTTP response -->
<html>
Simple HTML Page
</html>
HTTP 헤더가 없으므로 HTML 파일만 전송 가능하다.
상태 혹은 오류 코드가 없다.
기존 HTTP/0.9 기능을 확장
HTTP/1.0
이 등장한 배경은 HTTP/0.9 가 굉장히 제한적이었고, 확장성을 높이기 위해서이다.버전 정보가 각 요청에 포함된다. 요청 메서드는 기존 GET
에서 HEAD
, POST
가 추가되면서 세 가지로 확장되었다.
상태 코드가 각 응답의 시작 부분에 포함되어, 웹 브라우저가 해당 요청에 대한 성공 또는 실패를 알 수 있고, 동작할 수 있다.
HTTP 헤더 개념이 등장하면서, 서버와 브라우저의 메타데이터 전송을 허용하며 프로토콜을 유연성 및 확장성을 가능하게 만들어졌다.
새로운 HTTP 헤더의 등장(Content-Type
)으로 HTML 파일 이외의 다른 파일도 전송할 수 있게 되었다.
<!-- HTTP request -->
GET /mypage.html HTTP/1.0
User-Agent: NCSA_Mosaic/2.0 (Windows 3.1)
<!-- HTTP response -->
200 OK
Date: Tue, 15 Nov 1994 08:12:31 GMT
Server: CERN/3.0 libwww/2.17
Content-Type: text/html
<HTML>
A page with an image
<IMG SRC="/myimage.gif">
</HTML>
표준화된 HTTP(표준 프로토콜)
HTTP/1.1
은 모호험을 명확하게 하고 많은 개선 사항들을 도입했다.[1] 연결 재사용
HTTP/1.0
에서는 기본적으로 한번 연결할 때, 하나의 요청을 처리하고 요청에 따른 응답이 수신되면 TCP 연결을 바로 종료했다.
하지만, 웹 페이지가 복잡해지면서 한 페이지에서 여러번 HTTP 요청이 발생했을 때 매번 새로 TCP Handshake 과정을 거쳐야해서 속도가 느려졌다. (RTT 증가)
RTT
는 패킷이 목적지에 도달하고 나서 다시 출발지로 돌아오기까지 걸리는 시간이다. 즉, 패킷 왕복 시간을 말한다.TCP 가상 회선 방식
은 신뢰성을 보장하지만 속도가 느리다는 단점이 있다.
이에 대한 해결방안으로 한 번 수립한 연결을 재사용하게 설정했다.
Keep-Alive
란 하나의 TCP 연결을 활용해서 여러번의 HTTP 요청과 응답을 주고받을 수 있도록 도와주는 역할이다. 이러한 Keep-Alive
기능을 통해 TCP Handshake 과정이 생략되므로 성능 향상을 기대할 수 있고, 응답 시간을 개선할 수 있다.
(HTTP/1.0에서도 있었지만 표준화가 아니었고, HTTP/1.1부터 표준화가 되어 기본 옵션으로 설정되었다)
Keep-Alive를 이용한 통신은 클라이언트 혹은 서버 중에 한 족이 다음 헤더를 부여해 접속을 끊거나 타임아웃이 될 때까지 연결이 유지된다.
Keep-Alive 지속 시간은 클라이언트와 서버 모두 가지고 있다. 한쪽이 TCP/IP 연결을 끊는 순간에 통신은 완료되므로 어느 쪽이든 짧은 쪽이 사용된다.
[2] 파이프라이닝(Pipelining)
기존에는 여러 요청을 보낼 때, 하나의 요청에 대한 응답이 끝냈을 때 다음 요청을 보냈다면, 파이프라이닝 기법은 첫번째 요청에 완료되기 이전에 다음 요청을 보내는 기술이다. 다음 요청까지의 대기 시간을 없앰으로써 네트워크 가동률을 높이고 성능을 향상시켰고, Communication latency을 낮췄다.
Keep-Alive 이용을 전제로 하며, 서버는 요청이 들어온 순서대로 응답을 반환한다.
로드밸런싱
은 서버에 가해지는 부하(=로드)를 분산(=밸런싱)해주는 장치 또는 기술을 말한다.클라이언트와 서버풀 사이에 위치하며, 한 대의 서버로 부하가 집중되지 않도록 트래픽을 관리해 각각의 서버가 최적의 퍼포먼스를 보일 수 있도록 한다.
로드밸런싱을 해주는 소프트웨어 혹은 하드웨어 장비를 로드밸런서라고 한다.
로드밸런서는 VIP(Virtual IP)와 함께 구성된다.
VIP
란 로드밸런싱의 대상이 되는 여러 서버들을 대표하는 가상의 IP이다. 클라이언트들을 서버에게 IP로 직접 요청 하는 것이 아니라 로드밸런서가 가지고 있는 VIP를 대상으로 요청을 한다. 그리고 로드밸런서는 설정된 부하 분산 방법에 따라 각 서버로 요청을 분산시키는 것이다.로드밸런싱의 주 목적은 서버 자원 사용의 최적화, 데이터 처리량의 증가, 클라이언트와 서버 간의 응답속도 감소, 특정 서버의 과부화 방지, 안정성 및 가용성 극대화 등을 고려하여 적절히 분산처리하여 해주는 서비스이다.
로드밸런싱은 여러 대의 서버를 두고 서비스를 제공하는 분산 처리 시스템에서 필요한 기술이다.
사업의 규모가 확장되고, 클라이언트의 수가 기하 급수적으로 늘어나면서, 그에 따라 증가된 트래픽을 대처하려면 어떻게 해야할까?
Scale-up
은 서버 자체의 성능을 확장하는 것을 의미한다. 서버에 CPU 또는 RAM을 추가하거나, 고성능의 부품을 교체할 때 쓰는 방법이다.
데이터베이스 서버
에 적합하다.Scale-out
은 서버를 여러 대 추가하여 시스템을 확장하는 방법이다.
웹 서버
에 적합하다.Scale-out 장점
하드웨어 향상하는 비용보다 서버 한대 추가 비용이 더 적다.
여러 대의 Server 덕분에 무중단 서비스를 제공할 수 있다.
여러 대의 서버에게 균등하게 트래픽을 분산시켜주는 역할을 하는 것이 로드밸런서
이다.
[1] 라운드 로빈 방식(Round Robin Method)
입력 받은 요청을 각각의 서버에 순차적으로 할당하는 방식이다.
클라이언트의 요청을 순서대로 분배하기 때문에 알고리즘이 단순하고 각 서버가 트래픽을 골고루 나눠서 처리하므로 각 서버의 처리량이 비슷한 경우에 쓰이는 기법이다.
[2] IP 해시 방식(IP Hash Method)
클라이언트의 IP 주소를 특정 서버로 매핑하여 요청을 처리하는 방식이다.
사용자의 IP를 해싱해 로드를 분배하기 때문에 클라이언트는 항상 동일한 서버로 접속하게 된다.
[1] 가중 라운드 로빈 방식(Weighted Round Robin Method)
각 서버별로 가중치를 설정하고 가중치가 높은 서버에 클라이언트 요청을 우선적으로 배분하는 방식이다.
주로 서버의 트래픽 처리 능력이 상이한 경우 사용되는 부하 분산 방식이다.
예) 클라이언트의 입력이 100이고, 각 서버 A, B, C의 가중치가 2,3,5라고 가정한다면 각 서버에는 20, 30, 50의 입력이 라운드 로빈 방식으로 전달된다.
[2] 최소 연결 방식(Least Connection Method)
요청이 들어온 시점에 가장 적은 연결 상태를 보이는 서버에 우선적으로 트래픽을 배분하는 방식이다.
세션이 자주 길어지거나, 서버에 분배된 트래픽들이 일정하지 않는 경우에 사용되는 방식이다.
[3] 최소 응답 시간 방식(Least Response Time)
클라이언트 요청을 전달하기 전에 각 서버에 응답을 요청하고 응답 시간이 가장 짧은 서버에 클라이언트 요청을 전달하는 방식이다.
각 서버의 성능이 상이한 경우에 사용되는 방식이다.
NAT(Network Address Translation) : 사설 IP 주소를 공인 IP 주소로 바꾸는 데 사용하는 통신망의 주소 변조기이다.
Tunneling : 인터넷상에서 눈에 보이지 않는 통로를 만들어 통신할 수 있게 하는 개념이다. 데이터를 캡슐화해서 연결된 상호 간에만 캡슐화된 패킷을 구별해 캡슐화를 해제할 수 있다.
DSR(Dynamic Source Routing protocol) : 로드밸런서 사용시 서버에서 클라이언트로 되돌아가는 경우 목적지 주소를 스위치의 IP 주소가 아닌 클라이언트 IP 주소로 전달해서 네트워크 스위치를 거치지 않고 바로 클라이언트를 찾아가는 개념이다.
L2 : Mac주소를 바탕으로 로드밸런싱을 한다.
L3 : IP주소를 바탕으로 로드밸런싱을 한다.
L4 : 전송계층(Transport Layer)에서 로드밸런싱을 한다. (TCP, UDP 포트 정보를 바탕으로 한다)
장점 : 데이터 안을 들여다보지 않고 패킷 레벨에서만 로드를 분산하기 때문에 속도가 빠르고 효율이 높다. L7 로드밸런서보다 가격이 저렴하다.
단점 : 패킷의 내용을 살펴볼 수 없기 때문에 섬세한 라우팅이 불가능하다. 사용자의 IP가 자주 바뀐다면 연속적인 서비스를 제공하기 어렵다.
L7 : 응용계층(Application Layer)에서 로드밸런싱을 한다. (TCP/UDP뿐만 아니라 HTTP, HTTPS, FTP의 파일명, 쿠키 정보를 바탕으로 한다)
장점 : 상위 계층에서 로드를 분산하기 때문에 더 섬세한 라우팅이 가능하며 캐싱 기능을 제공한다. 비정상적인 트래픽을 사전에 필터링 할 수 있어서 서비스 안정성이 높다.
단점 : 패킷의 내용을 복호화해야 하기에 L4 로드밸런서보다 더 높은 비용을 지불해야 한다.(가격이 더 비싸다) 그리고 클라이언트가 로드밸런서와 인증서를 공유해야하므로 해커가 로드밸런서를 통해서 클라이언트 데이터에 접근할 가능성이 있어서 보안상 위험성이 존재한다.
장애가 났을 경우의 시나리오
이중화된 로드밸런서들은 서로 Health Check를 한다.
메인 로드밸런서가 동작하지 않으면 가상 IP(VIP, Virtual IP)는 여분의 로드밸런서로 변경된다.
여분의 로드밸런서로 운영하게 된다.
프락시 서버
는 클라이언트와 서버 사이에 위치하여 그들 사이의 HTTP 메시지를 정리하는 웹 중개자 역할을 한다.요청 : 사용자가 웹 브라우저에서 도메인을 입력한다.
전달 : 사용자가 요청한 것을 캐시 역할을 하는 프록시 서버로 전달한다.
확인 : 프록시 서버 내에 도메인 홈페이지의 페이지를 가지고 있는지 확인한다.
가지고 있는 경우 - 홈페이지가 있는 서버에게 자신이 가진 페이지가 최신 버전인지 확인하고 필요한 경우 갱신할 부분만 가져온다.
가지고 있지 않는 경우 - 홈페이지가 있는 서버와 연결하여 페이지를 가져온다.
프락시
는 같은 프로토콜을 사용하는 둘 이상의 애플리케이션을 연결하고, 게이트웨이
는 서로 다른 프로토콜을 사용하는 둘 이상을 연결하며, 클라이언트와 서버가 서로 다른 프로토콜로 통신하더라도 서로 간의 트랜잭션을 완료할 수 있도록 도와준다.
하지만 실무에서는 프락시와 게이트웨이의 경계가 불분명하다.
프락시
는 브라우자와 서버가 다른 버전의 HTTP를 구현하는 경우 또는 상용 프락시
는 SSL 보안 프로토콜, SOCKS 방화벽, FTP 접근, 웹 기반 애플리케이션을 지원하는 경우 등 게이트웨이 기능을 구현하는 경우도 있으므로 사실상 차이를 논하기 모호하다.
프락시 서버는 실용적이고 유용한 서비스를 제공한다.
보안을 개선하고 성능을 향상하며, 비용을 절약해주고 트래픽 감시 및 수정이 가능하다.(모든 HTTP 트래픽에 접근이 가능하다)
위 그림에서 알 수 있듯이 프락시를 통해 필터링(제어) 를 중앙 집권적으로 해결할 수 있다.
프락시 서버는 어린이 필터, 문서 접근 제어, 보안 방화벽, 웹 캐시, 대리 프락시(리버스 프락시), 콘텐츠 라우터, 트랜스코더, 익명화 프락시 등에서 사용된다.
프락시 서버를 사용하지 않으면, 서버의 주소가 쉽게 노출되고, 다른 익명의 사용자가 서버로 접근하기가 쉽다.
이러한 문제점을 보완하기 위해 프락시 서버를 사용하여 중간에 경유하게 되면 서버의 IP를 숨기는 것이 가능하다.
프락시 서버를 방화벽으로 사용하기도 한다(프락시 방화벽)
방화벽
(firewall)은 보안 규칙에 기반하여 들어오고 나가는 네트워크 트래픽을 모니터링하고 제어하는 네트워크 보안 시스템이다. 신뢰할 수 있는 내부 네트워크와 신뢰할 수 없는 외부 네트워크 간의 장벽을 구성한다.
프락시 방화벽
은 세션에 포함되어 있는 정보의 유해성을 검사하는 역할로, 방화벽에서 세션을 종료하고 새로운 세션을 형성하는 방식이다.
출발지에서 목적지로 가는 세션을 가로채서 두 가지 세션으로 만든다(출발지에서 방화벽까지의 세션, 방화벽에서 목적지까지의 세션)
하나의 세션에서 다른 세션 정보를 넘겨주기 전에 검사를 수행하는 형식이다.
패킷 필터에 비해 많은 부하를 주어서 속도가 느리지만, 더 많은 검사 기능을 제공하고 프로토콜 변경 등 추가적인 수행이 가능하다.
프락시 캐시는 문서의 로컬 사본을 관리하고 해당 문서에 대한 요청이 오면 빠르게 제공하여, 느리고 비싼 인터넷 커뮤니케이션을 줄여준다. (전송시간 절약, 외부트래픽 감소)
웹 서버보다 웹 캐싱 프락시가 가깝다면 클라이언트는 가까운 웹 캐시의 문서에 접근한다.
포워딩 프락시(Forwarding Proxy)를 일반적으로 프락시라고 부른다.
클라이언트가 인터넷에 직접 접근하는 것이 아닌, 포워딩 프락시 서버가 클라이언트의 요청을 받고 인터넷에 연결한 이후에 그 결과를 클라이언트에게 응답한다.
예) 팬시(사용자)가 google.com
에 연결하고자 할 때, 프락시 서버가 팬시의 요청을 받아 google.com
에 연결하고 그 결과를 팬시에게 응답한다는 것이다.
포워딩 프락시는 캐시 기능이 있으므로 자주 사용하는 컨텐츠라면 성능을 향상시킬 수 있고, 정해진 사이트만 연결하게 설정하는 등 웹 사용 환경을 제한할 수 있으므로 보안이 매우 중요한 기업환경에서 많이 사용한다.
리버스 프락시
는 포워딩 프락시가 서버쪽에도 존재한다고 생각하면 된다.
클라이언트가 인터넷에 데이터를 요청하면 리버스 프락시가 이 요청을 받아 내부 서버에서 데이터를 받은 후 클라이언트에게 응답한다.
클라이언트는 내부 서버에 대한 정보를 알 필요 없이 리버스 프락시에게 요청하면 된다.
내부 서버가 직접 서비스를 제공할 순 있지만, 리버스 프락시를 사용하는 이유은 보안 때문이다.
기업의 네트워크 환경에서는 DMZ
라 불리는 내부 네트워크와 외부 네트워크 사이에 위치한 구간이 존재한다.
이 구간에 보통 메일 서버, 웹 서버, FTP 서버 등 외부 서비스를 제공하는 서버가 위치한다.
내부 서버(WAS)
에 직접 접근하게 되면 DB에 접근이 가능하므로 해킹 문제가 발생할 우려가 있다.
리버스 프락시 서버를 DMZ
에 두고 실제 서버는 내부망에 위치 시켜서 서비스 하는 것이 일반적이고 보안상 안전하다.
내부 서버를 설정하게 되면 로드 밸런싱이나 서버 확장에 유리한다.
SSL 암호화에 좋다. 원래 서버가 클라이언트와 통신을 할 때 SSL(or TSL)로 암호화, 복호화를 하면서 비용이 많이 들게 된다. 하지만 리버스 프락시
를 사용하면 들어오는 요청을 모두 복호화로 하고 나가는 응답을 암호화해주기 때문에 클라이언트와 안전한 통신을 할 수 있으며 본래의 비용보다 줄일 수 있다.