728x90
SpringEvent와 MessageQueue기존에 MessageQueue로서 RabbitMQ, Kafka를 고려할 때 이와 비슷한 역할을 하는 SpringEvent도 후보에 있었다.SpringEvent도 이벤트 기반의 비동기 프로그래밍을 지원하는 아이인데 추가적인 외부 도구 설정은 필요없다. 내부에서 비동기 작업이나 트리거 처리를 간소화할 수 있고, Application 내에서 처리가 되니 디버깅이나 로깅도 편하다. 간편한데 안 쓴 이유분산환경에는 얘가 알맞지 않다. 그야 SpringEvent는 이벤트의 발생과 Listener 호출이 동일한 JVM내에서 처리하다보니, A애플리케이션에서 발생한 Publish 호출을 B 애플리케이션의 Listener가 알 리가 없다. 클러스터 환경에선 다른 서버 노드로이벤..
ExceptionException은 프로그램 실행 중에 발생하는 오류상황이다. 가령 없는 파일을 읽거나 잘못된 인덱스를 참조하는 등 많은 예외가 발생한다. 그리고 이들은 Checked Exception과 Unchecked Exception으로 분류를 할 수 있다. Checked ExceptionChecked Exception은 '컴파일 시점'에 처리 여부를 확인해야 하는 예외다. 즉, 코드 작성 때 반드시 처리해야한다. 처리하지 않으면 컴파일러가 오류를 발생시킬 것이므로, try-catch 블록으로 처리하거나 throws 키워드를 선언해주는 것이 예방책이다.import java.io.BufferedReader;import java.io.FileReader;import java.io.IOException..
JPA의 N+1 문제 발생 이유와 해결방법(ft. Featch 전략) JPA의 N+1 문제N+1 문제는 연관된 데이터를 로딩할 때 발생하는 성능 문제다. 예를 들어, 하나의 엔티티(A)가 연관된 엔티티(1, 2, 3… N)를 가질 때, 한 번의 조회로 A를 가져오고, 이후 연관된 N개의 엔티티를 각각 따로 조회하는 상황이 된다.이러한 경우, 총 N+1개의 쿼리가 발생하므로 불필요하게 많은 데이터베이스 Query가 실행된다.// User와 Order는 일대다 관계List users = userRepository.findAll(); // User에 대한 1번의 쿼리for(User user : users){ List orders = user.getOrders(); // 각 Order에 대한 총 N번의 쿼리} ..
JPA의 영속성 컨텍스트영속성 컨텍스트는 JPA가 Entity 객체를 상태관리하는 공간 및 매커니즘이다.자세히는 엔티티의 상태를 메모리 상에 올려 놓고, Datsbase와의 동기화를 관리하는 공간으로 볼 수 있다. 이 공간에 올라간 객체는 변경 사항을 추적할 수 있게 되고 트랜잭션이 끝나는 시점에 Database에 반영된다. 1. 영속성 상태JPA의 영속성 컨텍스트 내에서 관리되는 Entity는 네 가지의 상태를 갖는다비영속(Transient)Database와 전혀 관련이 없는, 단순 메모리 상에만 존재하는 상태영속(Persistent)영속성 컨테스트에 의해 관리되고 있는 상태준영속(Detached)영속 상태에서 벗어나 분리된 상태삭제(Removed)Database에서 삭제 예정인 상태(트랜잭션이 커밋..
Scheduler 설정 구조@DependsOn({"..."})@Configurationpublic class ConfigScheduling { @Bean public JobDetail ...JobDetail(){ return JobBuilder.nowJob(잡.class) .withIdentity(잡.class.getSimpleName()) .storeDurable(true) .build(); } @Bean public Trigger ...JobTrigger(){ ... return trigger.newTrigger() .withIdentity(잡.c..
WebSocket-STOMP 테스트하기SpringBoot의 테스트도구인 JUnit에서 WebSocket - STOMP 프로토콜을 테스트해보자더불어서, Connect시의 accessToken 검증을 거치는 별도로 제작된 interceptor 통과를 위한 설정도 함께 한다. 1. SocketClient 생성socketJS가 활성화된 서버임을 가정하며, 다음과 같이 session 객체를 얻어온다this.SOCKET_URL = "http://localhost:" + port + "/ws";this.session = setSession();...private StompSession setUserSession() throws ExecutionException, InterruptedException { // ..