일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- JPA
- Spring
- gradle
- ansible
- AOP
- Collection
- 방화벽
- Pipeline
- 캐시서버
- Java
- IntelliJ
- STREAM
- post
- jdk
- tomcat
- 소켓
- container
- docker
- LAN어댑터
- DevOps
- Set
- 액세스회선
- mybatis
- 허브
- 라우터
- map
- sonarQube
- cloud
- Jenkins
- Linux
- Today
- Total
거북이-https://velog.io/@violet_evgadn 이전완료
캐시 서버 본문
프록시
◎ 프록시란?
캐시 서버에 대해 알아보기 전 "Proxy(프록시)"에 대해 알아볼 필요가 있다.
사실상 프록시라는 개념에 의하여 "캐시"라는 기능이 나왔으며, 이 캐시 기능을 활용한 서버가 캐시 서버이기 때문이다.
Proxy를 직역하면 "대리"라는 의미를 가진다.
이런 직역을 네트워크로 가져온다면 네트워크의 동작 과정 중 어떤 기기가 수행하는 동작을 대신해 주는 주체정도로 이해할 수 있을 것이다.
네트워크에서의 "프록시"란 웹 서버와 클라이언트 사이에 들어가서 웹 서버에 대한 액세스 동작을 중개하는 역할 구조를 말한다.
프록시는 액세스를 중개하는 역할을 함과 동시에 웹 서버에서 받은 데이터를 디스크에 저장해 두고 웹 서버를 대신하여 데이터를 클라이언트에 반송하는 기능 또한 가지고 있는데 이를 "캐시"라고 하며, 이 캐시를 사용하는 서버를 "캐시 서버"라고 하는 것이다.
프록시의 종류에는 클라이언트 쪽 설정을 수행하는 "포워드 프록시", 서버 쪽에 설정을 수행하는 "리버스 프록시", 그리고 두 개를 결합한 "트랜스페어런트 프록시"가 존재한다.
◎ 포워드 프록시
프록시라는 구조의 원형은 "포워드 프록시"로써 현재 네트워크에서 활용하는 프록시의 원조라고 할 수 있다.
포워드 프록시가 처음 등장했을 때 캐시를 이용한다는 목적도 있었으나 방화벽을 실현한다는 중요한 목적이 또 하나 존재했다.
방화벽의 목적은 인터넷으로부터의 부정 침입을 막는 것으로 제어 정보를 조사하여 패킷을 통과시키거나 차단시킨다.
방화벽의 목적을 간단하고 완벽히 달성시키기 위한 방법은 인터넷과 사내 LAN 사이를 통과하는 모든 패킷을 차단시키는 것이지만 인터넷을 안전히 사용하기 위하여 인터넷을 사용하지 못하는 상황이 발생한다.
차 사고를 내지 않고 조심히 운전하기 위하여 차를 없애버리는 것과 동일한 것이다.
프록시는 "대리"라는 뜻을 가진 만큼 본래의 클라이언트(유저 컴퓨터)를 대신하여 웹 서버에 액세스 하는 것이다.
프록시는 액세스 한 페이지 정보들을 자체적으로 저장해 놓는 캐시 기능을 가지고 있다.
따라서 이전에 액세스 한 페이지를 다시 접속할 경우 프록시에 액세스한 뒤 캐시 정보를 검색하여 저장된 정보를 받아오면 저속 회선에서 인터넷에 액세스 하는 것보다 훨씬 빠른 응답 시간을 가질 것이다.
프록시는 방화벽과 다르게 리퀘스트의 내용까지 조사한 뒤 전송한다.
즉, 위험한 사이트나 작업과 관계없는 사이트에 액세스 하려 한다면 프록시에서 리퀘스트 내용을 검사한 뒤 위험한 패킷 송신을 금지하는 보안적 조치도 수행할 수 있다.
이러한 점에서 포워드 프록시는 "캐시 저장을 통한 액세스 고속화"와 "URL 필터링"이라는 장점을 가지고 있다는 것을 알 수 있다.
포워드 프록시에 대한 개념은 위와 같다.
이러한 포워드 프록시에서 신경 써야 할 것은 "클라이언트가 어느 포워드 프록시에 연결될 것인가"이다. 이 세상에는 포워드 프록시가 매우 많이 존재할텐데 이 중 클라이언트가 어떤 프록시 서버를 통해 패킷을 보낼지에 따라 동작 과정도 살짝씩 달라지기 때문이다.
포워드 프록시의 경우 보통 클라이언트가 브라우저의 설정 화면에 준비되어 있는 "프록시 서버" 항목에서 사용할 포워드 프록시의 IP 주소를 직접 설정한다.
(윈도우 10의 경우 [Windows 메뉴] > [설정] > [네트워크와 인터넷] > [프록시]에서 설정할 수 있음)
그리고 이렇게 사용자가 직접 포워드 프록시를 설정하면 브라우저의 리퀘스트 메시지 송신 동작 또한 약간 달라진다.
먼저 이전에 배웠던 포워드 프록시를 활용하지 않을 경우의 리퀘스트 메시지 송신 동작을 잠깐 살펴보자.
브라우저는 리퀘스트 메시지를 만들 텐데 이 중 가장 중요한 부분은 리퀘스트 메시지의 첫 번째 줄인 리퀘스트 라인이다.
여기에는 HTTP Method, URI, 그리고 HTTP Version을 입력한다.
이때 포워드 프록시를 사용하지 않을 경우 브라우저는 URL 문자열을 통해 액세스 대상의 웹 서버를 계산한 뒤 URI 부분에 웹 서버의 이름을 제외한 파일이나 프로그램의 경로명을 추출하여 기록한다.
예를 들어 "http://www.sample.com/dir/sample1.html"에 접근할 경우 먼저 "http://www.sample.com"을 통해 메시지를 보낼 목적지를 확인하고 URI 부분에 "/dir/sample1.html"을 기록하는 것이다.
하지만 포워드 프록시를 사용할 경우 URL에 상관없이 무조건 포워드 프록시로 리퀘스트 메시지를 보낸다.
또한 포워드 프록시도 어떤 URL에 요청을 보낼지 알아야 하기 때문에 입력한 URL을 그대로 리퀘스트의 URI 부분에 입력하게 된다.
즉, "http://www.sample.com"에 요청을 보내든 "http://blog.test.com"에 요청을 보내든 무조건 프록시 서버로 리퀘스트 메시지를 보낼 것이며, "http://www.sample.com/dir/sample1.html"에 접근할 경우 URI 부분에 "/dir/sample1.html"이 아닌 "http://www.sample.com/dir/sample1.html" 값을 저장한다는 것이다.
또한 나중에 배우겠지만 서버 측에 두는 캐시는 미리 설정해 둔 웹 서버에만 패킷을 전송할 수 있다.
하지만 포워드 프록시를 사용할 경우 포워드 프록시에 전달된 리퀘스트 메시지에 URL 전체가 적혀 있으므로 모든 웹 서버에 메시지를 전송할 수 있는 것이다.
◎ 리버스 프록시
리버스 프록시란 포워드 프록시와 달리 웹 서버 쪽에 위치하며 클라이언트의 접근을 최초로 받아 리퀘스트에 해당하는 웹 서버에 배분해 주는 역할을 한다.
이 리버스 프록시가 이후 설명할 캐시 서버와 비슷한 개념이라고 생각하면 된다.
그렇다면 왜 포워드 프록시가 존재함에도 불구하고 서버 쪽에 설치하는 리버스 프록시라는 개념이 나왔을까?
포워드 프록시는 브라우저에서 포워드 프록시에 대한 설정을 꼭 수행해야 한다는 특징을 가진다.
그런데 포워드 프록시를 브라우저에서 직접 설정해야 할 경우 설정 방법이 번거롭기도 하고 설정이 잘못되었을 경우 브라우저가 제대로 동작하지 않는 장애의 원인이 되기도 한다.
또한 클라이언트는 DNS 서버에서 검색한 값을 통해 어떤 웹 서버에 접속하는지 알 수 있지만 인터넷에 공개된 웹 서버는 어떤 클라이언트가 액세스 하는지 알 수 없다. 즉, 포워드 프록시를 사용할 경우 웹 서버는 어떤 곳으로 응답 메시지를 보내야하는지 알 수 없는 것이다.
게다가 웹 서버 브라우저에 프록시를 설정할 수도 없다.
이러한 제약 조건 때문에 웹 서버 바로 앞에 프록시를 두는 포워드 프록시를 사용하지 않는다.
대신 브라우저에서 프록시를 설정하지 않아도 프록시를 사용할 수 있도록 개량되었는데 이것이 "리버스 프록시"이다.
리버스 프록시에서는 리퀘스트 메시지의 URI에 쓰여 있는 디렉토리명과 전송 대상의 웹 서버를 대응시켜 URI 부분에 URL 전체 경로가 적혀 있지 않은 보통의 리퀘스트 메시지를 전송할 수 있도록 했다.
리버스 프록시에선 URI에 쓰여 있는 디렉토리명만으로 분산된 웹 서버에 패킷을 송신할 수 있어야 하므로 접속하고 있는 웹 서버에 대한 정보가 미리 등록되어 있어야 한다.
또한 유저는 웹 서버가 아닌 리버스 프록시에 요청을 보내기 때문에 웹 서버 대신 리버스 프록시를 DNS 서버에 등록시켜 놔야 한다.
리버스 프록시를 사용할 경우 3가지 장점이 존재한다.
먼저 웹 서버에 대한 부담이 분산된다.
설정을 통해 정적 페이지를 반환해야 하는 동작과 동적 페이지를 반환해야 하는 동작을 나눔으로써 메모리 사용량의 효율화를 할 수 있다. 이를 로드 밸런서와 병용할 경우 부담을 더욱 분산시킬 수 있다.
두 번째로 리버스 프록시도 포워드 프록시와 동일하게 캐시를 저장하므로 이전에 방문했던 페이지에 대한 데이터를 캐시 정보로 반환함으로써 빠르게 응답할 수 있다.
마지막으로 보안성이 좋아진다.
유저가 웹 서버에 접속하기 위해선 결국 리버스 프록시 서버에 패킷이 집중될 것이다.
따라서 리버스 프록시 쪽에 시큐리티 설정이나 바이러스 대책 등을 구현한다면 웹 서버로 오는 악의적인 공격용 패킷을 미리 차단할 수 있는 것이다.
정리하자면 리버스 프록시는 "인터넷 뒤에" 존재하는 프록시 서버, 포워드 프록시는 "인터넷 앞에" 존재하는 프록시 서버이다. 아래 사진은 이를 매우 잘 나타내는 이미지라고 생각하여 가져왔다.
◎ 트랜스페어런트 프록시
어떤 곳에서는 Transparent Proxy와 Forward Proxy(포워드 프록시)를 동일한 개념으로 보기도 한다.
엄밀히 따지자면 다른 개념이지만, 여기서 우리는 트랜스페어런트 프록시 또한 "클라이언트 측에 설치되는 프록시"라는 것 정도는 이해하고 갈 수 있다.
포워드 프록시에선 리퀘스트 메시지 URI 값으로 전체 URL을 기록함으로써 프록시 서버 측에서 웹 서버의 위치를 찾았다.
하지만, 생각해 보면 이 과정이 필수적인가에 대한 의문이 들 수 있다.
패킷의 수신지 IP 주소는 DNS 검색을 통해 알 수 있으며 수신지 포트 번호 또한 이미 클라이언트 측에서 알아낸 뒤 헤더에 저장해 놓을 텐데 굳이 포워드 프록시에서 웹 서버의 위치를 다시 찾아야 하는 과정이 필요할까?
실제로 프록시 서버에서 리퀘스트 메시지를 저장한 패킷의 헤더 값을 통해 전송 대상을 판단하는 방법이 존재한다.
그리고 패킷 IP 헤더 중 수신처 IP 주소를 통해 액세스 대상 웹 서버 위치를 파악하는 프록시 서버를 "트랜스페어런트 프록시"라고 한다.
트랜스페어런트 프록시는 포워드 프록시와 리버스 프록시의 장점만 모아둔 편리한 구조의 프록시이다.
이 방법을 사용한다면 포워드 프록시처럼 리퀘스트 메시지에 전체 URL을 기록할 필요가 없으며 이 때문에 URI 부분에 경로만 적혀 있는 보통의 리퀘스트 메시지를 전송할 수 있으므로 포워드 프록시처럼 브라우저에 프록시 서버를 설정할 필요가 없다.
또한 리버스 프록시처럼 전송 대상을 캐시 서버에 설정할 필요 없이 어느 웹 서버에서나 리퀘스트를 전송할 수 있다.
단지 트랜스페어런트 프록시를 사용할 경우 리퀘스트 메시지 전달 방식에 주의해야 한다.
트랜스페어런트 프록시는 브라우저에서 프록시의 위치를 지정하지 않다.
이 때문에 포워드 프록시와는 다르게 브라우저는 바로 웹 서버에 리퀘스트 메시지를 보낼 것이다. 즉, 트랜스페어런트 프록시로 리퀘스트 메시지를 보낸후 프록시 서버에서 대신 웹 서버로 송신하는 과정이 생략되는 것이다.
리버스 프록시와 마찬가지로 트랜스페어런트 프록시의 IP 주소를 DNS 서버에 미리 등록해 놓았다면 리퀘스트 메시지가 프록시 서버에 도착할 수 있겠지만 트랜스페어런트 프록시는 동작 구조상 DNS 서버에 등록할 수 없다.
만약 DNS 서버에 트랜스페어런트 프록시를 등록하여 그 곳에 패킷을 보낼 경우 프록시 서버가 액세스 대상이 되어 수신처 IP 주소 값으로 트랜스페어런트 프록시 IP 주소가 설정될 것이다.
이렇게 될 경우 트랜스페어런트 프록시는 수신처 IP 주소를 통해 전송 대상 웹 서버의 IP 주소를 판단할 수 없을 것이다.
이런 문제를 해결하기 위해 웹 서버로 리퀘스트 메시지가 흘러가는 경로에 트랜스페어런트 프록시를 설치한다.
그리고 메시지가 트랜스페어런트 프록시를 통과할 때 프록시 서버에서 이를 가로채는 것이다.
이런 방법을 채택하므로 만약 웹 서버로 가는 경로가 많다면 이 모든 경로에 트랜스페어런트 프록시를 설치해야 할 것이다.
따라서 트랜스페어런트 프록시를 채택한 경우 길이 한 개로 수렴하는 형태로 네트워크를 만든 뒤 수렴되는 곳에 트랜스페어런트 프록시를 설치하는 것이 보통이다.
인터넷에 연결하는 액세스 회선 부분이 이런 형태로 되어 있으므로 액세스 회선 부분에 설치해도 된다.
트랜스페어런트 프록시를 사용할 경우 사용자가 프록시의 존재에 대해 인지할 필요성이 거의 없다.
따라서 HTTP 메시지를 전송하는 구조에 대한 관심이 적어지고 캐시를 이용해 빠른 처리가 가능하다는 측면에서 비중이 높아지고 있는 프록시 서버이다.
캐시 서버
◎ 캐시 서버를 통한 부하 분산
이제는 "부하 분산"이라는 측면에서 캐시 서버를 활용하는 방법에 대해 알아보자.
부하를 분산할 때 이전에 설명한 것처럼 같은 기능을 가지고 있는 여러 대의 서버를 설치하는 방법도 존재하지만 역할에 따라 서버를 나누어 부하를 분산하는 방법도 존재한다.
데이터베이스 서버, 웹 서버와 같이 맡은 역할에 따라 서버를 나누는 방법이 있으며 이러한 역할별 분산 처리 방법 중 하나가 "캐시 서버"를 이용하는 방법이다.
캐시 서버는 프록시 구조를 사용하여 데이터를 캐시에 저장하는 서버이다.
프록시에 대해선 위에 설명했으며, 프록시 서버에서 액세스 동작을 중개할 때 웹 서버에서 받은 데이터를 디스크에 저장해 두었다가 동일한 액세스 동작을 수행할 경우 저장한 데이터를 반송하는 기능을 "캐시"라고 한다.
그리고 캐시 서버는 이러한 캐시 기능을 이용하는 서버이다.
웹 서버에서 리퀘스트를 처리할 때는 URL 점검, 액세스 권한 점검, 페이지 내의 데이터 처리 등을 수행하므로 요청을 받은 뒤 클라이언트에게 응답 데이터를 보내기까지 다소 시간이 걸린다.
캐시 서버는 이와 달리 웹 서버에서 받은 뒤 저장했던 데이터를 그대로 클라이언트 측에 보내기만 하면 되므로 훨씬 빠르게 응답 데이터를 보낼 수 있다.
단지 캐시에 데이터를 저장했더라도 웹 서버 측에서 데이터가 변경되었다면 기존에 저장했던 캐시 데이터를 사용할 수 없다.
또한 CGI 애플리케이션 등이 출력하는 동적 페이지 데이터도 내용이 매번 달라지므로 캐시를 이용할 수 없다.
따라서 언제든 캐시 데이터를 이용할 수 있는 것은 아니다.
하지만 캐시 서버를 사용한다면 액세스 동작의 일정 부분은 웹 서버를 번거롭게 하지 않고 캐시 서버에서 처리할 수 있다.
캐시 서버를 통해 조금이라도 액세스 동작을 고속화할 수 있다면 이는 곧 전체 성능 향상과 동일하다고 생각하는 것이다.
또한 캐시 서버에서 리퀘스트를 처리하면 그만큼 웹 서버의 부하가 줄면서 웹 서버의 처리 시간을 단축할 수도 있다.
◎ 캐시 서버 동작 - 사전 작업
동작에 대해 배우기 전 "캐시 서버"라고 해서 새로운 개념인 것 같지만 그냥 "리버스 프록시 서버"라고 생각하고 이해해도 전혀 지장이 없다는 점을 알고 가자.
캐시 서버를 사용할 때도 부하 분산 장치를 사용하는 것과 마찬가지로 웹 서버 대신 캐시 서버를 DNS 서버에 등록한다.
일단 사용자는 DNS 서버에 등록된 IP 주소로 리퀘스트 메시지를 보낼 것이므로 캐시 서버가 메시지를 받을 것이다.
이때의 수신 동작은 웹 서버의 수신 동작과 같다.
웹 서버의 수신 동작은 뒤에서 배울 텐데, 접속을 기다리는 패킷을 만든 뒤 여기에 사용자가 접속하면 접속 동작을 실행하여 리퀘스트 메시지를 수신받는다 정도로만 알고 있자.
리퀘스트 메시지를 받은 캐시 서버는 리퀘스트 메시지 내용을 조사하고 해당하는 데이터가 자신의 캐시에 저장되었는지 조사한다.
이후의 동작은 캐시에 저장되어 있는 경우와 저장되어 있지 않은 경우가 다르기 때문에 따로 설명하겠다.
◎ 캐시 서버 동작 - 캐시 서버에 데이터가 저장되어 있지 않은 경우
캐시 서버에 데이터가 없을 경우 캐시 서버는 리퀘스트 메시지에 캐시 서버를 경유했음을 나타내는 헤더 필드를 추가한다.
추가한 헤더 필드는 "Via"이며 이 헤더 필드를 추가한 리퀘스트 메시지를 웹 서버 측에 보낸다.
Via 헤더 필드는 어디까지 캐시 서버를 경유했다는 사실을 웹 서버에 알리기 위한 것으로 그다지 중요한 값은 아니며 캐시 서버 설정에 따라 Via 헤더 필드를 붙이지 않는 경우도 있다.
리퀘스트 메시지에 "Via" 헤더 필드를 붙였다면 이젠 연결된 웹 서버 중 어느 웹 서버에 리퀘스트 메시지를 전송해야 할지 판단해야 한다.
캐시 서버와 연결된 웹 서버가 한 대밖에 없으면 웹 서버의 도메인명이나 IP 주소를 캐시 서버에 설정해 둔 뒤 무조건 거기에 전송하는 방법을 취한다.
하지만 네트워크에서 캐시 서버를 사용할 경우 대부분 1대의 캐시 서버에 여러 대의 웹 서버를 연결시켜 놓는다.
이 경우 여러 대의 서버 데이터를 1대의 캐시에서 저장해야 하므로 조금 더 고도화된 방법이 필요하다.
이 방법은 몇 가지 존재하는데, 대표적으로 리퀘스트 메시지의 URI에 쓰여 있는 디렉터리를 보고 판단하는 방법이 있다.
이는 위에서 리버스 프록시를 설명할 때 잠깐 이미지로 나왔는데, 다시 그 이미지를 확인해 보자.
위 이미지처럼 캐시 서버(리버스 프록시)에 미리 설정을 통해 URI에 따른 전송 대상 웹 서버를 설정해 놓는다.
이후 캐시 서버에 리퀘스트가 도착했다면 캐시 서버는 미리 설정되어 있는 설정값을 통해 전송 대상을 판단하여 리퀘스트 메시지를 전송한다.
이 과정은 어려운 것은 아니고 클라이언트와 웹 서버가 직접 TCP 커넥션을 생성하여 패킷을 주고받는 과정과 동일하다.
단지 클라이언트의 역할을 캐시 서버가 대신 수행할 뿐이다.
이후 웹 서버 입장에서는 실제로 리퀘스트를 보낸 대상이 캐시 서버이기 때문에 요청에 대해 처리한 응답 메시지를 캐시 서버에게 보낼 것이다.
캐시 서버가 응답 메시지를 받았다면 리퀘스트 메시지를 받았을 때와 동일하게 캐시 서버를 경유했음을 나타내는 "Via" 헤더 필드를 부가한다.
이후 클라이언트와 캐시 서버를 대상으로 보았을 때는 캐시 서버가 웹 서버의 역할을 하기 때문에 웹 서버가 해야 할 응답 메시지를 전송하는 역할을 대신 수행한다.
마지막으로 응답 메시지를 캐시에 저장한 뒤 저장한 일시를 기록하면 캐시 서버에 데이터가 저장되어 있지 않은 경우의 캐시 서버 동작이 종료된다.
◎ 캐시 서버 동작 - 캐시 서버에 데이터가 저장되어 있는 경우
이젠 캐시 서버에 데이터가 저장되어 있는 경우의 캐시 서버 동작을 살펴보자.
캐시 서버에 데이터가 존재한다면 캐시 서버는 웹 서버 측에 데이터가 변경되었는지 조사하기 위해 "If-Modified-Since"라는 헤더 필드를 추가하여 웹 서버에 전송한다.
위에서 응답 메시지를 캐시에 저장할 때 저장한 일시를 같이 기록한다고 설명했다.
이때 데이터와 같이 저장한 저장 일시를 "If-Modified-Since" 헤더 필드 값으로 설정하여 웹 서버에 전송하는 것이다.
이후 웹 서버는 "If-Modified-Since" 헤더 필드의 값과 데이터 최종 갱신 일시를 비교하여 데이터 최종 갱신 일시가 더 빠르다면 변경이 없다는 것을 나타내는 응답 메시지를 반송한다.
응답 메시지의 첫 줄에 "304 Not Modified"라는 응답 코드 및 응답 문구를 통해 변경이 없음을 알릴 수 있다.
웹 서버 입장에서는 데이터의 최종 갱신 일시와 If-Modified-Since 헤더 필드 값만 비교하면 되므로 페이지 데이터 전체를 응답으로 보내는 것보다 훨씬 부담이 적어지며 보낼 패킷의 길이 또한 짧아질 것이다.
응답 메시지가 캐시 서버에 도착하면 캐시 서버는 캐시에 저장된 데이터가 최신 데이터와 동일하다는 것을 알 수 있다.
따라서 캐시 서버는 캐시에서 데이터를 추출해 사용자에게 보낸다.
만약 웹 서버 측 데이터가 변경된 경우 캐시에 저장된 데이터가 유효하지 않은 데이터라는 의미이다.
따라서 웹 서버는 최신 데이터를 캐시 서버로 반송할 것이며 이후 동작은 캐시 서버에 데이터가 없는 경우의 동작과 동일하다.
'CS 지식 > 네트워크' 카테고리의 다른 글
서버 (0) | 2023.03.30 |
---|---|
콘텐츠 배포 서비스 (0) | 2023.03.30 |
부하 분산 (0) | 2023.03.28 |
방화벽 (0) | 2023.03.28 |
웹 서버 설치 장소 (0) | 2023.03.27 |