Spring 20

Spring에서 @Async를 통한 비동기 처리하기

비동기(Asynchronous)란?작업이 시작된 후 그 결과를 기다리지 않고 다른 작업을 계속 진행할 수 있는 처리 방식을 의미한다.즉, 작업이 실행되는 동안 해당 작업이 완료될 때 까지 기다리지 않고, 다른 작업을 수행한다.예를 들어 이메일 보내기 서비스를 개발한다고 하면,사용자가 서버에 요청했을 때 이메일 보내는 기능은 비동기로 처리하고 이메일 보내는 것과 무관하게 200을 응답한다. 따라서 사용자는 이메일이 보내지는 것을 기다릴 필요 없어진다.작업: 이메일 보내기, 200 응답 보내기시간이 오래 걸리는 작업, 비동기 시킬 직업: 이메일 보내기비동기와 별개로 바로 수행할 작업: 200 응답 보내기왜 사용할까?응답성 향상: 비동기를 사용하면 사용자가 상호작용 하는 동안에도 백그라운드에서 작업을 계속 진..

Spring 2024.09.26

Spring에서의 동기, 비동기

동기 vs 비동기동기 = 요청이 순차적으로 실행되며, cpu가 주어진 요청을 완료하기 전까지는 다음 요청을 처리하지 않는 방식비동기 = 작업이 시작된 후 그 결과를 기다리지 않고 다른 작업을 계속 진행할 수 있는 처리 방식Tomcat 서버에서는 동기, 비동기적 방식 모두 스레드 풀에 여러 스레드가 대기하고 있고, 여러 요청이 한 번에 오면 각 요청에 대해 스레드가 할당되어 처리된다.  동기에서의 작업 처리동기에서 작업 요청이 오면, 각 스레드는 주어진 작업을 모두 스스로 처리한다.위 그림에서 작업2가 외부 API를 호출하고 응답받을 때까지의 지연시간이라고 한다면,작업 2만큼 스레드는 놀게 된다.  비동기에서의 작업 처리작업 2를 비동기 처리해 두었다면, 스레드1, 2는 각각 작업1, 작업3을 마치고 다른..

Spring 2024.09.26

OSIV란? (feat.OSIV를 통한 성능 최적화)

OSIV(Open Session In View)란?OSIV란 Lazy Loading에 관련된 설정으로세션(세션이란 영속성 컨텍스트와 DB 커넥션을 관리하는 주체이다.)을 유저에게 응답할 때(View단, Controller단)까지 열어두거나, 닫아 두는 기능이다.OSIV를 켜면 트랜잭션(@Transactional)이 종료된 이후에도 데이터베이스 세션이 열려있기 때문에, 뷰에서 지연 로딩이 발생할 수 있다.디폴트로 열어져(On) 있다. 개발자는 임의로 키거나 끌 수 있다.Jpa에서는 OEIV(Open Entity In View)라고 부른다.Hibernate에서는 그대로 OSIV(Open Session In View)라고 부른다. OSIV를 설정해야 하는 이유OSIV on 해두는 경우,요청에서 응답까지의 시간..

Spring/Spring Jpa 2024.09.25

Eager Loading(즉시 로딩) vs Lazy Loading(지연 로딩) 중 어느 전략을 사용해야 할까?

스프링 Jpa에서는 연관관계를 언제 DB에서 가져올 지 로딩 전략을 통해 결정할 수 있다.이에 대해서는 즉시 로딩(Eager) or 지연 로딩(Lazy)가 존재한다. 지연 로딩(Lazy Loading)지연 로딩 = 어떤 엔티티를 조회하였을 때 연관된 엔티티는 Proxy 객체( like 빈 객체)로 넣고, 실제로 사용될 때 DB 조회를 통해 가져온다.지연 로딩은 N + 1 문제가 발생할 수 있다,  N + 1 문제란? 더보기이는 1개의 쿼리로 N개의 데이터를 조회할 때, N개의 추가 쿼리가 발생하는 상황을 의미한다.예를 들어 jpa를 통해 리스트(예를 들어 게시글)를 조회한다고 했을 때,한 번의 쿼리(게시글 목록 조회)가 필요하다.이 조회를 통해 N개의 리스트 원소를 가져왔다고 하자. 가져온 각 게시글 안..

Spring/Spring Jpa 2024.09.24

Spring MVC와 Security에서의 CORS 설정

이 포스트를 통해Spring MVC에서의 CORS 설정Spring Security를 사용했을 때의 CORS 설정을 적어보려 한다. 만약 cors 자체에 대해 이해가 부족한 상황이라면 아래 포스트 글을 참조하면 좋을 거 같다.정리가 매우 잘 되어 있어 첨부했다.https://inpa.tistory.com/entry/WEB-%F0%9F%93%9A-CORS-%F0%9F%92%AF-%EC%A0%95%EB%A6%AC-%ED%95%B4%EA%B2%B0-%EB%B0%A9%EB%B2%95-%F0%9F%91%8FSpring MVC와 Spring Security를 구분한 이유Spring에서 CORS 이슈가 발생할 수 있는 곳은 MVC단과 Security단이 있다. 이렇게 구분하는 이유는 각 요청이 처리하는 곳이 다르기 때..

java PageImpl에서 totalElements가 바뀌는 오류 해결

나는 PageImpl을 활용하여 List를 Page로 바꾸어 응답했다.api테스트를 하는 도중 마지막 페이지에 접근하면 totalPage 와 totalElements 가 늘어나는 오류가 발생했다. 문제 상황똑같은 요청에 대해 page정보만 바꿔서 요청을 날려봤다.마지막 페이지인 9페이지 이전인 8페이지를 요청했을 때마지막 페이지인 9페이지를 요청했을 때보이는 거와 같이 totalElements 와 totalPages 가 변경된 것을 볼 수 있다.원인PageImpl이 매개변수로 받는 Pageable 객체는 기본적으로 0번 인덱스부터 시작한다.하지만 모든 ui에서 페이지는 1번 페이지부터 시작하므로 나는 임의로 Pageable의 시작 인덱스를 1번부터 시작하도록 변경하였다.(악몽의 시작이었다.)원인 분석Pa..

Spring 2024.08.13

[개발 일상] Spring 공통 응답 만들기

백엔드 서버에서 클라이언트에게 응답을 보낼 때 응답의 형식을 통일시키는 것은 중요하다.프론트는 백엔드의 응답을 받아, 이를 처리하여 화면에 보여주게 되는데 응답의 형식이 불분명하면 프론트에서 불편함을 겪을 수 밖에 없다.그래서 나는 프로젝트를 시작하기 전에 프론트분들과 소통하여 요구사항을 파악하고 공통 응답을 만들었다.백엔드 요구사항우선 백엔드 입장에서 생각했던 요구사항은 다음과 같았다.상태코드(403등)은 header에서 설정한다.body에는 상태메세지(Not Found등), 본문 data, 시간등을 포함시킨다.프론트엔드 요구사항반면 프론트엔드 입장은 다음과 같았다.상태코드를 헤더로 주면 try catch로 처리해야해서 불편하다.응답에 상태코드와 상태가 둘 다 있으면 좋겠다.결론적으로 시간,성공여부, ..

Spring 2024.08.13

Spring Security(스프링 시큐리티)의 동작 원리(Filter, FilterChain, Filter의 구조등)

Spring Security이번 프로젝트에 스프링 시큐리티를 맡게 되었고분명 작년에 해봤으니까 잘 할 수 있겠지 생각했다.하지만 이번에는 userName(아이디)과 creatential(비밀번호)외에도 추가로 roomId를 user를 식별하기 위해 사용하면서 난항을 겪게 되었다..내가 생각보다 시큐리티 원리에 대해 이해를 못하고 있어, 전체적인 커스텀을 못 했기 때문이다.그래서 이번 기회를 통해 시큐리티 원리에 대해 더욱 정확히 알아보고자 한다.스프링 시큐리티란?스프링 시큐리티란 인증, 인가와 공격자에 대한 보호를 제공해주는 프레임워크이다. 보안과 관련된 많은 옵션을 제공해주기에, 개발자가 일일히 보안 로직을 작성하지 않고 가져다 사용하면 된다.인증(Authentication) : 사용자가 본인인지 확인..

Spring 자바, 스프링에서 객체 응답시 is로 시작하는 변수가 변경되는 문제

개발을 하다가 다음과 같은응답 객체로 응답을 받았는데내 예상과 달리 응답에 온 변수명이isSuccess → success로 변경되어 온 것을 발견할 수 있었다. 위는 내가 만든 응답 객체이다. 위는 BaseResponse를 상속해서 만든 ErrorResponse이다. 이러한 문제가 발생한 이유는자바빈 규약 때문이다. 자바빈 규약에 따르면boolean의 getter는 is변수명() 과 같이 is로 시작하고Boolean의 경우 getter는 get변수명() 과 같이 get으로 시작한다. 즉 @Getter 를 사용하여 getter를 생성한다면 자바빈 규칙에 따라boolean형 변수는 is변수명() 으로 getter를 생성한다. 여기서 변수명이 is로 시작하는 경우 중복이 되므로 자동으로 변수명을is를 제외한 ..

Spring 2024.05.25

spring jpa를 활용한 데이터 저장 성능 향상(saveAll(), bulk insert)

Spring boot를 이용하여 프로젝트 과제를 하다가,20만 건 이상의 데이터를 저장시키는 작업이 필요했다. “그냥 저장시키면 되겠지”라는 안일한 생각으로 저장로직을 작성해 저장을 시켜보니무려 40분 이라는 시간이 걸리는 게 아닌가.. 내 기준 40분이면 밥🍚 먹고 설거지까지 마칠 시간이라 도저히 용납할 수 없었다.그래서 어떻게 성능을 올릴 수 있을까 고민하는 시간을 가져봤다. 1. @Transactional 쓰기 지연을 활용할 수 없을까?어디서 가장 크게 성능 저하가 일어날까 고민해봤을 때db에 저장될 때 성능저하가 크게 일어나지 않을까 추측하였다. 왜냐하면 db에 작업을 할 때에는 매 번 db에 연결하기 위해 작업이 필요하기 때문이다.그래서 db에 연결하는 횟수를 줄이기 위한 방법을 고민하게 되었..

Spring/Spring Jpa 2024.05.16