문제패스워드 변경을 서비스 레이어에서 처리할 경우, 서비스 레이어를 우회하여 객체를 직접 생성하는 실수가 발생하면 도메인 내부에 검증된 값이 존재함을 보장할 수 없습니다.특히, 패스워드 암호화와 같은 규칙은 실수로 인해 치명적인 결과를 초래할 수 있으므로, 이러한 실수가 발생할 가능성 자체를 없애고 싶었습니다.@Service@Transactional@RequiredArgsConstructorpublic class MemberService { private final MemberRepository memberRepository; private final CustomPasswordEncoder passwordEncoder; public void save(final MemberSaveReque..
현재 서버에서 Scheduler를 사용하는 중이고 Scheduler가 어떻게 동작하는지 알아 볼려고합니다.단일 스레드에서 스케줄링 작업들을 순차적으로 처리@Configurationpublic class ScheduledTasks { private final Logger log = LoggerFactory.getLogger(ScheduledTasks.class); @Scheduled(fixedRate = 1000) // 1초마다 taskA를 실행합니다. public void taskA() throws InterruptedException { Thread.sleep(10000); // 10초 동안 일시 중단합니다. log.info("taskA - {} - {}", L..
저는 현재 국내 가상화폐 거래소에 *스테이블 코인 가격 알림 서비스를 운영하고 있습니다.가상화폐 거래소는 증권시장과 다르게 거래소마다 독자적으로 운영(상장, 거래, 정산 등)하는 방식이라 거래소마다 서로 다른 API를 제공합니다. 문제는 각각의 거래소가 제공하는 Response가 모두 다르기 때문에, 저희 서비스에서 이를 바로 호환하기 어렵다는 점입니다.*스테이블코인은 달러화 등 기존 화폐에 고정 가치로 발행되는 암호화폐를 말한다. 문제점@FeignClient(name = "Bithumb", url = "https://api.bithumb.com/public")public interface BithumbClient { @GetMapping("/ticker/{symbol}_{currency}") ..
Spring Scheduler를 사용할 때, 같은 작업을 하는 스케줄러가 다중 인스턴스 환경에서 중복 실행되는 문제가 있습니다.이 문제를 해결하기 위해 Quartz, ShedLock 등을 고려할 수 있습니다. 저는 그 중 ShedLock을 선택했는데, 그 이유는 해결하려는 문제가 클러스터 안의 서버 노드 중 스케줄링 작업을 선택하거나 예외 처리 등의 기능이 필요한 것이 아니라, 단순히 중복 작업을 방지하는 데 ShedLock이 충분하다고 판단했기 때문입니다단일 환경에서 중복 실행 문제 위에서 설명한 중복 실행 문제는 모두 다중 인스턴스 환경에서 발생할 수 있지만, 단일 환경에서도 중복 실행 문제가 발생할 수 있습니다.단일 환경에서 운영되는 서버라도 Blue/Green 무중단 배포 상황에서 두 개의 인스턴..
기존 배포 환경의 문제점 기존에는 빌드/배포 자동화를 위해서 Github Action에 Self-hosted Runner를 사용했습니다 하지만 Self-hosted Runner를 사용하면서 여러 불편한점이 있었습니다. 환경 변수 관리 문제 첫 번째로, 환경 변수의 관리가 어려웠으며, 어떤 값이 설정되었는지 알기 힘들었습니다. 단일 장애 지점(SPOF) 발생 두 번째로, 러너를 배포하기 위해 서버에 직접 설치해야 했는데, 이는 러너에 문제가 발생할 경우 단일 장애 지점(SPOF)으로 이어질 수 있습니다. 실제로 배포중에 메모리가 부족해서 서버가 다운되는 경우가 종종 있어서 가상 메모리를 추가했었습니다. 예상 치 못한 문제 추가적으로, 러너가 종료될 때 고아 프로세스들이 함께 종료되어서 서버가 다운되는 문제..
코틀린답게 JPA Entity 작성하기 @Entity public class Parents { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; ... } 자바에서는 일반적으로 GeneratedValue를 사용해 id를 설정하며, 별도로 id 값을 초기화하지 않습니다. @Entity data class Parents( @Id @GeneratedValue(strategy = GenerationType.IDENTITY) val id: Long?, ) { } 하지만 코틀린의 Null Safety 특성 때문에 id를 초기화하지 않고 null 상태로 둘려면 ?를 사용하여 null을 허용해야 합니다. 이는 코틀린의 Null Safety..
logging: level: org.hibernate.type.descriptor.sql.BasicBinder: TRACE spring: jpa: properties: hibernate: format_sql: true show-sql: true SpringBoot 2 버전에서는 위와 같이 작성한 application.yml 을 프로젝트에서 사용하는 SpringBoot 3 버전에서 사용했을때 binding parameter가 표시되지 않았다. 이유는 SpringBoot 3 부터는 Hibernate 6 버전을 사용하는데 Hibernate 6 버전에서 BasicBinder가 Rename 되었다. spring: h2: console: enabled: true datasource: generate-unique-n..
FeignClient 란? Feign Client란 Netflix에서 개발한 Http Client다. 카카오 소셜로그인 카카오 토큰을 받는 API는 x-www-form-urlencoded 타입이 필수값이다. x-www-form-urlencoded 타입은 Spring에서 @RequestParam, @ModelAttribute 어노테이션으로 주입받을 수 있다. 둘중에 하나를 선택해야하는데 @RequestParam은 사용하고싶지않았다. @RequestParam 단일 파라메터 @FeignClient(url = "https://kauth.kakao.com", value = "kakaoAuthApi") public interface KakaoAccessTokenClient { @PostMapping( value =..
Flyway 란? Flyway is an open-source database migration tool. Flyway 공식 홈페이지를 보면 Flyway를 데이터베이스 마이그레이션 도구 라고 소개한다. 데이터베이스 마이그레이션 도구란? 데이터베이스 마이그레이션 도구는 버전 관리를 통해 여러 버전의 데이터베이스 스키마와 데이터 변경을 추적할 수 있고, 롤백 기능으로 변경 사항을 쉽게 되돌릴 수 있으며, 테스트 작업을 지원하여 데이터베이스 변경 사항을 안전하게 검증하고 적용할 수 있도록 도와줍니다 Flyway를 사용하면서 발생한 문제점 Flyway에는 규칙이 몇가지 존재하는데 migration 되었던 sql 파일이 변경될 경우 체크섬 검증이 실패하며, migration 이 수행되지 않습니다. sql 파일 네..
Comment @Getter @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Comment extends BaseEntity { private Long roomId; @Column(length = 500) private String comment; @ManyToOne(targetEntity = Member.class, fetch = FetchType.LAZY) @JoinColumn(name = "member_id") private Member member; ... } Member @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Me..
- Total
- Today
- Yesterday
- dto 검증
- User Scenario
- @Converter
- dto 위치
- JPA SQL Injection
- entity 검증
- DispatcherServletInitializer
- BasicBinder
- 유저 시나리오
- defer-datasource-initialization
- @FormProperty
- WebFlux 의존성
- Spring Boot 3
- CreationTimestamp
- 구글 OpenID
- java 17
- HTTPInterface
- setDateFormat
- ServletContainerInitializer
- ValidateException
- HandlesTypes
- CreatedDate
- 레이어드 아키텍처
- Attribute Converter
- @ElementCollection
- org.springframework:spring-webflux
- 구글 소셜로그인
- FormProperty
- feignClient
- 유저 스토리
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |