애플리케이션이 화폐인 경제에서는 가용성이 중요한 문제입니다. 응답하지 않는 앱은 즉시 삭제되고 Yelp의 부정적인 리뷰처럼 빠르게 인터넷에 비난의 화살이 쏠립니다.
인터넷이 처음 생겨난 이래로 기업들은 24시간, 365일 애플리케이션(예전에는 웹사이트)을 사용할 수 있도록 노력해 왔습니다. 인터넷은 잠들지 않고, 휴가도 가지 않고, 병가도 내지 않습니다.
이러한 필요성(실제로는 요건)에 부응하기 위해 가용성을 제공하는 최초의 애플리케이션 서비스 중 하나로 확장성이 부상했습니다. 가용성 요구 사항을 충족하는 가장 눈에 띄고 잘 이해되는 애플리케이션 서비스는 로드 밸런싱입니다.
그러나 이 핵심 기술을 사용하여 구현할 수 있는 부하 분산에는 다양한 형태가 있으며 확장성 패턴도 있습니다. 오늘은 앱과 인터넷을 24시간 연중무휴로 온라인 상태로 유지하는 데 사용되는 상위 5가지 확장성 패턴을 강조해 보겠습니다.
GSLB는 정말 잘못된 이름입니다. 실제로 서버 부하 분산이 중요한 것이 아니라, 사이트 가용성이 중요한 것입니다. 오늘날 이는 앱 가용성에도 확대되고 있습니다.
GSLB는 한 데이터 센터(클라우드 또는 기존 데이터 센터)가 응답하지 않을 경우 다른 데이터 센터를 찾을 수 있는 수단입니다. GSLB는 도메인이나 호스트 수준에서 적용될 수 있습니다. 따라서 이것을 사용하면 api.example.com 뿐 아니라 example.com도 위치 간에 전환할 수 있습니다.
가장 기본적인 GSLB는 기본적인 DNS 기반 부하 분산을 사용합니다. 즉, 도메인이나 호스트와 연관된 IP 주소 목록이 있고, 첫 번째 주소를 사용할 수 없으면 요청은 목록의 두 번째 주소로 전송됩니다. 아니면 세 번째, 네 번째 주소 등으로 전송됩니다.
이 과정에는 두 단계가 있습니다.
1단계에서 내린 결정에는 일반적으로 지능이 없습니다. 이는 주어진 사이트가 응답하는지 여부에 따라 엄격하게 결정됩니다. 하지만 이렇게 하면 클라우드, 호스팅 제공자, 온프레미스 등 여러 위치를 사용하여 가용성을 보장할 수 있습니다. 다양한 지리적 지역에 전략적으로 위치를 선택하면 자연 재해나 인터넷 중단의 영향을 피할 수 있습니다.
하지만 그것은 DR(재해 복구) 또는 BC(비즈니스 연속성) 시나리오에 더 가깝습니다. 지리적 위치 및 애플리케이션 성능과 같은 더욱 스마트한 GSLB 애플리케이션 서비스를 활용하는 사람들도 있습니다. 사이트 A의 앱 성능이 좋지 않다면 문제가 해결될 때까지 방문자를 사이트 B로 보내는 것이 좋습니다. 아니면 성능 개선을 위해 사용자를 지리적으로 가장 가까운 위치로 안내하고 싶을 수도 있습니다(여전히 빛의 속도는 규칙이며 거리는 앱 성능에 영향을 미치기 때문입니다).
어떤 방식으로 결정을 내리든 기본 패턴은 동일하게 유지됩니다. GLSB는 사용 가능한 사이트 중 하나의 IP 주소를 반환하여 물리적으로 분리된 여러 사이트에 요청을 분산시킵니다. API든 앱이든 GSLB는 최상위 수준의 가용성 보장 패턴입니다.
POLB(Plain Old Load Balancing)는 표준 TCP 기반 부하 분산을 설명하는 데 사용하는 용어입니다. 이 패턴을 사용하면 앱을 복제하고 클라이언트(사용자, 기기)와 앱 사이에 연결이 이루어지도록 하여 간단히 가용성을 달성할 수 있습니다.
로드 밸런서(또는 선호하는 경우 프록시)는 연결 요청을 받고, 사용 가능한 앱 인스턴스를 선택하고, 연결을 전달합니다. 로드 밸런서가 적극적으로 참여하는 마지막 시간입니다. 이는 두 동료의 만남을 주선하는 '소개 이메일'과 같습니다. 당신은 초기 거래에 적극적으로 참여하지만, 이후 신용 카드 라인으로 이동하고 일반적으로 더 이상 참여하지 않습니다.
POLB라는 용어를 사용하는 이유는 요청을 어떻게 전달할지 선택하는 데 알고리즘 외에는 아무것도 관련되지 않기 때문입니다. 불행히도, 요청을 배포하는 데 사용되는 알고리즘에 따라 많은 문제가 발생할 수 있습니다. 예를 들어, 라운드 로빈은 용량이나 성능에 관심이 없습니다. 그냥 "다음 앱"을 선택하고 요청을 실행합니다. "최소 연결"을 선택하면 리소스를 로드하여 성능에 빠르게 영향을 미칠 수 있지만 다른 방법은 더 빠를 수 있습니다. 알고리즘 선택은 가용성을 유지하는 데 중요한 구성 요소가 됩니다.
POLB는 컨테이너 환경 내부와 많은 클라우드 기반 로드 밸런싱 서비스의 기본 로드 밸런싱 방법입니다.
3계층 애플리케이션의 현실 중 하나는 일반적으로 상태가 있다는 것입니다. 즉, 애플리케이션 작동에 중요한 요청과 응답 간의 정보를 저장한다는 의미입니다. 쇼핑 카트, 자격 증명, 상태, 마지막으로 방문한 페이지, 프로세스의 어느 단계에 있는지는 모두 "세션"의 일부로 저장되는 사소한 정보입니다. 문제는 3계층 프레임워크를 사용하여 개발된 많은 앱이 해당 세션을 데이터베이스가 아닌 애플리케이션이나 웹 서버에 저장한다는 것입니다. 즉, 서버에 연결되면 모든 정보를 사용할 수 있는지 확인하기 위해 해당 서버로 계속 돌아가야 한다는 뜻이었습니다.
로드 밸런서는 다양한 방법으로 지속성을 구현했으며, 가장 인기 있는 것은 쿠키 기반 방식입니다. 세션 ID는 쿠키에 저장되어 로드 밸런서에서 요청이 올바른 서버에 전달되었는지 확인하는 데 사용되었으며, 알고리즘 선택 프로세스를 효과적으로 우회했습니다.
쇼핑객이 보안을 느끼는 데 SSL/TLS를 사용하는 것이 중요한 요구 사항이 되면서, 동일한 문제가 발생했습니다. SSL/TLS는 클라이언트와 특정 앱 서버 간의 보안 세션을 가능하게 합니다. 대화의 양측이 해당 연결을 통해 교환되는 데이터를 해독하고 사용할 수 있도록 하려면 로드 밸런서는 클라이언트 요청을 시작된 서버로 전송할 수 있어야 합니다. 세션 기반 지속성을 가능하게 하는 동일한 기술을 사용하여 로드 밸런서는 SSL/TLS 기반 지속성을 지원할 수 있었습니다.
어떤 유형의 지속성을 사용하든 패턴은 동일합니다. 세션이 이미 설정되었다는 표시가 있으면 로드 밸런서는 기존 연결을 존중하고 사용자 세션이 지속되는 동안 연결이 유지되도록 합니다. 그렇지 않은 경우, 로드 밸런서는 구성 및 알고리즘을 기반으로 리소스를 선택하고 연결을 설정합니다.
이는 부하 분산 알고리즘을 선택할 때 용량 계획에 영향을 미칩니다. 이 시나리오에서는 최소 연결 방식이 좋은 선택입니다. 진행 중인 세션으로 인해 단일 리소스에 과부하가 걸리는 반면 다른 리소스는 유휴 상태로 유지되는 것을 방지하기 때문입니다. 다른 알고리즘을 사용하면 단일 리소스가 동시에 많은 사용자 세션을 유지할 가능성이 있으며, 이는 해당 서버로 연결된 모든 사용자의 성능에 부정적인 영향을 미칩니다.
호스트 기반 부하 분산은 가장 흔하고 널리 지원되는 확장성 패턴 중 하나입니다. 모든 웹 서버는 동시에 여러 호스트로 위장할 수 있는 기능을 지원하므로 이 기능을 구현하는 데 로드 밸런서가 필요하지 않다고 생각할 수도 있습니다. 하지만 그럴 수도 있죠. 웹/앱 서버는 여러 가상 서버를 호스팅할 수 있지만 반드시 각 서버 간에 로드 밸런싱을 수행하지는 않습니다. 그래서 확장을 위해서는 로드 밸런서가 필요합니다. 질문은 로드 밸런서가 호스트를 분리할 것인지, 아니면 웹/앱 서버에 맡길 것인지입니다.
웹/앱 서버 지시문을 사용하든 외부 로드 밸런서를 사용하든 흐름은 동일하게 유지됩니다. 요청이 대상(로드 밸런서 또는 웹/앱 서버)에서 이루어지고 수신됩니다. 그런 다음 대상 서버는 HTTP 헤더를 검사하고 호스트 값을 찾은 후 해당 가상 서버로 요청을 전달합니다.
로드 밸런서를 사용하여 호스트를 분할하는 이점은 호스트를 기준으로 도메인을 분리하고 개별적으로 확장할 수 있다는 것입니다. 이 방법이 더 효율적이며 애플리케이션을 확장하는 데 필요한 서버(하드웨어 및 소프트웨어) 수를 줄일 수 있습니다. 또한, 각 호스트 서버가 특정 시간에 처리할 수 있는 부하를 더 잘 예측할 수 있으므로 용량 계획이 더 쉬워집니다.
그 이유는 비즈니스 로직을 호출하는 데 필요한 컴퓨팅 요구 사항이 이미지를 요청하는 데 필요한 컴퓨팅 요구 사항과 동일하지 않기 때문입니다. 동일한 확장성 도메인에서 호스트를 섞어서 일치시키면 부하가 불안정해지고 용량이 예측 불가능해집니다. 일반적인 로드 밸런싱을 제공하기 위해 로드 밸런서를 사용하기로 선택한 경우, 웹/앱 서버는 호스트를 분리하고 적절한 가상 서버로 요청을 전송해야 합니다. 이 접근 방식의 또 다른 단점은 공유 인프라의 특성으로 인해 버전 충돌과 패치, 앱 업데이트로 인해 가상 서버 간에 마찰이 발생할 가능성이 있다는 것입니다.
컨테이너와 마이크로서비스의 채택이 확대됨에 따라 인그레스 컨트롤러 형태의 호스트 기반 부하 분산 사용이 확대되고 있습니다.
제가 가장 좋아하는 방식은 7계층(HTTP) 부하 분산입니다. 다재다능함(민첩성?)이 뛰어나거든요. 페이로드를 포함하여 HTTP를 기준으로 요청의 부하를 분산할 수 있습니다. 대부분의 사람들은 (제 생각에 현명하게도) HTTP 헤더에서 찾을 수 있는 내용으로 부하 분산 규칙을 제한합니다. 여기에는 호스트, HTTP 메서드, 콘텐츠 유형, 쿠키, 사용자 정의 헤더, 사용자 에이전트 등이 포함됩니다.
HTTP 부하 분산은 먼저 라우팅에 관한 것이고 그 다음에 부하 분산에 관한 것입니다. 일반적인 HTTP 부하 분산 패턴은 경로 -> 분배 형태를 취합니다. 즉, 먼저 요청을 어느 가상 서버로 보낼지 결정한 다음 알고리즘을 통해 해당 가상 서버를 지원하는 풀에서 리소스를 선택합니다.
HTTP 부하 분산을 사용하면 API 버전이 URI(또는 사용자 지정 HTTP 헤더)에 포함되는 API 버전 관리와 같은 패턴을 사용할 수 있습니다. 로드 밸런서는 버전을 분리하고 클라이언트가 실행을 위해 올바른 백엔드 서비스로 전송되도록 보장할 수 있습니다. 강제 업그레이드가 불가능한 상황에서도 클라이언트를 항상 우아하게 마이그레이션합니다.
이러한 유형의 확장성 패턴은 기능 분해 및 데이터 분할과 같은 다른 확장성 패턴도 지원합니다. 이는 믹스에서 가장 견고하고 민첩한 확장성 패턴이며 앱과 점점 더 늘어나는 마이크로서비스를 확장할 때 광범위한 옵션을 허용합니다.
요약하자면, 우리는 5가지 주요 확장성 패턴을 얻었으며, 이 중 대부분은 (종종 결합되어) 가장 효율적인 리소스 사용과 가능한 최고의 성능을 구현할 수 있습니다. 지금 그 중 하나를 사용하지 않더라도 사용하게 될 가능성이 높으므로, 기본 구성을 이해하는 것은 어떤 종류의 앱을 사용하든, 어디에 배포하든 확장 가능한 아키텍처를 구축하기 위한 좋은 기초가 됩니다.
확장하세요!