728x90
상품 상세 조회 시, 데이터베이스로부터 매번 데이터를 가져오는 것은 성능 저하를 초래할 수 있습니다. 이를 개선하기 위해 캐싱을 도입할 수 있습니다.
Product Entity
@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Table(name = "products")
public class Product extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String category;
@Column(nullable = false)
private Integer price;
@Column(nullable = false)
private Integer quantity;
@Column(nullable = false)
private String description;
}
ProductController
@RestController
@RequiredArgsConstructor
@RequestMapping("/api/products")
public class ProductController {
private final ProductService productService;
@GetMapping("/{id}")
public ResponseEntity<Product> getProductById(@PathVariable Long id) {
return productService.getProductById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
}
ProductService
@Service
@RequiredArgsConstructor
public class ProductService {
private final ProductRepository productRepository;
public Optional<Product> getProductById(Long id) {
return productRepository.findById(id);
}
}
ProductRepository
@Repository
public interface ProductRepository extends JpaRepository<Product, Long> {
}
Get요청으로 /api/products/1 상품 상세 정보 조회를 할 경우
이 와 같은 결과를 확인 할 수 있다.
build.gradle
implementation 'org.springframework.boot:spring-boot-starter-cache'
캐싱 관련 의존성을 추가
캐싱을 활성화하기 위해 @EnableCaching 어노테이션을 추가합니다.
Entity 수정
@Entity
@Getter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Table(name = "products")
public class Product extends BaseTimeEntity implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String category;
@Column(nullable = false)
private Integer price;
@Column(nullable = false)
private Integer quantity;
@Column(nullable = false)
private String description;
}
ProductService 수정
@Service
@RequiredArgsConstructor
@CacheConfig(cacheNames = "products")
public class ProductService {
private final ProductRepository productRepository;
@Cacheable(key = "#id")
public Optional<Product> getProductById(Long id) {
return productRepository.findById(id);
}
}
@CacheConfig 및 @Cacheable 어노테이션을 사용하여 캐싱을 적용합니다.
JMeter 테스트 결과
- 캐싱 적용 전
- 평균 응답 시간: 20ms
- 최소 응답 시간: 14ms
- 최대 응답 시간: 108ms
- 표준 편차: 6.54
- 캐싱 적용 후
- 평균 응답 시간: 8ms
- 최소 응답 시간: 5ms
- 최대 응답 시간: 50ms
- 표준 편차: 3.42
캐싱 적용 전
- 모든 요청에 대해 데이터베이스를 조회
- 높은 응답 시간과 데이터베이스 부하
캐싱 적용 후
- 첫 번째 요청 이후 동일한 데이터는 캐시에서 조회
- 응답 시간 단축 및 데이터베이스 부하 감소
결과 분석
캐싱을 적용한 후, 응답 시간이 크게 개선되었습니다. 평균 응답 시간은 약 60% 감소하였고, 최대 응답 시간 또한 크게 줄어들었습니다. 표준 편차가 줄어든 것도 응답 시간의 일관성이 높아졌음을 의미합니다.
728x90
'IT 개발 관련 > [프로젝트]' 카테고리의 다른 글
[예약 구매] 자동화 테스트 툴 (0) | 2024.07.27 |
---|---|
[예약구매] 재고 감소 동시성 테스트 (0) | 2024.07.21 |
MySQL transaction_isolation 문제 (0) | 2024.06.21 |
[예약구매] API 문서 작성 (0) | 2024.06.20 |
[예약구매] Docker Compose 로컬 개발 환경 구축 (0) | 2024.06.20 |