본문 바로가기

Spring-Boot

(8)
테스트 코드의 여러가지 팁 깔끔한 Application.class 유지하기@ComponentScan({"com.sample.product"})@EnableJpaAuditing@ConfigurationPropertiesScan@SpringBootApplicationpublic class SampleApplication {}메인 애플리케이션 클래스에 @ComponentScan과 같은 어노테이션을 추가하면, 애플리케이션이 로드될 때 불필요한 스캔이 이루어질 수 있다. 이는 특히 테스트 환경에서 문제가 될 수 있다. 예를 들어 @WebMvcTest를 사용하여 컨트롤러 단위 테스트를 수행할 때, 이 어노테이션은 기본적으로 컨트롤러와 관련된 컨포넌트(application.class 포함)만 스캔한다. 이때 @ComponentScan이 app..
Redis 를 사용한 Distributed Lock 분산 환경에서 서로 다른 클라이언트가 공유 리소스를 사용하는 경우동시성 문제가 발생할 수 있으며Redis를 사용하여 원자성을 보장할 수 있다.분산 환경에서 다양한 클라이언트가 공유 리소스를 사용할 때 동시성 문제가 발생할 수 있으며이러한 문제를 해결하기 위해 Redis를 사용하여 원자성을 보장할 수 있다.Spin LockRedis에서는 SET NX (SET if Not Exists)라는 명령을 통해 값이 존재하지 않을 때만 설정할 수 있다. 이를 활용하여 Lock 메커니즘을 구현할 수 있다.💡 NX의 명령 구성은 key, value, 유지시간(ms)으로 구성된다. 스핀 락은 클라이언트가 값을 설정할 때까지 SET NX 명령을 반복 시도하여 락을 획득하는 방법이며 아래는 Spin Lock의 작동 방식이다..
JpaRepository 가 아닌 Repository를 상속 받아 CQRS 로 분리하기 @Repository public interface MemberRepository extends JpaRepository, CustomMemberRepository { } 위같이 흔히 볼 수 있는 JpaRepository + CustomRepository 조합에서 데이터베이스는 하나지만 왠지 모르게 저 인터페이스를 CQRS로 분류하고 싶은 순간이 다들 한 번쯤 올 것이다.(아님 말고) CQRS의 Command를 담당할 Repository의 이름을 MemberCommandRepository로 Query를 담당할 Repository의 이름을 MemberQueryRepository라고 한다면 어떻게 구성할수있을까? @Repository public interface MemberQueryRepository ex..
API Controller 주변 청소하기 spring boot를 사용하여 api 개발을 하면서 swagger을 함께 사용하다 보면 많은 API들이 다들 위와 같은 모습을 하고 있는 게 뭐랄까.. 애정이 안 간다. 코드를 아래의 기준으로 정리를 하여 애정이 생길만한 이쁜 모습으로 바꿔보려 한다. 한눈에 보기 좋을 것 중복 코드가 없을 것 api 파라미터는 스네이크 케이스이고 controller 인자는 카멜 케이스 일 것 @ApiOmplicitParams 만 사용하기 @ApiOperation(value = "주문 조회") @ApiImplicitParams({ @ApiImplicitParam(name = "productId", value = "제품 id", required = false, dataType = "string", paramType = "..
이벤트 페이지 그리고 데드락.. 그리고 FK 로 인한 공유 잠금.. 그리고 비관적 잠금.. 서비스에서 이벤트를 쿠폰으로 뿌리게 되면 엄청난 트래픽으로 인해 장애를 경험한적은 다들 한번쯤 있을것이다. 근데 나는 없다. 그래서 나는 혼자 이벤트를 만들고 혼자 참여하고 혼자 장애를 경험하고 혼자 고쳐보려 했다. 개발하는 어플리케이션은 정해진 쿠폰 수가 있고 쿠폰 재고가 끝날때까지 쿠폰을 받아갈수있는 이벤트이다. Event 엔티티와 Coupon 엔티티를 작성한다. @Entity @Table(name = "tb_event") @NoArgsConstructor @Getter @EqualsAndHashCode public class Event { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(unique = ..
Spring @Bean 과 @Component Spring 에서 IOC Containe 에 의해 관리되는 Spring Bean 을 사용하기위해서는 등록하는 과정이 있어야하는데 Bean 을 등록하는 어노테이션으로는 @Bean 과 @Component 가 있다. 둘다 Bean 을 등록하도록 하는 기능이지만 용도가 다르다. @Bean Bean의 @Target 를 보면 METHOD 로 되어있어 메소드 위에 부착하는 어노테이션이라는것을 알수있다. @Target({ElementType.METHOD, ElementType.ANNOTATION_TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Bean {} 외부라이브러리 와 같이 개발자가 직접 제어가 불가능한 Bean 을 생성하려할때 사..
Spring Boot 및 DB 모니터링 시스템 구축 Spring Boot Actuator Spring Boot Actuator 는 다양한 엔드포인트를 통해 모니터링을 지원하는 라이브러리. 이를통해 실행 중인 호스트와 애플리케이션의 상태 정보, 메모리 사용량, 요청 횟수, HTTP 엔드포인트 등 다양한 정보를 확인 의존성 추가 //Spring Boot Actuator implementation 'org.springframework.boot:spring-boot-starter-actuator' runtimeOnly 'io.micrometer:micrometer-registry-prometheus' Spring Boot Actuator 는 자체적으로 다양한 엔드포인트를 제공하고있다 예로 /actuator/health 에 접근하면 헬스체크 엔드포인트로 {stat..
@RequestBody 동작 이해하기 API 의 Body 를 통해 JSON 데이터를 받기위해 @RequestBody 를 사용하여 받는다. 이는 JSON,XML 과 같은 HTTP 데이터 형식을 JSON 으로 변환한다. 스프링 내부에서 HttpMessageConverter을 통해 알맞는 오브젝트로 변환된다. 일단 간단한 API를 작성해서 확인해보자 @PostMapping("/request-body") public String requestBodyTest(@RequestBody RequestBodyTestDto requestBodyTestDto){ return requestBodyTestDto.getParamString(); } public class RequestBodyTestDto{ private String name; private int ..