썸네일 프로젝트 성능 개선기(nGrinder을 활용한 부하 테스트) 팀 프로젝트 종료 후, 개인적으로 Fork하여 학습을 시작한 이유지난 1월 말, 팀 프로젝트가 종료되면서 개인적으로 새로운 기능을 추가하거나 기존 코드를 변경하는 것이 쉽지 않다고 판단했다. 협업 프로젝트에서는 함부로 commit하거나 push하는 것이 위험할 수 있기 때문이다. 그동안 백엔드 관련 지식을 꾸준히 쌓아왔지만, 실제 성능 테스트를 진행할 기회는 적었다. 로컬 환경에서 Docker를 활용해 모니터링 시스템을 구축하고, 쿼리 최적화 등을 진행하긴 했지만, 결국 Docker는 호스트의 자원을 사용하기 때문에 실제 트래픽 환경을 완벽하게 재현하기 어렵다는 한계를 느꼈다. 또한, Grafana + Prometheus를 활용한 기본적인 모니터링은 학습했지만, • 어떤 메트릭을 중점적으로 봐야 하는지 ..
썸네일 Mysql 비효율적인 쿼리 개선기(+ 무한스크롤, 페이징 성능 비교) 현재 진행중인 프로젝트에서 공동구매 기능이 있어 상품을 보여주는 페이지가 존재한다.  공동구매라는 특성 상, 사용자에게 빠르게 상품 데이터를 보여주고 추후 검색 기능까지 확장하기 위해서 페이징 방식보다는 커서 기반의 무한스크롤 방식을 채택하게 되었다. 그 후, 무한스크롤에 대한 정보를 찾아보던 중 기존 offset 기반 페이징 방식에 비해 커서방식의 무한 스크롤이 데이터가 많아질 수록 성능적으로 이점을 가져간다는 것을 알게 되었다. 이유는 간단하다, offset 방식의 경우 원하는 데이터가 나올 때까지 모두 탐색을 한 후에 원하는 데이터를 가져오게 된다. 예를 들어, offset이 100만이라면 100만 개의 데이터를 탐색한 후에 원하는 데이터를 가져오게 되는 셈이다. 하지만 커서 기반 무한스크롤의 경우..
썸네일 스프링 프레임워크 따라해보기 - 멀티 모듈과 빈 생성 및 등록 멀티 모듈로 변경한 이유먼저 다른 기능들을 구현해보기에 앞서 멀티모듈로 변경한 이유부터 말해보려 한다.기존 프로젝트의 경우에는 한 개의 src 파일 아래로src| - framework| - project이런식으로 2개의 패키지를 구성해서 framework 패키지 아래로는 스프링을 따라해본 구현체를 사용하고, project 패키지에는 우리가 흔히 웹 서비스를 만드는 것처럼 controller, service, repository를 사용하려고 했다. 그런데, 곰곰히 생각을 해보니 결국 framework 패키지는 외부에서 주입받아 사용되어야 하기 때문에 이를 1모듈 2패키지가 아니라, 2모듈 2패키지로 진행하는 것이 좋을 것 같다는 생각을 해서 분리를 하게 되었다. 또한, 앞선 글에서는 basepackage를..
썸네일 스프링 프레임워크 따라해보기 - 컨트롤러 매핑과 응답 전송 앞에서는 웹 서버를 구축하여 Http 요청을 받고 기본적인 응답을 전송하는 기능을 구현했다.스프링 프로젝트를 해 본 사람이라면 모두 알겠지만, @ReuqestMapping, @Controller 등의 어노테이션을 통해서 url을 분석하고 이에 맞는 컨트롤러로 요청을 전달 하는 모습을 확인할 수 있었다. 그렇다면, 이러한 과정이 어떻게 이루어지는지 간단하게 작성을 해보자. DispatcherServlet스프링 프레임워크에는 DispatcherServlet이라는 클래스가 있는데 이 클래스의 역할은 애플리케이션으로 들어오는 모든 요청을 핸들링하고 공통작업을 처리해준다고 한다. DispatcherServlet은 프론트 컨트롤러라고도 부르며, 서블릿 컨테이너의 맨 앞에서 모든 요청을 받아 처리해주는 컨트롤러를 의..
썸네일 오류가 발생했을 때 Jwt 검증 필터로 계속해서 들어오는 건에 대하여.. 새로운 팀 프로젝트에 합류해서 코드를 작성하며 진행을 하고 있었다. 그런데, swagger로 엔드포인트를 테스트 하던 도중, 오류가 발생했는데 내가 원하는 response가 아니라 CORS 에러 같은 알 수 없는 오류가 발생하는 것을 확인하였다. 해당 코드는 단순히 유저의 내용을 변경하는 코드인데, 예외 테스트를 할 때 일부러 Json이 파싱되지 않게 넣었다. 당연히 예상 결과는 400 Bad Request가 발생해야 한다고 생각했는데 위처럼 아예 실패라는 결과를 얻게 되었다.. 이유가 뭔지 궁금해서 스프링의 로그를 확인해보니위 사진과 같은 형태로 에러 발생 후에도 계속해서 JWT 검증 필터에 접근하는 현상을 확인할 수 있었다. ExceptionHandler을 사용해서 처리하면 되는 부분 아닌가?사실 이..
썸네일 [Project] 나만의 블로그 만들기 (7) - 게시글 작성과 게시글 태그 등록 로직 변경 + UUID 사용 제일 처음으로 작성한 게시글을 등록하는 방식은 다음 로직과 같이 되어있다.글쓰기 버튼 클릭 [POST] -> 백엔드에서 pk값과 createdAt 만 가지는 빈 내용의 entity 생성 후 클라이언트측에 pk값 전달클라이언트측에서는 제목, 내용, 태그 등을 작성제목, 내용 전달 [PATCH : /contents] -> update 로직을 통해 내용 수정태그 전달 [POST : /contentTags] -> 새로운 contentTag 엔티티 생성 후 DB에 저장하지만 이 방법은, 글쓰기 버튼을 누르는 순간 DB에 새로운 데이터가 생성되기 때문에 필요하지 않아진 데이터도 만들어질 것으로 생각되었고 이는 불필요한 pk값 증가 등으로 관리하는 데 있어서 불필요할 것 같다는 생각을 하였다.따라서, 다음에 시도한 ..
썸네일 [Project] 나만의 블로그 만들기 (6) - QueryDsl 을 이용해 페이징 + fetch join 한번에 수행하기 먼저 글을 작성하기 전에 fetch join이 무엇이고 왜 사용되는지부터 알아보자Fetch Join이란?우리는 SQL문을 사용하면서 테이블끼리 연관관계가 존재하고 이를 이용하기 위해 INNER JOIN, OUTER JOIN 등을 사용하게 된다. 그럼 스프링을 통해 개발할 때 사용되는 Fetch Join은 무엇일까?Fetch Join은 JPA나 JPQL에서 성능 최적화를 위해 제공하는 기능으로, 연관된 엔티티나 컬렉션들을 한 번의 SQL쿼리로 조회할 수 있도록 하는 기능이다. 즉 여러 데이터를 한번에 조회를 할 수 있기 때문에 성능적인 이점을 가져올 수 있으며, 주로 N+1 문제를 해결하는 데 있어 도움이 된다.다음 예시를 한 번 보자 현재, Cotnent 엔티티는 태그를 달아주기 위해 Tag 와 N:M ..
썸네일 [Project] 나만의 블로그 만들기 (5) - RefreshToken + Redis 통한 자동 로그인 기능 구현 사실 이번 프로젝트를 진행하면서, 프론트엔드도 같이 작성을 해야 하기 때문에 많은 시간이 백엔드 api 개발보다는 프론트엔드 코드 작성하는데에 더 많은 시간을 쏟게 되어 아쉬움이 많았다.하지만, 이번에 구현해볼 기능은 jwt 토큰을 이용해서 자동 로그인 기능을 해보려 했고, 프론트엔드 측면보다는 백엔드적인 측면에서 많은 고민을 할 수 있어서 아주 반갑고 재밌었다. 먼저, 이전에 도입했던 accessToken만 사용했을 때의 단점을 몇 가지 이야기해볼 수 있다.일단 기본 로직부터 다시 생각해본다면Oauth 로그인 -> 인증/인가를 위한 jwt 토큰 (accessToken) 발급 -> 백엔드에서 response 헤더로 AccessToken을 발급하여 전달 -> 전달받은 AccessToken을 프론트에서 관리..
썸네일 [Spring] 스프링 DB 접근 기술 Intro Spring을 이용하여 개발을 진행하면 백엔드에 관련된 코드를 작성하는 이상 필연적으로 DB와의 연동을 신경쓰게 된다. 많은 기술들이 존재하지만 전부 알지는 못하고 Spring JDBC, Spring Data JDBC, JPA, Spring Data JPA정도만 알아보려고 한다. 또한 기존 JAVA의 DB연동 방식인 JDBC에 대해 조사하고, Mybatis 또한 많이 사용된다고 하는데 이에 대한 내용도 공부해보겠다. 이 내용들은 설정 및 사용 방법에 대한 자세한 조사보다는 개념적으로 어떠한 차이들이 있고 어떠한 특징을 가지고 있는지에 중점을 두려고 한다. 제목을 스프링 DB 접근 기술이라고 적었지만, 정확히는 JAVA에서 DB에 접근하는 기술이 더 옳은 것 같다. 🔑 요약 : JDBC, Spr..
썸네일 [Spring] Spring의 기본적인 구조는 어떻게 생겼을까? Intro Spring boot를 통해서 프로젝트를 진행하고 공부하는 사람들 중에는 나처럼 일단 해보고 생각하자! 하면서 @Controller... @Entity.. 이렇게 코드부터 작성을 하는 사람들이 많을 것이다. 강의를 통하든, 인터넷 게시글 등을 통하든 대략적인 정보를 파악하고 코드를 쓰다 보면 에러가 발생하는 경우가 많은데, 이 에러들이 내가 평소에 알던 에러의 이름들이 아니다. Servlet이 어쩌고 저쩌고... Bean이 어쩌고 저쩌고.. 하면서 알지 못하던 부분들이 많게 되서 그때마다 구글링을 통해서 누락된 부분을 추가하거나 수정하는 식으로 공부를 하였다. 그러던 와중 대체 이 Spring Boot가 어떻게 동작하길래 저런 에러들이 존재하는걸까? 하는 의문을 가지게 되었고 한 번 알아보기로..
썸네일 [Spring] Spring? Spring Boot? Intro 백엔드 개발에 대해 공부를 하다 보면, 백엔드 개발을 하기 위한 언어에도 여러 가지가 존재하는 것을 알 수 있다. Java, JavaScript(node.js), Ruby, Python 등... 또한, 이러한 언어들에서 웹 개발을 조금 더 수월하게 진행하게 해주기 위한 프레임워크들(Spring, Django ..)등 많은 언어들이 있을 것이다. 나는 Java Spring을 이용한 백엔드 개발자가 되는 것을 희망하고 있었는데, 그 이유는 단순히 "현재 기업에서 많이 선택하는 언어인 것으로 알고 있고, 입문하기에 자료들이 가장 많지 않을까?" 하는 이유였다. 그런데 조금 자세히 보면 Java? Java Spring? Spring Boot? 등 처음 입문하는 사람들은 찾아보지 않으면 그 의미를 정확..