# Rate Limit이란?일정 시간 동안 호출될 수 있는 API 횟수를 제한하는 걸 말한다. 예를 들어 파일 업로드는 10분에 최대 3번만 가능 이런 걸 구현할 때 사용하는 개념이다. 자세한 건 아래글 참조https://gngsn.tistory.com/224 Rate Limiter, 제대로 이해하기Rate limiter의 역할과 강단점을 살펴보고, 구현 알고리즘 5가지를 이해하는 것이 해당 포스팅의 목표입니다. 본 포스팅의 모든 그림은 필자가 직접 그린 것으로 무단 사용을 금하며, 사용 시 출처gngsn.tistory.com 이번 글에서는 로컬 캐시 라이브러리로 유명한 Caffeine으로 Rate Limiter 기능을 구현해 볼 것이다. # 왜 Caffeine인가?Spring Cloud Gateway..
@Transactional로 감싸진 블록은 RuntimeException을 상속받는 예외를 맞이하면 자동적으로 롤백을 해준다. 그런데 간혹, 여러 데이터를 저장할 때 일부는 실패하더라도 트랜잭션이 성공했으면 바라는 경우가 있다. 그럴 때 Transaction silently rolled back because it has been marked as rollback-only라고 에러가 발생하면서 전체 롤백이 되는 경우가 있다. 왜 이런지 구체적으로 알아보도록 하자. # 예시 상황총 5명의 User의 포인트를 1씩 증가시켜가며 저장할 것이다.이때 포인트가 2이면 예외를 발생시킨다.예외가 발생하더라도 다른 User는 저장에 성공해야 한다.@Serviceclass UserTestService( priva..
서버 어플리케이션에서 DTO를 만들어서 사용하는 것은 아주 흔한 일이다. 이 글에서는 필자가 서버 어플리케이션을 개발할 때 사용하는 DTO 명명법과 역할에 대한 생각을 공유하고자 한다. # DTO의 명칭 필자는 DTO 이름을 명명할 때 다음과 같은 관례를 따르도록 작성하고 있다. ~Reqeust 요청 query param이나 request body, 컨트롤러가 받는 요청 객체 ex) UpdateUserNicknameRequest ~Response 응답 DTO ex) UpdateUserNicknameResponse Request,Response에는 꼭 행위(Create, Update, Get)를 붙힌다. 파일 정렬등을 고려하면 도메인명을 앞으로 빼도 무방하다 (UserUpdateNicknameRequest..
간혹 어플리케이션 외부에서 읽어오는 JSON 데이터 (외부 API나 JSON 파일 등)에서 JSON 포맷과 필드가 복잡한 경우가 많다. 이 경우 원하는 필드만 읽을 수 있도록 할 수도 있는데, 스프링 부트에서 기본적으로 내장되어있는 Jackson 라이브러리 설정을 다음과 같이 변경한다. @Configuration class JacksonConfig { @Bean fun objectMapper() = ObjectMapper().apply { configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) } } 예시로 대강 이런 JSON 파일을 읽어온다고 가정해보자 { "SJML": { "header": { "identifier": "텍스트_구어체 ..
서버에서 발생하는 로그를 슬랙으로 자동으로 전송하는 설정을 알아보자 # 웹훅 생성 https://mopil.tistory.com/159 [Spring Boot] Slack 메시지 보내기 어플리케이션에서 슬랙으로 메시지를 보내는 방법에 대해 공유한다. 토큰을 사용한 봇 방법과 웹훅 방법이 있는데, 여기서는 웹훅 방법을 통해 구현한다. # 웹훅 만들기 먼저 원하는 워크스페이 mopil.tistory.com 웹훅을 먼저 생성한다. 위 글을 참조할 것 # application.properties 및 기타 설정 위 구조로 설정파일들을 생성한다. application-dev.properties에서 logback 설정파일을 읽을 수 있도록 다음을 추가한다. (live도 동일) logging.config=classpa..
어플리케이션에서 슬랙으로 메시지를 보내는 방법에 대해 공유한다. 토큰을 사용한 봇 방법과 웹훅 방법이 있는데, 여기서는 웹훅 방법을 통해 구현한다. # 웹훅 만들기 먼저 원하는 워크스페이스로 들어간 다음 웹훅을 생성한다. add webhook을 누르면 이렇게 채널을 선택할 수 있다. 여기서 대표 채널 하나만 설정하고, 나중에 어플리케이션 레벨에서 하나의 웹 훅으로 여러 채널에서 공유해서 쓸거다. # SlackClient @Component class SlackClient( private val restTemplate: RestTemplate, @Value("\${slack.webhook.url}") private val webhookUrl: String, ) { data class SlackMessage..
코프링 환경에서 MySQL과 MongoDB 두 개를 연동하고 간단한 CRUD 예제를 만들어본다. MongoDB만 연동해보려 했으나, 보통 NoSQL 하나만 사용하는 경우는 드물기 때문에 RDBMS도 같이 연동해보기로 했다. https://github.com/mopil/spring-boot-mongo-mysql-sample GitHub - mopil/spring-boot-mongo-mysql-sample: mysql, mongodb 연동 예제 mysql, mongodb 연동 예제. Contribute to mopil/spring-boot-mongo-mysql-sample development by creating an account on GitHub. github.com # 기본 설정 dependencie..
로컬과 EC2 환경을 분리하는 작업을 정리한다. AWS CloudWatch 로깅을 해놨는데, 개발환경에서 부팅할 때도 모두 로그가 남아져서 이를 분리하고자 했다. resource 폴더 자체를 나눌 수도 있지만, 여기서는 application.yml 파일을 나누는 것을 다룬다. (firebase 디렉토리와 apple_sign_key는 무시하자. 여기서 필요 없다.) 이런 식으로 하나의 resources 폴더 안에 yml파일 이름으로 분리할 것이다. # application.yml spring: profiles: default: secret-local jpa: properties: hibernate: dialect: org.hibernate.dialect.PostgreSQLDialect 먼저 기본 설정파일을..