728x90

분류 전체보기 288

@PathVariable vs @RequestParam

Spring 환경에서 RestApi 를 정의할 때 항상 고민을 하게 되는 것이 자원을 식별하는 값을 동적으로 정의할 경우 @PathVariable, @RequestParam 중 어떤 것을 사용할 것이냐 이다. 예를 들어 특정 그룹의 카운트를 리턴하는 api 를 만든다고 할 때 아래 두가지 방법을 사용할 수 있다. @GetMapping("/target/admin/{groupSeq}/count") fun adminTargetCount(@PathVariable groupSeq: Long): ResponseEntity{ return ResponseEntity(pushService.adminTargetCount(groupSeq), HttpStatus.OK) } @GetMapping("/target/admin/co..

Backend/Spring+Boot 2022.03.07

[Kotlin] RequestBody 유효성 검증로직 추가하기

RequestBody에 할당되는 값에 대한 유효성 검증 방법에는 여러가지가 있을 것이다. Spring 환경이라면 대표적으로 @Valid 또는 @Validated 을 사용할텐데 여기에서는 직접 유효성 검증 로직을 추가하는 방법을 알아본다. 사실 이 방법은 Kotlin 에서만 국한된 것은 아니기 때문에 개념만 이해한다면 어디서든 사용할 수 있다. 우선 여기에서 @Valid와 @Validated 의 차이는 구체적으로 다룰 필요는 없겠지만 간단하게 말하면 그냥 @Validated 이 상위호환 이라고 보면 되고 아래부터 @Validated 로만 표현하겠다. @Validated 는 왜 사용하지 않았나? 단일 값의 유효성만 검증하는게 아니라 2개 이상 값의 조합도 검증하고 싶었다. 예를 들어 주민등록번호를 검증을 한..

Backend/Kotlin 2022.03.07

[SpringBatch] 주의사항

트랜잭션 Reader, Processor, Writer 구조 기준 PageSize 와 ChunkSize 를 설정할 수 있을 것이다. 이 의미를 정확하게 알고 사용할 필요가 있다. PageSize의 경우 여러 Reader 구현체에서 실제로 한번에 읽어올 row 단위를 의미한다. 이렇게 읽어온 row 를 Reader와 Processor 에서는 무조건 1 row씩 읽어서 처리한다. Writer 에서는 ChunkSize 가 사용되는데 ChunkSize 만큼 메모리에 row 결과가 쌓이면 그걸 한번에 처리한다. 여기에서 한번에 처리한다는 것은 트랜잭션 단위를 의미한다. 즉, DB트랜잭션 Start, End 상태에 해당하는 것이다. 이런 이유로 ChunkSize 중에서 특정 row를 별도로 CUD 작업 하고 싶다면..

Backend/Spring+Boot 2022.02.28

SpringBoot 환경에서 JAVA_OPTS, TOMCAT_OPTS

외부 Tomcat 을 사용할 경우 구동시 추가할 실행옵션이 필요할 경우 JAVA_OPTS 또는 TOMCAT_OPTS 환경변수에 추가해 놓으면 실행시 자동으로 참조한다. 예를 들어 startup.sh 로 구동시 -Xmx256m 같은 메모리 설정을 추가하고 싶다면 환경변수 JAVA_OPTS 를 추가해서 -Xmx256m 를 등록해놓으면 된다. 기본적으로 구동시 JAVA_OPTS, TOMCAT_OPTS 를 모두 참조하기 때문에 하나만 정의해도 되지만 공식메뉴얼에서는 Java 관련된 설정값은 JAVA_OPTS 에 Tomcat 관련된 설정값은 TOMCAT_OPTS 에 설정하길 권장한다. 그런데 SpringBoot 내장톰캣에는 이게 적용되지 않는다. 기본적으로 아래와 같이 어플리케이션 구동시 command line ..

Backend/Spring+Boot 2022.02.22

[Mysql] 커넥션 정보

Mysql 서버에서는 Sql 을 처리하기 위해 연결가능한 커넥션 수를 미리 설정해 놓고 사용한다. 그 이상의 연결이 요청될 경우 Too Many Connection Error 가 발생한다. 이를 미리 예방하고 적절한 수치를 찾기 위해 Mysql 에서 제공하는 여러 데이터가 있지만 여기에서는 간단하게 설정된 최대 커넥션 수와 현재 접속된 커넥션 수 정도를 체크할 수 있는 방법만 기록한다.(사실 상세하게 정리된 포스팅이 너무 많은데 대부분 복붙같고.. 뜻이 애매한게 많아 잘 모르겠다...) 아래 질의를 통해 현재 Mysql 에 셋팅된 최대 연결 가능한 커넥션 수를 확인할 수 있다. show variables where variable_name in ( 'max_connections'); 아래 질의를 통해 현..

Backend/Database 2022.02.17

[Kafka] Consumer Error Handling(retry, recovery)

spring-kafka 을 통해 Consumer 구현하면 컨슈밍이 실패했을 때 기본적으로 최초 요청을 포함해서 10회까지 재시도한다. 그리고 재시도가 모두 실패하면 해당 메시지 skip 된다. 만약 이러한 정책을 커스텀하게 운영하고 싶다면 ConcurrentKafkaListenerContainerFactory 을 재정의하면 된다. spring-kafka 2.8 이전 버전에서는 setRetryTemplate 을 통해 retry 정책을 정의하고 setRecoveryCallback 를 통해 recovery 로직을 정의하면 됐다. 그런데 spring-kafka 2.8 버전부터 setRetryTemplate 은 deprecated 되었고, setRecoveryCallback 는 아직 있지만 대부분 아래와 같이 s..

Backend/Kafka 2022.02.15

No serializer found for class org.hibernate.proxy.pojo.bytebuddy.ByteBuddyInterceptor and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS)

JPA를 사용하다가 위와 같은 에러가 발생하는 경우가 있다. 의외로 서칭하니 답은 빨리나왔는데 설명이 장황하여 간단하게 원인만 정리한다. Entity 에 포함되는 속성 중 FetchType.LAZY 로 명시한 속성이 아직 Fetch 전인데 해당 Entity 를 json 직렬화 하려 할 때 발생한다. 좀 더 자세히 이야기 하면 Entity의 해당 속성이 아닌 프록시로 감싸져있는 hibernateLazyInitializer 를 직렬화 하려 하기 때문에 발생한다. 다르게 말하면 FetchType.LAZY 로 명시한 속성은 반드시 Fetch 가 완료된 뒤에 json 직렬화를 해야 한다. 만약 그게 싫다면 아래와 같이 해당 속성을 아예 직렬화에서 제외시켜야 한다. https://ahndding.tistory.co..

Backend/JPA 2022.02.14

[Kafka] multi KafkaTemplate

SpringBoot 에서 Kafka 연동은 매우 간단하다. org.springframework.kafka:spring-kafka 의존성을 추가하고 application.yml 에 Kafka 관련 구성정보만 추가하면 된다. 그런데 서로 다른 여러개의 브로커를 동시에 참조해야 할 때는 이 방법을 사용할 수 없다. application.yml 에 Kafka 브로커 정보는 spring.kafka.bootstrap-servers 에 지정하고 "," 로 구분된 여러개의 브로커 host를 지정할 수도 있긴 한데 이는 HA, LB를 위한 구성으로 순차적으로 접근하되 정상적인 상태의 단일 브로커만 연결된다. 또한 HA, LB를 위한 구성인만큼 지정된 브로커들은 기본적으로 모두 동일한 토픽이 존재해야 한다. 서로 다른 여..

Backend/Kafka 2022.02.11

[Kafka] 삽질 기록..

카프카 프로듀서와 컨슈머를 예전에 개발한 경험이 있는데 이번에 다시 개발하려니 예전에 잘못알고 있던 것도 있었고 새로 알게된 것 중 모호했던 것들을 정리한다. 1. spring-kafka, spring-cloud-stream 예전에 프로듀서와 컨슈머를 만들 때에는 spring-kafka 의존성을 사용했다. 그런데 리서치하다보니 spring-cloud-stream 라는 의존성도 있었다. 사실 이 중 뭘 사용해도 상관은 없다. 차이가 있다면 spring-kafka 는 메시지큐 중 Kafka 에 종속적이고 spring-cloud-stream 는 Kafka 외에 RabbitMQ 같은 다른 메시지큐도 지원하기 때문에 구성이 좀 더 추상적이다. 이에 구현은 spring-kafka 이 더 쉽지만 기능은 spring-..

Backend/Kafka 2022.02.10
728x90