분류 전체보기
-
Querydsl 로 페이징 처리기능 타입 세이프하게 구현하기백엔드 : 서버공부/Spring 2024. 11. 23. 22:50
프로잭트를 진행하던중 깃허브 이슈리스트 조회 기능을 구현하게되었다. 그런데 이슈 리스트라는 기능 특성상 무한 스크롤로 구현해야하는 소요가 생겼고, 그에따라 서버사이드에서 페이징 처리를 해줘야했다. 일반적으로 페이징처리라 하면 `OffSet`방식을 많이 떠올릴 것이다. 하지만 이 방식은 처음부터 오프셋 값만큼 데이터를 건너뛴 후 필요한 데이터를 조회하는 방식이기때문에 오프셋 값이 커질수록 건너뛸 데이터를 스캔하는 과정에서 처리할 데이터 양이 많아지고, 때문에 성능 저하가 발생한다. 또한 오프셋 방식은 실시간 처리에서 데이터 누락 등의 문제를 발생시킨다. 때문에 나는 `Cursor` 방식의 페이징을 구현하기로 했다. `OffSet` 방식을 구현하는 것은 Page 인터페이스 등을 사용하면 ..
-
SELECT 절 최적화를 통한 API 성능개선 해보기백엔드 : 서버공부/Spring 2024. 8. 11. 13:07
JPA를 공부하던 중 전 우아한형제들의 이동욱님의 영상을 보게되었다. [수십억건에서 QUERYDSL 사용하기](https://m.youtube.com/watch?si=Jxf1-cfuPN_mFssc&v=zMAX7g6rO_Y&feature=youtu.be)라는 영상이었다. 해당영상은 QUERYDSL을 사용하시며 정말 많은 DB속에서 최적화를 하기위해 고민하신 이야기를 들을 수 있는 정말 유익한 영상이었다. 이런 좋은 영상을 보면 나의 프로젝트에 도입할 수 있는 부분은 무엇인가 찾아보게되는 습관이있다. 지금 진행중인 프로젝트에선 QUERYDSL을 사용하지않아 QUERYDSL과 직접적인 관련있는 부분은 도입하진 못했다. (추후에 꼭 도입할것이다!) 하지만 영상내용중 JPA를 사용할때 엔티티자체를 조회하는..
-
흔히 보이는 애노테이션 1탄백엔드 : 서버공부/Spring 2024. 8. 3. 16:24
프로젝트를 진행하면서 빈 등록에 흔히 쓰이는 애노테이션들로는 아래와 같이 크게 4가지가 있다.`@Service`, `@Controller`, `@Repository`, `@Component`가 있다.기본적으로 아래와 같이 클래스 최상단에 붙이며 `@ComponentScan`과 `ClassPathBeanDefinitionScanner`이 빈을 스캔하여 등록할 수 있게 해준다. 여기서 빈이란 스프링 컨테이너에서 관리하는 객체로, 이 객체들은 필요할 때 컨테이너로부터 주입받아 사용하게 된다. 기본적으로 `@Service`, `@Repository`, `@Component`는 기능이 비슷하다. 하지만 프로젝트를 진행할 때 각 클래스의 계층에 맞게 붙이는 것이 좋다. 특히 `@Repository`는 데이터 액세스..
-
디스패치아니고 디스패처: DispatcherServlet 이야기...백엔드 : 서버공부/Spring 2024. 8. 2. 02:13
스프링부트를 이용해서 여러 프로젝트를 진행하던 중 문득 스프링을 처음배울때 크게 중요하게 공부하지않아 잊고있던 DispatcherServlet의 작동 메커니즘이 궁금해졌다. 정확하게 말하자면 스프링부트가 어떻게 HTTP요청을 주고받는지 궁금해졌다. 스프링부트는 기본적으로 DispatcherServlet을 통해 HTTP 요청을 받아들이고 처리 과정을 조정한다. DispatcherServlet은 웹 애플리케이션의 중앙 진입점으로, 모든 요청을 받아 핸들러로 전달하고, 결과를 다시 클라이언트에게 응답한다.대략적인 흐름이 이러하다. HTTP 요청 수신: 클라이언트가 HTTP 요청을 보내면 이 요청은 서블릿 컨테이너(예: Tomcat)로 들어온다. 서블릿 컨테이너는 이 요청을 DispatcherServlet으로 ..
-
그 세션이 아니라니까 : 스프링으로 소켓구현 [세션 관리]백엔드 : 서버공부/Spring 2024. 7. 15. 15:48
현재 프로젝트에서 WebRTC를 통한 실시간 서비스를 개발중이다. 그에따라 나는 스프링 부트로 시그널링서버를 구축하는 역할을 맡게 되었다.생각보다 순탄했다. WebRTC에서 시그널링서버는 클라이언트가 P2P로 서로의 정보만 최초교환 할 수 있게 해주면 된다.잘 알려진 코드들과 스프링부트의 라이브러리들로 소켓핸들러를 구현하였다.소켓핸들러는 크게 3-4가지 정도의 함수들로 구성된다.afterConnectedEstablished(),handleTextMessage(),afterConnectionClosed(),broadcastMessage()먼저 afterConnectedEstablished()함수는 소켓 연결된 후 호출되는 함수이다.나는 이 함수에게 세션을 소켓 URI에서 추출한 유저의 아이디, 스터디룸의 ..
-
<스프링 기초 - 자바> 2차원 배열 정렬백엔드 : 서버공부/Spring 2024. 5. 23. 12:35
이차원 배열 메소드의 원리에 대해 기록하려고 작성하는 글 자바에서 1차원 배열의 정렬은 아주 간단하다. Arrays.sort메소드를 사용하면 된다. 2차원 배열이라는 문제상황에서도 Arrays.sort는 유효할까? 아마 날먹(?)의 마음으로 이차원 배열을 Arrays.sort 인자로 넣으면 아래같은 문제를 맞이했을것이다.Arrays.sort(나는 2차원 배열) ClassCastException 예외가 발생하는 이유는 Arrays.sort 메소드가 2차원 배열을 위한 Comparable 인터페이스를 구현하지 않은 배열을 정렬하려고 하기 때문이다. ComparableTimSort는 Comparable을 구현한 객체들을 정렬할 때 사용됩니다. 만약 객체들이 Comparable을 구현하지 않았다면, Compa..
-
레디스 도입하기 [기초]백엔드 : 서버공부/Spring 2024. 5. 5. 15:45
최근 개인 공부용으로 프로젝트를 진행 중인데요, https://github.com/Mouon/issuehub이번에는 캐싱을 도입해보았습니다.도입한 이유는 데이터베이스에 부하가 걸리는 것을 최소화해보기 위해서입니다.이를 위해 레디스를 도입해보기로 하였구요 이를 통해 데이터를 캐시로 저장하고 빠르게 접근할 수 있도록 해보겠습니다. 캐시 도입시 간단한 흐름을 보면 아래와 같습니다.클라이언트가 요청을 보내면, 서버에서 해당 요청에 대한 데이터를 레디스 캐시에서 검색합니다.캐시에 데이터가 존재하면, 캐시된 데이터를 클라이언트에 반환합니다.캐시에 데이터가 존재하지 않으면, 데이터베이스나 다른 소스에서 데이터를 가져와서 캐시에 저장한 후 클라이언트에 반환합니다.데이터베이스나 다른 소스에서 가져온 데이터는 캐시에 저..
-
스프링 : DTO를 사용하는 이유백엔드 : 서버공부/Spring 2024. 3. 7. 15:47
애플리케이션을 개발할 때, 데이터를 UI에서 서버로, 서버에서 DB로 전달해야 하는 경우가 자주 있습니다. 이러한 경우, 직접 엔티티를 사용하여 데이터를 전달하는 것이 아니라, DTO를 사용해야 하는 여러 가지 이유가 있습니다. 1. API 스펙의 안정성 그 중 가장 큰이유는 API 스펙의 안정성입니다. 엔티티를 그대로 api에서 사용할 경우 엔티티의 수정이 api의 스펙 변화로 이어지게 됩니다. 이렇게 되면 api를 사용해 개발하는 클라이언트측에서 개발중 api가 작동하지 않는 문제를 경험할 수 있습니다. 2. 유연한 API 개발 또 다른 이유 하나는 유연한 API의 개발이 있겠습니다. 클라이언트의 요구 사항은 시시각각 변할 수 있습니다. 클라이언트 측에서 필요로 하는 데이터 형태가 변하더라도, DTO..