Files
test/COMMON_CODE_CACHE_REDIS.md
2025-12-08 11:20:45 +09:00

283 lines
7.7 KiB
Markdown

# 공통코드 Redis 캐시 시스템 - DanielLee
## 요구사항 검토
### 1. **API를 통해 공통코드 제공**
- **구현 완료**: `CommonCodeApiController`에서 전체 공통코드 조회 API 제공
```
GET /api/code
→ 모든 공통코드 조회
```
- **추가 구현**: 캐시 갱신 및 상태 확인 API
```
POST /api/code/cache/refresh → 캐시 갱신
GET /api/code/cache/status → 캐시 상태 확인
```
---
### 2. **애플리케이션 로딩시 Redis 캐시에 올리기**
- **구현 완료**: `CommonCodeCacheManager` 클래스 생성
#### 초기화 메커니즘
```java
@Component
@RequiredArgsConstructor
public class CommonCodeCacheManager {
@EventListener(ApplicationReadyEvent.class)
public void initializeCommonCodeCache() {
// 애플리케이션 완전히 시작된 후 공통코드를 Redis에 미리 로드
List<Basic> allCommonCodes = commonCodeService.getFindAll();
// @Cacheable이 자동으로 Redis에 캐시함
}
}
```
#### 동작 흐름
1. 애플리케이션 시작
2. Spring이 모든 Bean 생성 완료 (`ApplicationReadyEvent` 발생)
3. `CommonCodeCacheManager.initializeCommonCodeCache()` 실행
4. `commonCodeService.getFindAll()` 호출 (DB에서 조회)
5. `@Cacheable(value = "commonCodes")` 에노테이션이 결과를 Redis에 저장
---
### 3. **공통코드 변경시 데이터 갱신**
#### 자동 갱신
- **등록 (CREATE)**: `@CacheEvict` → 캐시 전체 삭제
- **수정 (UPDATE)**: `@CacheEvict` → 캐시 전체 삭제
- **삭제 (DELETE)**: `@CacheEvict` → 캐시 전체 삭제
- **순서 변경**: `@CacheEvict` → 캐시 전체 삭제
```java
@CacheEvict(value = "commonCodes", allEntries = true)
public ResponseObj save(CommonCodeDto.AddReq req) {
// 공통코드 저장
// ↓
// 캐시 전체 삭제 (다음 조회 시 DB에서 새로 로드)
}
```
#### 수동 갱신 (관리자)
```java
POST /api/code/cache/refresh
```
- 공통코드 설정이 변경된 후 API를 호출하여 캐시를 강제 갱신
#### 캐시 상태 모니터링
```java
GET /api/code/cache/status
→ 응답: { "data": 150 } // 캐시된 공통코드 150개
```
---
## 전체 아키텍처
```
┌─────────────────────────────────────────────────────────┐
│ 클라이언트 요청 │
└──────────────────┬──────────────────────────────────────┘
┌──────────▼──────────┐
│ CommonCodeApiController
└──────────┬──────────┘
┌─────────┴──────────┐
│ │
┌────▼─────┐ ┌──────▼────────────┐
│ 조회 API │ │ 캐시 관리 API │
│ (GET) │ │(POST, GET) │
└────┬─────┘ └──────┬────────────┘
│ │
│ ┌────────▼──────────┐
│ │CommonCodeCacheManager
│ │(캐시 초기화/갱신) │
│ └────────┬──────────┘
│ │
┌────▼─────────────────┬─▼────┐
│ CommonCodeService │ │
│ (@Cacheable) │ │
│ (@CacheEvict) │ │
└────┬──────────────────┴──────┘
┌────▼──────────┐
│ Redis 캐시 │
│ (공통코드) │
└────┬──────────┘
┌────▼──────────┐
│ PostgreSQL DB │
│ (공통코드) │
└───────────────┘
```
---
## API 명세
### 1. 공통코드 조회 (캐시됨)
```
GET /api/code
응답:
{
"data": [
{
"id": 1,
"code": "STATUS",
"name": "상태",
"description": "상태 공통코드",
"used": true,
...
},
...
]
}
```
### 2. 공통코드 캐시 갱신
```
POST /api/code/cache/refresh
응답:
{
"data": "공통코드 캐시가 갱신되었습니다."
}
```
### 3. 캐시 상태 확인
```
GET /api/code/cache/status
응답:
{
"data": 150 // Redis에 캐시된 공통코드 개수
}
```
---
## 캐시 갱신 흐름
### 자동 갱신 (CRUD 작업)
```
관리자가 공통코드 등록/수정/삭제
CommonCodeService.save() / update() / removeCode()
(@CacheEvict 실행)
Redis 캐시 전체 삭제
다음 조회 시 DB에서 새로 로드
```
### 수동 갱신 (API 호출)
```
관리자: POST /api/code/cache/refresh
CommonCodeCacheManager.refreshCommonCodeCache()
캐시 정리 + 새로운 데이터 로드
Redis 캐시 업데이트 완료
```
---
## 성능 최적화 효과
| 항목 | 개선 전 | 개선 후 |
|------|--------|--------|
| **조회 속도** | DB 직접 조회 (10-100ms) | Redis 캐시 (1-5ms) |
| **DB 부하** | 매번 조회 | 캐시 미스시만 조회 |
| **네트워크 대역폭** | 높음 (DB 왕복) | 낮음 (로컬 캐시) |
| **응답 시간** | 변동적 | 일정 (캐시) |
---
## 추가 기능
### CommonCodeUtil - 전역 공통코드 조회
```java
@Component
public class CommonCodeUtil {
// 모든 공통코드 조회 (캐시 활용)
public List<Basic> getAllCommonCodes()
// 특정 코드로 조회
public List<Basic> getCommonCodesByCode(String code)
// ID로 단건 조회
public Optional<Basic> getCommonCodeById(Long id)
// 코드명 조회
public Optional<String> getCodeName(String parentCode, String childCode)
// 하위 코드 조회
public List<Basic> getChildCodesByParentCode(String parentCode)
// 코드 사용 가능 여부 확인
public boolean isCodeAvailable(Long parentId, String code)
}
```
### 사용 예시
```java
@RequiredArgsConstructor
@RestController
public class SomeController {
private final CommonCodeUtil commonCodeUtil;
@GetMapping("/example")
public void example() {
// 1. 모든 공통코드 조회 (캐시됨)
List<Basic> allCodes = commonCodeUtil.getAllCommonCodes();
// 2. 특정 코드 조회
Optional<String> name = commonCodeUtil.getCodeName("PARENT", "CHILD");
// 3. 코드 사용 가능 여부 확인
boolean available = commonCodeUtil.isCodeAvailable(1L, "NEW_CODE");
}
}
```
---
## 완료 체크리스트
- Redis 캐싱 어노테이션 적용 (@Cacheable, @CacheEvict)
- 애플리케이션 로딩시 캐시 초기화
- CRUD 작업시 자동 캐시 갱신
- 수동 캐시 갱신 API 제공
- 캐시 상태 모니터링 API
- 전역 공통코드 조회 유틸리티
- 포괄적인 유닛 테스트 (12개)
---
## 모니터링
캐시 상태를 주기적으로 모니터링:
```bash
# 캐시 상태 확인
curl http://localhost:8080/api/code/cache/status
# 캐시 갱신
curl -X POST http://localhost:8080/api/code/cache/refresh
```
로그 확인:
```
=== 공통코드 캐시 초기화 시작 ===
✓ 공통코드 150개가 Redis 캐시에 로드되었습니다.
- [STATUS] 상태 (ID: 1)
- [TYPE] 타입 (ID: 2)
...
=== 공통코드 캐시 초기화 완료 ===
```