로고jiohh blog

JWT와 Session의 성능 차이는 어떻게 될까? – 부하테스트 1

JWT와 Session의 성능 차이는 어떻게 될까?


처음은 Session과 Jwt의 성능차이가 얼마나 될지에 대한 호기심이였다.
Jwt 암호화 비용 때문에 Jwt가 더 비용을 많이 잡아먹는다라고 있으나 직접한 사례를 찾기 힘들었다. 그래서 직접 해보기로 하였다.

이유를 나열하여 작성해보면 다음과 같다.

  • Session과 Jwt 로그인의 성능을 직접적으로 측정해보고 싶었다.
  • 로그인 과정을 직접 세세하게 구현 후 이를 Spring Security로 마이그레이션 해보면서 인증,인가 흐름도 제대로 확인해보고 싶었다.
  • 인증, 인가 과정에서 필터/인터셉터 활용, DB조회, 세션 활용, Cache 최적화등 여러 방면에서 적용할 수 있으므로 인증/인가 뿐만아니라 웹서비스의 라이프 사이클을 가장 간단하게 복습해볼 수 있는 기회라고 생각
    -> JPQL을 이용하여 구현후 이를 다른 추가적인 비즈니스 로직에 적용해 본다면 충분히 다른 로직도 구성할 수 있지않을까 라는 생각
  • 이전 프로젝트에서 부하테스트 없이 진행하였는데 간단한 로직에서도 문제가 발생하여 실제 실무에서는 부하를 어떻게 확인하고 개선하는지 궁금했음

물론, 실무에서는 성능만이 아닌 모바일 지원여부, 아키텍처, 도메인에 따라 선택하지 않을까 싶다.


부하 테스트 환경

로그인 서비스

간단한 서비스로 메모를 작성할 수 있는 서비스로 구현하였다.
JWT 인증 필터와 Session 인증 필터를 사용한 프로젝트 두개를 똑같이 생성하여 동일한 API 구조, 인증 방식만 다르게 구현하였다.

부하 테스트 환경

부하 테스트에 사용된 최종 아키텍처의 모습이다.

K6를 선택한 이유는 가장 간단하게 부하테스트를 진행할 수 있다고 판단했기 때문이다.
대체제로 Jmeter등 여러 툴이 있었으나 가장 빠르고 쉽게 사용할 수 있다고 판단하여 K6를 선택하였다.

초기 K6에서 점차 추가되어 이렇게 구성되었다. 그 과정을 통해서 성능비교를 말해보고자 한다.

  1. 단일 K6 부하테스트 진행
  2. K6 + InfluxDB + Grafana / 시계열 데이터 분석
  3. K6 + telegraf + InfluxDb + Grafana / 시스템 메트릭 추가

테스트 유형?

먼저 테스트 유형을 이야기하고 진행하여야할 것 같다.

스모크 테스트, 스파이크 테스트, 부하 테스트, 스트레스 테스트, 내구 테스트, 임계점 테스트 등등 여러 목적을 가지고 있는 테스트 유형이 존재한다. (각 테스트를 다 말하기에는 주제와 벗어나니 추후에 글 링크 추가)

이중 성능 비교에 어울리는 테스트를 선정하고 그에 맞추어서 구성하여야했다.

여러 테스트 중 시스템의 한계점인 임계지점을 찾을 수 있는 임계점 테스트로 진행했다.
임계지점을 비교하여 각 방식의 성능을 비교하였다.

시나리오 설정

Jwt와 세션에서 성능비교가 가능한 부분을 "인가 + 인가 후 메모 생성"으로 구성해서 진행했다.

즉, 성능차이가 발생하는 부분으로

  1. Jwt 방식 : Jwt가 토큰을 검증
  2. Session 방식 : 세션에서 유저 정보를 검증
  • 공통부분 : 메모작성

이 과정이 핵심 로직일 뿐만아니라 가장 큰차이라고 생각하였다. 그래서 메모작성을 기준으로 시나리오를 구성하였다.

export const options = {
  stages: [
  { duration: '5m', target: 2000 },
  { duration: '25m', target: 5000 },  // 30초 동안 50명의 VUs로 증가
  { duration: '10s' , target: 0 },   // 30초 동안 VUs를 0으로 감소
  ],
};

export default function() {
  const url = 'http://host.docker.internal:8080/api/memos';
  const payload = JSON.stringify({
      "content": "contentText",
    });
  const params = {
    headers: {
      'Content-Type': 'application/json',
      'Cookie': 'JSESSIONID=C8C891F97B812551C3CDAA6401323747', // 또는
      'Authorization': 'Bearer eyJhbGciOiJIUzI1NiJ9.eyJpZCI6MSwidXNlcklkIjoiMTIzNCIsIm5hbWUiOiLslYjrqZTrqqgiLCJyb2xlIjoiVVNFUiIsImlhdCI6MTc1MjgyMDk5NywiZXhwIjoxNzUyODIyNzk3fQ.lKek6DRTCnkVATit3I1eiHmlb3FiUrm3_KF8k4tKcYs'
    },
  };
  let res = http.post(url, payload, params);
  check(res, { "status is 200": (res) => res.status === 200 });
  sleep(1);
}

최종적으로 사용한 시나리오는 위의 코드이다.

미리 구한 토큰이나 세션을 바탕으로 인가정보를 헤더에 세팅 후 이를 바탕으로 정해진 시나리오를 반복하도록 설정하였다.

기본적인 메모 생성 시나리오는 동일하게 가져갔고 vus 수나 시간을 변경하며 여러번 테스트를 반복하였다.


다음 글에서는 이를 바탕으로 어떻게 진행하였는지에 대한 내용이다.