서버 개발 실무 지식

서비스 성능

  • 서버 성능 지표 2가지: 응답 시간, 처리량

응답 시간

  • 요청 → 서버 실행(DB 조회, 외부 API, 로직, 응답 생성) → 응답
  • TTFB (Time to First Byte): 응답 데이터 중 첫 번째 바이트가 도착할 때까지 걸리는 시간
  • TTLB (Time to Last Byte): 응답 데이터 중 마지막 바이트가 도착할 때까지 걸리는 시간

처리량

  • TPS (Transactions Per Second): 초당 처리량
  • RPS (Requests Per Second): 초당 처리 수

성능 개선

  • 병목 지점 파악
  • 스케일 업 (수직 확장), 스케일 아웃 (수평 확장) - 상황에 따라 선택

1. DB 커넥션 풀

  • 커넥션 풀 크기
  • 커넥션 대기 시간
    • 대기 시간을 길게 해서 무응답 상태로 유지되는 것보다는, 빠르게 에러를 반환하는 것이 낫다. (서버 부하 방지)
  • 최대 유휴 시간
    • 사용되지 않은 커넥션을 풀에 유지할 수 있는 최대 시간
    • DB에 설정된 비활성화 유지 시간보다 짧게 설정하면, DB가 연결을 끊기 전에 풀에서 커넥션을 제거할 수 있다.
  • 유효성 검사
    • 커넥션이 정상적으로 사용 가능한 상태인지 여부를 확인하는 절차
  • 최대 유지 시간
    • 최대 지정 시간까지 커넥션이 유효하며, 이후에는 커넥션을 닫고 풀에서 제거한다.

최대 유휴 시간과 최대 유지 시간을 무한대로 설정하지 않는 것이 좋다.
DB 설정을 참고하여 적절한 값으로 지정해야 한다.


2. 서버 캐시

  • (키, 값) 형태로 데이터를 저장하는 Map 같은 데이터 저장소
  • 캐시 키가 겹치지 않도록 주의
  • 캐시 조회 순서
    • 존재: 값을 사용
    • 미존재: DB에서 값 조회 → (키, 값)을 캐시에 저장 → 값 사용
  • 캐시에 보관할 수 있는 데이터는 제한적 → 삭제 정책 필요
    • 주로 오래된 데이터를 미리 삭제하는 것이 좋다.

2.1 로컬 캐시 (in-memory)

  • 장점: 빠른 접근 속도, 외부 연동 필요 없음 → 구조 단순화
  • 단점: 데이터 크기 제한, 메모리 한계, 서버 재시작 시 휘발 (적중률 하락)

2.2 리모트 캐시 (예: Redis)

  • 장점: 캐시 크기 유연한 확장, 서버 재시작 후에도 캐시 유지
  • 단점: 속도 저하 (네트워크 통신), 별도 장비·프로세스 필요 → 구조 복잡

로컬과 리모트 캐시는 상황·용도에 따라 선택한다.
데이터 규모, 변경 빈도, 응답 시간, 처리량 등을 종합적으로 고려한다.

  • 데이터 규모가 작고 변동이 적다면 로컬 캐시로 충분
  • 데이터 규모가 크면 리모트 캐시를 고려 (예: 트래픽 많은 대형 쇼핑몰의 개별 제품 정보)
  • 배포 빈도가 높은 서비스(하루에 몇 번씩 배포)는 리모트 캐시를 적극 고려

    (로컬 캐시는 휘발 → 적중률 저하 → 응답 시간 저하)

2.3 캐시 사전 적재

  • 트래픽이 순간적으로 급증하는 패턴이 있다면, 캐시에 데이터를 미리 적재해두는 것도 고려

2.4 캐시 무효화

  • 유효하지 않은 데이터를 적절한 시점에 삭제
  • 캐시에 보관된 데이터의 원본이 바뀌면, 캐시 데이터도 함께 변경 또는 삭제
  • 가격 정보, 게시글 내용처럼 민감한 데이터즉시 캐시 무효화 필요

2.5 가비지 컬렉터와 메모리 사용

  • JVM 기반 서버의 경우, GC (Garbage Collector) 가 서버 메모리 사용에 큰 영향을 준다.
  • 불필요한 객체가 계속 메모리에 남아있으면, GC로 인한 Stop-the-World 현상이나 메모리 부족으로 이어질 수 있다.
  • 또한, Redis나 Memcached 같은 리모트 캐시도 LRU(Least Recently Used), TTL (Time to Live) 과 같은 만료 정책으로 메모리를 관리한다.
  • 서버의 메모리 사용량을 지속적으로 모니터링하고, GC 튜닝을 통해 효율적으로 메모리를 사용하는 것이 중요하다.

2.6 응답 데이터 압축

  • HTML, CSS, JS, JSON 등 텍스트 기반 응답은 압축으로 전송량을 크게 줄일 수 있다.
  • gzip으로 압축하면 70% 이상 크기를 줄일 수 있다.
  • 클라우드 환경에서는 트래픽 비용으로 직결되므로, 응답 데이터 압축은 반드시 검토해야 한다.

2.7 정적 자원과 브라우저 캐시

  • 브라우저 캐시는 브라우저 단위로 동작
  • 많은 사용자가 동시에 접속하면, 브라우저 캐시 덕분에 서버의 데이터 처리량 감소

2.8 정적 자원과 CDN

  • CDN(Content Delivery Network)은 전 세계적으로 분산된 서버를 통해 정적 파일을 빠르게 전달
  • CDN을 사용하면 전 세계의 사용자에게 지리적으로 가까운 서버를 통해 콘텐츠를 제공할 수 있다.
  • 따라서 응답 속도가 빨라지고, 오리진 서버의 부하가 크게 줄어든다.
  • 장점: 오리진 서버의 부하 감소, 빠른 콘텐츠 제공, 트래픽 비용 절감
  • 이미지, 동영상, JS/CSS 파일과 같은 정적 리소스를 CDN에 저장하고, 사용자에게 전달하도록 설정한다.
  • 서비스가 성장하기 시작했다면, CDN 사용을 적극 검토해보자

2.9 대기 처리(유입 제어)

  • 부하로 인해 서비스가 아예 중단되는 것보다는, 대기 상태로 유지하는 것이 낫다.

서버 개발자라면 누구나 대규모 트래픽을 처리할 수 있는 아키텍처를 경험해보고 싶어한다.
그러나 개발자라면 비용도 반드시 고려해야 한다.
대규모 트래픽을 처리하기 위한 비용은 결코 적지 않다.
이런 관점에서 대기 제어는 매우 합리적이다.
게다가 대기 제어 기능은 직접 구현하지 않아도 된다. 이미 많은 솔루션이 존재해, 빠르게 도입할 수 있다.


참고 자료:

  1. 최범균: 주니어 백엔드 개발자가 반드시 알아야 할 실무 지식