Programming ,

브라우저에서 DB까지

by Mimul FollowSeptember 18, 2017 · 10 min read · Last Updated:
Share this

브라우저에서 URL을 입력해 DB까지 데이터를 처리하는데 까지 일어나는 일들과 각 단계별로 스타트업 개발자가 알아야할 일들을 정리해 본다. 스타트업 개발자가 서비스를 구축해서 운영하다 보면 알아야할 기술들도 이 범주안에 드는 경우가 많다. 처음 설정부터 운영중에 일어나는 병목이나 장애 등에 대한 원인을 찾고 대응력을 갖추는데 도움을 준다.

1. DNS

브라우저에서 mimul.com을 입력하고 엔터를 치면 먼저 로컬의 DNS 캐시를 확인해 있으면 IP 주소가 리턴되면 웹사이트에 엑세스 할 수 있다. 만약 로컬에 캐시가 없다면 인터넷 공급자(ISP)의 DNS 서버로 전달된다. ISP의 DNS 서버가 이미 해당 도메인 이름의 IP 주소를 캐시한 경우 이를 직접 클라이언트에 반환하여 웹사이트에 즉시 액세스할 수 있게 된다.

ISP의 DNS 서버에 캐시가 없는 경우에는 루트 DNS 서버로 쿼리가 전송된다. 루트 DNS 서버(ICANN 관리)는 직접 리디렉션하는 대신 적절한 TLD 서버(Top-level domain, 도메인 등록 기관)에 대한 참조 목록을 반환하여 해당 TLD 서버로 전송되고 TLD 서버는 권한있는 DNS 정보를 반환하고 권한 DNS 서버에서 해당 도메인의 IP주소를 반환해주면 해당 웹사이트로 클라이언트는 액세스하게 된다.

DNS

※ 스타트업 개발자가 해야할 일

  • SSL 인증서 설치를 할 수 있어야 한다.
  • DDOS 공격 등에 의한 장애에 대비해 도메인 네임 서버 이중화가 필요하다.
  • 서비스 구성시 도메인 설계 등을 고민해야 한다. 서브 도메인, CNAME 설정 정보도 알아야 한다.
  • 일정 수량 이상으로 메일 발송하기 위해 도메인 제공업체에서 소스 도메인별로 발신자 인증을 해야하는데, SPF/DKIM/DMARC 설정을 DNS 레벨에서 설정해 줘야한다. 구글 이메일 발신자 가이드를 참고하자.
  • 접속 장애일 경우 아래 커맨드를 통해 네임서버 장애인지 먼저 확인해 본다.
> dig www.mimul.com
> dig NS www.mimul.com
> dig @dns1.p01.nsone.net mimul.com any
> traceroute www.fittobe.com

2. CDN

CNAME 레코드를 사용하여 CDN 공급자를 가리키는 경우는 CDN의 DNS Look Up일 경우 로컬 DNS 캐시 정보를 먼저 검색하고 없다면 인터넷 공급자(ISP)의 DNS 서버 www.mimul.com을 도메인 resolve한 다음 authoritative name server로 recursively 쿼리를 날려서 정의된 CNAME의 DNS 도메인 정보를 받고 CDN 네임 서버로 가서 하위 CDN load balancer로 가서 목적지 CDN IP를 클라이언트로 전송해 클라이언트는 해당 서버로 액세스를 하게 된다.

CDN

CDN의 메커니즘

  • 콘텐츠 캐시 : CDN 에지 서버는 오리진 서버에서 콘텐츠(HTML 페이지, 이미지, 동영상, 스타일시트, JavaScript 파일 등)를 복사하고 캐시(임시 저장)한다.
  • 지리적 근접성 : 사용자가 웹사이트를 방문하면 DNS 확인 프로세스는 사용자와 가장 가까운 CDN 에지 서버를 선택한다. 웹페이지 로드 시간이 단축된다.
  • 부하 분산 : 콘텐츠 요청을 여러 에지 서버에 분산시켜 특정 서버에 걸리는 부하를 균등하게 밸런싱한다.
  • 콘텐츠 최적화 : 배포할 콘텐츠를 자동으로 최적화하는 기능을 제공한다.
  • 보안 강화 : DDoS 공격과 같은 사이버 위협으로부터 웹사이트를 보호하는 역할도 담당한다. 분산된 에지 서버를 사용하여 트래픽을 필터링하고 공격을 완화할 수 있다.

※ 스타트업 개발자가 해야할 일

  • CDN 서비스(Amazon CloudFront, Google Cloud CDN, Cloudflare, Akamai, CDNetworks, Incapsul, Fastly, Limeligh, Edgecast)를 알아두어 필요시 사용할 줄 알아야 한다.

3. 웹 사이트 액세스와 보안 통신

사용자의 브라우저가 CDN의 에지 서버(또는 최종 웹 서버)에 연결하면 TLS 핸드셰이크가 발생한다. 사용자가 웹 브라우저를 사용하여 mimul.com 사이트에 액세스하면 HTTP/HTTPS 프로토콜을 통해 데이터 교환이 이루어진다. HTTPS는 TLS(Transport Layer Security)를 이용하여 통신을 암호화하고 TLS 인증서를 통해 서버의 신원을 증명한다. HTTPS 연결은 사용자와 사이트 간의 통신이 보호되고 신뢰할 수 있는 보안 연결이 설정된다. 아래 그림은 DNS Lookup 다음의 프로세스를 나타낸다. 실제 단계별로 타임을 기록하는 스크립트도 공유한다. 이것으로 각 단계별로 처리시간을 확인할 수 있고 DDOS에 의한 DNS 장애도 이 스크립트로 유추하기도 했다.

SSL HANDSHAKE

❯ cat page-timing.sh
#!/bin/sh
time_format=`cat <<EOF
DNS Lookup : %{time_namelookup}
TCP HANDSHAKE : %{time_connect}
SSL HANDSHAKE : %{time_appconnect}
Request start : %{time_pretransfer}
Response start : %{time_starttransfer}
Time Total : %{time_total}
Redirect : %{time_redirect}
EOF`

curl -o /dev/null -w "${time_format}" -s https://www.mimul.com

1. TLS 핸드셰이크

  • 매개변수 교환/동의를 통해 합의하는 매개 변수는 암호화/키교환 알고리즘, 각종 확장 기능의 사용 여부 등을 클라이언트가 가능한 후보를 서버에 전달하고(ClientHello) 서버는 클라이언트에서 제시한 후보 중에서 가장 적합한 것을 하나 선택하고 그 값을 클라이언트에 반환한다.(ServerHello)
  • 실제로 인증서를 이용하는 것은 클라이언트와의 직접적인 통신을 담당하는 로드 밸런서의 경우가 많다.

2. TLS 인증서 검증

  • 브라우저는 받은 TLS 인증서의 유효성을 검사한다. 인증서는 신뢰할 수 있는 인증 기관(CA)에서 발급되었으며, 유효 기간내에 있으며 사이트의 도메인 이름이 일치하는지 확인한다.

3. 암호화 키 교환

  • 서버와 클라이언트는 세션 중에 사용하는 암호화 키를 안전하게 교환하며, 이후의 통신은 이 키를 사용하여 암호화된다.
  • 키교환은 주로 DHE, ECDHE 방식을 주로 사용한다.

더 상세한 내용을 확인할려면 HTTPS에 대해 알아야 할 것들이란 포스트를 보면 HTTPS 프로토콜 뿐만 아니라 Apache 등 서버 설정 정보도 있어 도움이 된다.

※ 스타트업 개발자가 해야할 일

  • SSL 인증서 설치를 웹서버(Apache, Nginx 등)에 설정(SSLProtocol, SSLCipherSuite, SSLCertificate)할 수 있어야 한다.
  • 특별한 경우 아니면 Let's Encrypt 무료 인증서를 설치하면 된다. 제일 중요한 건 해마다 인증서 갱신을 잘하자.
  • 별도의 데몬을 구동중이라면 openssl 커맨드 사용법을 알아두면 좋다.

    # PKCS12
    openssl pkcs12 -export -in /app/ssl/cert.pem -inkey /app/ssl/key.pem -out mycert.p12 -name netty -certfile /app/ssl/DigiCertCA.pem

4. Load Balancer

도메인의 IP주소를 받아서 해당 서버의 주소로 이동하면 대부분은 부하분산이나 장애 예방을 위해 로드발란서를 만나게 되는데, 로드 발란서의 부하 분산 방식에 의해 지정된 서버로 다시 이동을 한다.

로드 밸런서의 주요 기능

  • 부하 분산 : 서버에 로드를 적절하게 분산시키는 것.

    • Round Robin : 모든 서버에 동일하게 분산. 알고리즘 단순함.
    • Weighted Round Robin : 서버의 처리 능력에 따라 요청 할당 비율을 조정하는 방법.
    • Least Connection : 연결 수가 가장 적은 서버에 요청을 보냄. 최적의 성능 관점.
    • Least Response : 서버당 응답 시간이 가장 짧은 것에 요청을 우선적으로 할당하는 방법.
    • Hashing(Source IP, Source IP+Port) : client의 Source IP 정보 또는 Source IP + Port 정보를 바탕으로 hash 한 결과 값을 토대로 분산. 같은 클라이언트가 같은 서버로 요청이 갈수 있도록 하기 위함.
  • 서버의 사활 감시 : 서버가 정상적으로 실행 중인지 확인하는 프로세스.
  • 서버 유지보수의 용이성 향상 : 새로운 기능 적용 등으로 서버를 내리고 적용하고 올리는 과정을 다운 타임없이 진행이 가능하고 서버 성능 및 트래픽 패턴을 시각화하고 실시간 모니터링을 통해 문제를 조기에 감지하고 대응할 수 있다.

※ 스타트업 개발자가 해야할 일

  • 서비스의 특성에 맞는 부하분산 알고리즘을 선택해서 LB를 설정 등록할 수 있어야 한다.
  • 로드 발란서에 적용할 서버의 IP를 빼고 서비스를 내리고 올리는 스크립트를 만들어서 반영할때 활용하게 한다.

5. 방화벽(WAF)

해당 서버로 이동하게 되면 방봐벽이 나타난다. 기본적으로 허가된 요청이 아닌 경우 차단을 하게되고 또, 서버를 과부하 상태에 빠뜨리고 합법적인 사용자의 액세스를 방해하는 DDoS(분산 서비스 거부) 공격을 필터링 한다. 웹 애플리케이션 방화벽은 애플리이션 공격(예: SQL 주입 및 크로스 사이트 스크립팅)으로부터 보호하고 다양한 악의적인 시도를 감지하고 차단한다.

※ 스타트업 개발자가 해야할 일

  • SSH, DB, NoSQL 등의 포트에 대한 방봐벽 설정을 할 줄 알아야 한다.

6. 웹 서버

클라이언트 요청이 방화벽을 통과하고 난 다음 HTML 페이지, 이미지, 비디오 또는 파일과 같은 정적 콘텐츠를 브라우저에 반환하는 역할을 웹 서버가 지원한다. 대표적인 제품으로는 Apache, Microsoft IIS, Nginx가 있다.

※ 스타트업 개발자가 해야할 일

  • 웹 서버 설치 및 구동 그리고 서버의 가용범위내에서 최대 성능을 발휘할 수 있는 설정 튜닝 등을 할 수 있어야 한다.
  • 커널 레벨에서 튜닝을 할 줄 알아야 지속 가능한 서비스가 만들어진다.

7. 어플리케이션(API 포함) 서버

클라이언트 요청이 방화벽을 통과하고 난 다음 동적 콘텐츠 생성, 애플리케이션 로직 및 다양한 리소스와의 통합을 지원하는데, 이는 어플리케이션 서버에서 지원한다. 제품으로는 Tomcat, Unicorn, IIS, Gunicorn, uWSGI, NGINX Unit 등이 있다. 애플리케이션 서버와 API 서버는 웹 애플리케이션 및 서비스의 백엔드에서 핵심적인 역할을 한다. 이러한 서버는 클라이언트로부터 요청을 받고, 필요한 비즈니스 로직을 처리하고 데이터베이스와 상호 작용하며, 클라이언트에 동적 콘텐츠 및 API 응답을 제공한다.

애플리케이션 서버는 웹 애플리케이션의 비즈니스 로직 계층을 실행하기 위한 플랫폼이다. 클라이언트(예: 웹 브라우저 또는 모바일 앱)의 요청을 받고 필요한 처리(예: 데이터 검색, 가공, 저장 등)를 수행한 후 적절한 응답을 클라이언트에 반환한다. 세션 관리, 트랜잭션 관리, 보안, 데이터베이스 연결 관리 등 복잡한 비즈니스 프로세스를 지원하는 기능을 제공한다.

API 서버는 내부, 외부 서비스에 필요한 기능들을 제공하며, RESTful API 및 GraphQL과 같은 기술을 사용하여 데이터 검색, 업데이트, 삭제 등의 작업을 지원한다. API 서버는 기본적으로 Stateless이며 각 요청은 자체적으로 완료되며, 요청간에 사용자의 상태를 유지할 필요가 없으며 수평 스케일(수평 확장)을 쉽게 할 수 있는 특징이 있다.

어플리케이션 서버의 아키텍처 패턴

  • 모놀리식 : 단일 코드 기반 애플리케이션. 개발이 단순하지만 대규모화하면 관리가 복잡해진다.
  • 서비스 지향 아키텍처(SOA) : 여러 애플리케이션 및 시스템에서 비즈니스 로직을 제공하는 시스템 구성. 엔터프라이즈 서비스 버스를 통해 서비스 간 연계 DB를 공유하고 있기 때문에, 동기화 등의 처리가 필요 없다.
  • 마이크로서비스 : 비즈니스 로직을 세분화하여 개별 서비스로 한 아키텍처. API를 통해 통신, DB를 분리하고 있기 때문에 데이터가 중복될 가능성도 있다.

MSA

※ 스타트업 개발자가 해야할 일

  • AP 서버 제품군을 선택해 설치 및 설정 튜닝을 통해 안정적 운영을 할 수 있어야 한다.
  • 완벽하지는 않겠지만 확장 가능한 아키텍처를 고려한 애플리케이션을 개발한다.(ID 관리, 트랜젝션 관리, 테스트 전략 등)

8. 캐시 서버

애플리케이션 서버에서 많이 요청되는 데이터는 캐시 전략을 쓰는데, 이 때 메모리 기반 데이터베이스(Memcached, Redis) 캐시를 주로 사용 한다. 캐시에 저장할 데이터 군과 선택한 캐시 전략에서 발생하는 문제들을 고려해서 구현을 한다.

캐시 구현 전략

  • Cache-Aside : 애플리케이션 코드는 캐시와 데이터 소스를 모두 관리한다. 데이터 요청이 있을 때 먼저 캐시를 확인하고 데이터가 없는 경우에만 데이터베이스에 액세스한다. 애플리케이션 측 코드가 단순하게 유지되어 캐시 미스시의 데이터 읽기 처리를 자동화할 수 있다.
  • Read-Through : 캐시 계층은 데이터 로드를 관리한다. 데이터 요청시 캐시에 데이터가 없으면 캐시 계층은 데이터베이스에서 데이터를 읽고 캐시에 저장한 다음 애플리케이션으로 반환한다. 애플리케이션 측 코드가 간단하게 유지된다. 캐시 미스시의 데이터 판독 처리를 자동화할 수 있다.
  • Write-Through : 쓰기 작업도 캐시 계층에서 관리한다. 애플리케이션에서 데이터 쓰기 요청을 받으면 캐시 계층이 먼저 데이터를 데이터베이스에 쓰고 캐시에 동일한 데이터를 저장한다. 데이터 무결성을 유지하고 데이터베이스와 캐시 간의 동기화 프로세스를 자동화할 수 있다.
  • Write-Back(Behind) : 데이터 쓰기를 일시적으로 캐시에 유지하고 일괄 처리 또는 지연 처리를 통해 나중에 데이터베이스에 기록하는 방법이다. 이렇게 하면 쓰기 작업의 성능을 향상시킬 수 있다.

Cache Strategy

※ 스타트업 개발자가 해야할 일

9. 데이터베이스

애플리케이션 서버에서 데이터 처리가 필요할 경우 DB접속을 해 해당 프로세스를 진행한다. 제품으로는 Oracle, SQL Server, MySQL, PostgreSQL이 있다.

스케일 아웃 방법들

1. Replication

  • 마스터 슬레이브 : 하나의 마스터 서버가 쓰기(등록, 수정, 삭제)를 담당하고 데이터를 하나 이상의 슬레이브 서버로 복제한다. 슬레이브 서버는 읽기 전용 또는 읽기 우선이며 이 구성은 읽기 부하 분산 및 데이터 백업에 효과적이다.
  • 멀티 마스터(파어 투 피어) : 여러 서버 간의 데이터 복제를 나타내고 한 서버에서 변경된 내용이 다른 모든 서버로 복제되고 모든 서버가 데이터에 대해 동일한 소유권을 갖는다. 모두가 대응한 피어이다. 여러 서버가 동일한 데이터를 동시에 업데이트할 수 있으므로 충돌이 발생할 수 있지만, 이 충돌은 버전 정보가 포함된 추가 열과 업데이트 시 타임스탬프 정보를 사용하여 자동으로 해결된다. 궁극적으로 최신 타임 스탬프가 있는 업데이트가 유지되고 다른 서버로 변경 사항이 전파된다.

2. Sharding

데이터를 여러 데이터베이스(샤드)에 분산하여 단일 데이터베이스에 대한 부담을 줄이고 읽기/쓰기 작업 속도를 높일 수 있는 전략이다. 여러 데이터베이스를 대상으로 작업해야 하기 때문에 경우에 따라서는 기능에 제약이 있을 수 있고(JOIN 연산 등) 일관성(consistency)과 복제(replication) 등에서 불리한 점이 많다. 과거의 샤딩은 애플리케이션 서버 레벨에서 구현하는 경우가 많았는데 최근에는 이를 플랫폼 차원에서 제공하려는 시도가 많다. 그중 미들티어에 샤딩 플랫폼을 둔 Gizzard, Spider, Spock Proxy 등의 제품군이 있다.

샤딩 기법
  • Vertical Sharding(수직 샤딩) : 데이터베이스의 다른 테이블을 별도의 데이터베이스(샤드)로 분할합니다. 각 샤드는 데이터베이스의 다른 기능 영역을 담당한다.
  • Horizontal Sharding(수평 샤딩) : 동일한 테이블의 레코드를 여러 데이터베이스(샤드)에 분산시킨다. 이는 특정 열의 값(예: 고객 ID 또는 지리적 위치)을 기반으로 하는 경우가 많다.
  • Key-based Sharding : 데이터를 샤드에 할당할 때 일관된 해시 함수를 사용하여 키를 생성하고 해당 키를 기반으로 샤드를 결정한다.

※ 스타트업 개발자가 해야할 일

  • 설치해 운영할 경우 DB 복제, 이중화를 고민해야 한다.
  • Cloud 제품군을 사용할 경우 비용 절감 방안 및 이슈 대응할 수 있어야 한다.
  • 보안에 대한 준비(SQL Injection, 권한 등)를 해야한다.
  • DB의 정기적 인 백업 스크립트, 복원 스크립트를 준비해야 한다.
  • SQL 색인이 올바르게 적용했는지 검토한다.
  • 서비스 운영중에 일어나는 수작업(민원 처리)을 정리해 소스코드에 적용해 데이터 정합성을 강화하고 배치로 사후 보정작업을 적용해 수작업을 줄이는 노력을 해야한다.

참조 사이트