이 글은 제 포트폴리오에서 사용된 기술에 대한 내용을 다루고 있습니다.
자세한 내용은 추가로 검색을 해보셔서, 본인의 언어로 정리하시길 추천드립니다.
이 글 역시 제 생각과 언어에 맞게 정리하였고, 틀린 부분이 있을 수 있으니 댓글로 지적해 주시면 감사하겠습니다!
[Redis]
💡Redis의 특징
⬇️정리
- key - value쌍의 해시맵과 같은 구조를 가진 NoSQL이다.
- 오픈소스 기반으로 인메모리 데이터 저장소로, 메모리에 데이터를 저장한다.
1. 성능
- 모든 데이터를 메모리에 저장되어 대기 시간을 낮추고 처리량을 높인다.
- 읽기, 쓰기 속도가 RDBMS에 비해 빠르다.
2. 유연한 데이터 구조
- String, List, Set, HashMap 등 다양한 데이터타입을 지원한다.
3. 개발 용이성
- 쿼리문이 따로 필요하지 않고, 단순한 명령 구조로 데이터의 저장, 조회가 가능하다.
4. 영속성
- 영속성을 위해 데이터를 디스크에 저장할 수 있다.
- 서버에 문제가 발생해도 디스크에 저장된 데이터를 통해 복구가 가능하다.
5. 싱글 스레드 방식
- Redis는 싱글 스레드 방식을 사용해서 한번에 하나의 명령어만 처리한다.
- 따라서 경쟁상태가 발생하지 않는다.
- 멀티 스레드를 지원하지 않기 때문에 시간복잡도가 O(n)인 명령어의 사용은 주의해서 사용해야한다.
Redis 사용 사례
- 캐싱
- 채팅, 메시징 대기열
- 랭킹 보드(순위 표)
- 인증 토크 저장(세션 스토어)
- 미디어 스트리밍
- 실시간 분석
- 위치기반 데이터 타입 사용
💡JWT 토큰 관리에 Redis를 사용하는 이유
제 포트폴리오에서 Spring Security와 JWT를 이용한 회원 로그인 상태 관리를 하였고, 로그아웃 처리, refreshToken관리에 Redis를 사용했습니다.
⬇️로그아웃 처리 시 Redis를 사용 한 이유
AccessToken Blacklist
JWT 토큰 자체를 무효화 처리 할 수 있는 방법은 없습니다. 따라서 로그아웃 시에는 해당 토큰으로 인증을 할 수 없도록 Redis에 저장하여, 저장된 토큰을 마치 Blacklist처럼 관리합니다.
또한, TTL(Time To Live)을 설정할 수 있어서, accessToken의 expire Time과 Redis에 저장할 데이터의 TTL을 일치시킬 경우, 시간이 지나면 자동으로 삭제되게 할 수 있어서 메모리 낭비가 발생하지 않습니다.
로그아웃 처리 과정
- 로그아웃 요청 시 Redis에 Key=accessToken 인 데이터를 넣는다.
- Security Filter에서 요청 시 Authorization 헤더에 포함된 accessToken이 Blacklist에 존재하는 토큰인지 여부를 확인하는 로직을 추가한다.
- Blacklist에 존재하는 경우, 로그인 되지 않은 상태와 같이 처리한다.
⬇️Refresh Token 관리에 Redis를 사용 한 이유
Refresh Token의 탈취 문제를 해결하기 위해 Redis에 RefreshToken을 저장합니다.
Key = 사용자 ID, Value = RefreshToken 형식으로 저장하여 사용자 한 명 당 하나의 RefreshToken만 유효하도록 처리합니다. 로그인 시에 refreshToken을 발행할 때와 AccessToken 재발행(Reissue) 시에 재발행된 RefreshToken을 Redis에서도 새로 저장합니다. 이렇게 하면 로그인 시, Reissue시마다 이전에 사용하던 RefreshToken이 무효화되는 것과 다름없어집니다.
💡분산 락에 Redis를 사용한 이유
⬇️Answer
두가지 이유가 있습니다.
첫 번째는 Redis가 싱글 스레드로 동작하기 때문에 경쟁상태가 발생하지 않게 되서, 동시성 문제가 발생하지 않습니다.
두 번째는 Redis가 인메모리 DB 이기 때문에 읽기, 쓰기가 빠릅니다. 분산락이 처리되는 과정에서 Redis의 데이터에 대해 읽기, 쓰기, 삭제만 일어나기 때문에 빠른 속도로 분산 락을 처리할 수 있습니다.
[SSE]
💡알림을 구현할 때 SSE를 사용한 이유
⬇️Answer
SSE는 HTTP 프로토콜 위에서 동작해서 Client가 구독을 한 상태에서 Server로부터 데이터를 받을 수 있는 방식입니다. 실시간으로 pop-up을 할 순 있지만, 실시간성이 그렇게 중요하진 않고 만약에 연결이 끊겨서 알림을 받지 못해도 큰 문제가 발생하진 않기 때문에 알림에는 SSE를 사용했습니다.
⬇️다른 실시간 처리 방법도 있는데, SSE를 사용한 이유
[WebSocket / SSE / Polling 차이점]
Polling
단순하게 Client가 주기적으로 Server로 HttpRequest를 보내서 이벤트가 있는지 확인하는 방식인데,
변화가 없어도 주기적으로 Request를 보내야해서 리소스 낭비가 발생합니다.
알림 상황이 그렇게 자주 일어나지 않기 때문에 적합하지 않다고 생각했습니다.
WebSocket
HTTP가 아닌 ws 프로토콜을 통해 통신을 하고, 양방향 통신이고, 한번 연결하면 지속적으로 연결을 유지한다고 알고 있습니다.
SSE
SSE는 구독 요청 이후로는 서버가 클라이언트에게 단방향으로 데이터를 전송하는 방식이라, 알림에 적합하다고 생각했습니다.
💡SSE 작동 방식
⬇️Answer
HTTP 프로토콜 위에서 동작해서 Client가 구독을 한 상태에서 Server로 부터 데이터를 받을 수 있는 방식입니다.
저희 서비스에서는 로그인 시에 따로 subscribe API를 이용해서 서버에 요청을 하면 SseEmitter를 만들어서 반환합니다.
서버측에 Key=회원 ID, Value=SseEmitter로 갖는 ConcurrentHashMap에 저장합니다.
특정 회원에 대한 알림 발생 상황에서, 해당 SseEmitter를 꺼내서 알맞은 회원에게 알림을 전송하는 방식으로 작동합니다.
[ 배포 ]
💡배포 과정에 대해 설명해 주세요.
⬇️Answer
- AWS EC2에서 무료로 t2.micro 서버 인스턴스를 사용해서, ubuntu 리눅스 서버를 사용
- java, git , docker 설치
- git clone 받고 빌드해서 jar 파일 생성
- docker-compose로 서버에서 사용하는 docker image들을 자동으로 생성
- jar 파일을 백그라운드에서 실행
💡Docker 사용 이유
⬇️Answer
- Docker : 오픈소스 컨테이너, 가상 인스턴스
- 새로 만든 배포 서버에 여러가지 인프라를 다 설치해줘야 하는데, 이걸 일일히 설치하지 않아도 되도록 여러 이미지를 도커에 띄워놓고 사용할 수 있습니다.
- 환경이 바뀌어도 도커를 이용하면 기존에 사용하던 이미지들을 다시 그대로 사용할 수 있다는 장점이 있습니다.
- 로컬 환경과 배포 환경에서 동일하게 동작할 수 있도록 하고, 편하게 MariaDB, Redis 등의 인프라를 받아서 사용하기 위해서 도커를 사용했습니다.
💡MSA란?
⬇️Answer
MSA(Micro Service Architecture)는 하나의 시스템을 도메인 별로 나눠서 독립적으로 배포 가능한 여러개의 서비스로 분할하는 것입니다. 각각의 서비스는 API를 통해 데이터를 주고받으며 하나의 큰 서비스를 구성합니다. 모든 구성요소가 하나의 프로젝트에 포함되어 있는 Monolithic Architecture와 대척점에 있는 아키텍처입니다.
[장점]
- 일부 서비스에 장애가 발생해도 전체 서비스에 영향을 끼치지 않는다.
- 각각의 서비스를 다른 언어와 프레임워크로 구성할 수 있다.
- 서비스 확장에 용이
[단점]
- 서비스가 분리되어 있어 테스트나 트랜잭션 처리 등이 어렵다.
- 서비스 간에 API로 통신하기 떄문에 그 비용이 발생한다.
- 서비스 간의 호출이 연속적이기 때문에 에러 트레이싱이 어렵다.
'기타 > Tech Interview' 카테고리의 다른 글
백엔드 개발자 기술 면접 정리 - 운영체제(CS) (0) | 2024.03.19 |
---|---|
백엔드 개발자 면접 질문 모음 (답변 없음) (0) | 2024.03.19 |
백엔드 개발자 기술 면접 정리 - 네트워크(Web, HTTP, Network) (0) | 2024.02.12 |
백엔드 개발자 기술 면접 정리 - Spring, JPA (1) | 2024.02.10 |
백엔드 개발자 기술 면접 정리 - Java, 객체 지향 (0) | 2024.02.09 |