[Test] 500명 유저의 동시 로그인 요청 처리

2026. 2. 2. 17:36·Test

500명 동시 로그인으로 CCU 375,000을 커버할 수 있는가?

  이전의 포스트에 작성하긴 했지만 일단 서두로 리마인드하고 넘어가려고 합니다.

 

  375,000명 기준의 CCU에서 90%는 자동 로그인으로 접속합니다.

 

  자동 로그인은 클라이언트 측에서 핸들링합니다. 일반적으로 JWT를 사용하는데, 만료된 AccessToken을 헤더에 달고 인증이 필요한 API를 요청하면, 서버에서는 401을 반환합니다. 이때 클라이언트 내부적으로 401을 반환받으면 RefreshToken을 이용해서 서버에게 AccessToken 갱신하는 API를 호출합니다. RefreshToken이 유효하다고 판단되면 AccessToken을 반환받고 이를 이용해서 기존 API를 처리합니다.

 

  일반적인 로그인에서는 비밀번호 검증을 위한 BCrypt 등을 사용하고, 토큰 생성 또는 검증에서는 HMAC-SHA256 등을 사용합니다. 이때 비밀번호 검증과 토큰 생성 및 검증에서 사용되는 알고리즘의 설계가 매우 달라서, 시간적인 차이가 매우 큽니다.

  비밀번호 검증 토큰 생성 / 검증
사용 알고리즘 BCrypt, SCrypt, Argon2 ... HMAC-SHA256, RSA ...
소요 시간 (Latency) 300ms ~ 500ms 0.01ms ~ 0.05ms
CPU 부하 매우 높음 거의 없음
초당 처리량 (TPS) 약 10 ~ 50 TPS 약 50,000 + TPS

 

  기본적으로 비밀번호 검증에서는 비밀번호 해시 값이 유출됐을 때 Brute Force로 비밀번호를 알아내지 못하도록 일부러 느리게 만듭니다. 1초에 10억 번 대입하는 등의 행위를 1초에 3번만 대입하게 강제하는 등의 방법이 있습니다. 따라서 느릴 수 밖에 없습니다.

 

  반면에 JWT의 Access token은 생성 시에 서버가 서명만 하면 됩니다. JWT의 KEY 값을 이용해서 입력된 문자열과 섞어서 단순 해싱 (HMAC-SHA256)을 진행하는데 이는 매우 가벼운 비트 연산입니다.

 

  따라서 자동 로그인으로 로그인을 대체하면 매우 빨리 연산을 끝낼 수 있고, 10%의 유저의 로그인을 감당할 수 있다면 로그인을 잘 처리할 수 있을 것입니다.

  Peak CCU에 37500명은 하루 동안의 실제 로그인 기능을 사용하는 사람입니다. 여기서 1분 동안 로그인을 하는 사람을 500명 정도 커버할 수 있다면 서비스 상으로는 문제가 없을 것 입니다.

 

  따라서 코드의 개선과 부하 테스트로 해당 부분을 개선하려고 합니다. 이전에 판단했던 결과는 다음과 같습니다.

  • 100명: avg=1.0s, max=1.2s
  • 1000명: avg=5.0s, max= 13.1s

  100명의 상황에서는 문제가 없으나, 1000명의 상황에서는 문제가 명확합니다. 로그인 속도가 13초까지 가버리는 것은 UX를 해칠 수 있습니다.

 

일단 500명의 상황에서 문제를 해결하는 것을 목표로 잡고 개선을 진행해보겠습니다.

테스트

export const options = {
    scenarios: {
        login_ramp_up: {
            executor: 'ramping-vus',
            startVUs: 0,
            stages: [
                { duration: '1m', target: 500 },
                { duration: '30s', target: 500 },
                { duration: '10s', target: 0 },
            ],
            gracefulStop: '30s',
        },
    },
    thresholds: {
        'http_req_failed': ['rate<0.01'],
        'http_req_duration': ['p(95)<1000'],
    },
};

 

K6의 시나리오 세팅입니다. 체크해볼 API는 1개 밖에 없습니다.

Hikari CP의 상태

  문제가 생기면 개선을 해보려고 했으나... http_req_duration이 생각보다 너무 좋게 나왔습니다. max가 2.88s이나 그래도 p(95)의 상황, 즉 하위 5%에서는 1.7s 이므로 선방했다고 볼 수 있습니다. CPU Uitlization도 0.996으로 훌륭하다고 보입니다.

 

  다만 로그인 시에 반환 값으로 DB를 조회해서 해당 유저의 읽지 않은 알림 개수를 반환하기 때문에 알림 개수가 많으면 동시 로그인 자체에 문제가 생길 수 있습니다. 이에 대한 해결은 추후의 알림 DB I/O 개선에서 다루도록 하겠습니다.

반응형

'Test' 카테고리의 다른 글

[Test] 점진적 부하테스트: 30,000명 유저의 SSE 구독 요청 - TCP  (0) 2026.02.04
[Test] 점진적 부하테스트: 10,000명 유저의 SSE 구독 요청 - 톰캣  (0) 2026.02.03
[Test] 점진적 부하테스트: 10,000명 유저의 동시 SSE 구독 요청 - 삽질  (0) 2026.02.02
[Test] Prometheus, InfluxDB 하이브리드 부하 테스트 구조 설계  (0) 2026.01.29
[Test] JaCoCo의 원리와 Test coverage 검증  (0) 2026.01.26
'Test' 카테고리의 다른 글
  • [Test] 점진적 부하테스트: 30,000명 유저의 SSE 구독 요청 - TCP
  • [Test] 점진적 부하테스트: 10,000명 유저의 SSE 구독 요청 - 톰캣
  • [Test] 점진적 부하테스트: 10,000명 유저의 동시 SSE 구독 요청 - 삽질
  • [Test] Prometheus, InfluxDB 하이브리드 부하 테스트 구조 설계
soberyl
soberyl
개발과 청춘 일지
    반응형
  • soberyl
    soberyl 님의 블로그
    soberyl
  • 전체
    오늘
    어제
    • 분류 전체보기 N
      • 프로젝트 N
        • Snap Trade N
        • 팀 프로젝트
        • 오픈 소스
      • 개발일지
        • 코딩 테스트
        • 알고리즘
        • CS
      • Full stack
      • Frontend
        • UXUI
        • React
        • Next.js
        • React Native
        • Monitor
      • Backend
        • NestJS
        • Spring
        • Monitor
        • DB
      • DevOps
        • CICD
      • Test
      • AI
      • Infra
        • AWS
        • On-premise
      • 청춘
        • 희곡
        • 연극
      • 잡설
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백엔드
    코딩테스트
    알고리즘
    최적화
    EC2
    MySQL
    memory
    io
    java
    프론트엔드
    설계
    테스트
    희곡
    CPU
    거래소
    OS
    DB
    thread
    연극
    코테
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
soberyl
[Test] 500명 유저의 동시 로그인 요청 처리
상단으로

티스토리툴바