Spring Data Redis (1) 캐시와 Redis 글에 이어 작성합나다. Redis를 원격 캐시 저장소로 사용하는 방법을 알아보겠습니다.
레디스 서버는 도커를 사용할 예정입니다. 도커를 사용해본 적이 없다면 Docker 시작하기 기본 명령어를 참고해주세요. 필요한 것 위주로 나열해서 잘 정리되지는 않았지만 포스팅에 적힌 명령어만 알아도 우선 도커 위에 레디스 서버를 띄우는건 문제가 없을거에요.
목차
1. 사용 방법
2. 도커 설정
3. API 호출을 통한 검증
사용 방법
Spring Data Redis Reference를 주로 참고해서 작성하겠습니다. 우선 스프링 부트 환경에서 개발할 것이기 때문에 아래 의존성을 추가해줍시다.
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
의존성을 주입받고 다시 빌드하게되면 아래 프로젝트들이 들어오게 됩니다.
Lettuce는 레디스 서버와 통신하기 위한 클라이언트 라이브러리입니다. Jedis 라는 클라이언트 라이브러리도 있는데 따로 설정하지 않으면 디폴트로 Lettuce가 들어오게 됩니다.
몇 가지 설정을 합시다. 클라이언트 라이브러리를 빈으로 등록하고 데이터베이스 연결 및 커넥션 풀을 관리할 RedisTemplate도 빈으로 등록해야 합니다.
@Configuration
public class RedisConfig {
@Value("${spring.data.redis.port}") // (1)
public int port;
@Value("${spring.data.redis.host}")
public String host;
@Bean // (2)
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
@Bean // (3)
public RedisTemplate<?, ?> redisTemplate() {
RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
(1) 호스트와 포트를 등록해야 합니다. 일반적으로 @Value는 숨기고 싶은 정보를 매핑할 때 사용하는 것으로 알고 잇습니다. 아래 설정 파일의 값들이 매핑됩니다.
application.yml
spring:
data:
redis:
host: localhost
port: 6379
(2) RedisConnectionFactory는 Redis 연결 ,커넥션 풀 관리 등의 역할을 합나다. 해당 구현체를 결정해서 빈으로 등록해줍시다.
(3) RedisTemplate은 Repository 라고 생각하면 됩니다. RedisConnectionFactory를 통해 CRUD 작업을 할 수 있습니다. Spring Data 프로젝트를 통해 편리하게 사용할 수 있습니다. RedisTemplate 을 직접 사용해서 redis가 지원하는 다양한 데이터 자료 구조를 이용할 수 있습니다. (나중에 따로 테스트 해보도록 하겠습니다.)
이제 설정을 마쳤으니 레디스 엔티티와 Repository를 만들겠습니다.
Entity
@RedisHash(value = "refreshToken", timeToLive = 60) // (1)
public class RefreshToken {
@Id // (2)
private String refreshToken;
private Long memberId;
private LocalDateTime createAt;
public RefreshToken(String refreshToken, Long memberId) {
this.refreshToken = refreshToken;
this.memberId = memberId;
this.createAt = LocalDateTime.now();
}
}
(1) 레디스 엔티티를 사용하려면 @RedisHash 애노테이션을 사용합니다. value 파라미터는 key의 prefix를 의미합니다.
이런 식으로 key 앞에 프리픽스로 붙습니다. redis-cli에서 key를 찾기 위해서는 prefix까지 포함해서 적어야 합니다.반면 애플리케이션 레벨에서는 prefix를 제외하고 @Id가 매핑된 필드 값만 적어주면 해당 value를 불러올 수 있습니다.
timetoLive는 만료 시간이고 단위는 초입니다. TTL이라고도 불리기도 하는데 메모리를 사용하는만큼 적절한 TTL 설정이 중요한 것으로 알고 있습니다. (Redis 영상이나 JVM 모니터링 포스팅들에 항상 나오는 말들!)
(2) @Id 는 org.springframework.data.annotation.id; 를 사용합니다. JPA @Id가 아닙니다.
Repository
public interface RefreshTokenRepository extends CrudRepository<RefreshToken, String> { // (1)
Optional<RefreshToken> findByMemberId(Long memberId);
}
(1) CrudRepository 인터페이스를 상속해줍니다. 혹시 레포짓토리가 동작하지 않는다면 설정 파일에@EnableRedisRepositories을 추가해주세요.
이제 끝났습니다.
도커 설정
우선 리눅스가 아닌 윈도우 환경이기 때문에 Docker Desktop으로 도커를 켜겠습니다. 그리고 인텔리제이 IDE에서 제공하는 PowerShell 터미널을 사용해서 도커 명렁어를 사용하겠습니다. 도커 허브 - redis를 참고하셔도 됩니다.
레디스 인스턴스 실행 및 포트포워딩
docker run -p [호스트 포트]:[컨테이너 포트] --name [컨테이너 이름] redis
호스트와 컨테이너 포트를 연결해야 합니다. 그래야 통신을 할 수 있습니다. 호스트 포트는 원하는대로 설정할 수 있어요. 아마 컨테이너 포트는 서버마다 다 다를겁니다. redis는 기본적으로 6379포트를 사용하는 것 같아요. 그래서 컨테이너 포트 자리에 6379를 사용했습니다.
현재 실행중인 컨테이너 확인
docker ps
잘 실행중인것을 볼 수 있습니다. 이제 구성은 끝났습니다. 저는 아래 호스트 포트가 6379인 것으로 테스트를 하도록 하겠습니다. 위 설정에서 호스트 포트를 6379로 설정했었거든요!
API 호출을 통한 검증
POST 요청을 보낼 때 리프래시 토큰이 만들어지는 API를 하나 만들었습니다.
@PostMapping("/token/{member-id}")
public String issue(@PathVariable("member-id") Long memberId) {
RefreshToken token = new RefreshToken(UUID.randomUUID().toString(), memberId);
repository.save(token);
return "토큰 발급 완료 " + token.getRefreshToken();
}
검증은 Redis CLI를 통해 하겠습니다. 터미널에 아래 명령어를 입력합니다. 현재 터미널이 컨테이너가 실행중인 상태라만 새로 터미널을 만들어서 진행하면 됩니다 :)
docker exec -it [컨테이너 ID] redis-cli
이제 레디스 명령어를 사용할 수 있습니다. 우선 현재 만들어진 엔티티의 데이터 구조를 확인해봅시다.
type [prefix] //엔티티 @RedisHash value 값
결과는 set입니다. 예제가 조금 이상하긴 합니다. 실제라면 key 값에 memberId를 넣고 value에 리프래시 토큰 값을 넣으면 됩니다.
API 호출하겠습니다. POST /token/2
레디스에 추가 됐는지 확인해봅시다.
keys [pattern]
정상적으로 추가된 것을 확인할 수 있습니다. 레디스는 key:value 구조라고 했죠? 한 번 value도 확인해봅시다.
정상적으로 저장이 됐군요. 위에서 엔티티를 만들 때 TimeToLive 를 60초로 설정했습니다. 1분이 지난 뒤 다시 keys를 검색해보겠습니다.
예상대로 없어진 것으로 보여집니다.
이렇게 레디스를 사용하는 방법에 대해서 아주아주 간단하게나마 알아보았습니다.
'Spring' 카테고리의 다른 글
@TransactionalEventListener (0) | 2023.06.22 |
---|---|
Spring Data Redis (3) 모니터링 cli, redis-stat (0) | 2023.06.13 |
spring cache (2) 테스트 케이스 작성하기 CacheManager 활용 (0) | 2023.06.02 |
spring cache (1) 스프링 캐시 컨셉 이해하기 (0) | 2023.06.02 |
DDD - 이벤트의 장점, 용도 그리고 구조 (0) | 2023.05.26 |