데이터 캐싱해보기 - Spring Cache와 Caffeine
2023. 8. 14. 16:22
JAVA
개요 프로젝트에서 특정 기간 동안의 국가별 사용자 데이터에 대한 통계를 대시보드로 제공하려고 한다. 이 경우에 꽤 볼륨이 큰 쿼리를 사용하게 되는데, 일정 시간을 기준으로 하는 데이터이기 때문에 매번 사용자가 조회할 때마다 데이터를 전달하는 것보다 고정된 데이터를 주기적으로 업데이트만하고 이를 캐시로 제공하면 좋겠다고 생각했다. 이를 위해 Redis를 얹는 것보다, 로컬 캐싱만으로도 충분히 해결할 수 있는 볼륨이어서 Spring Cache, 그리고 로컬 캐싱에 특화된 캐싱 라이브러리인 Caffeine을 이용하고자 한다. Spring Cache? Spring에서 단순한 추상화(어노테이션)를 통해 캐시를 쉽게 사용할 수 있도록 지원하는 라이브러리다. 선언적인 방식(어노테이션, 무엇을 할지만 적어놓는다)을 통..
예제로 QueryDSL 사용해보기
2023. 7. 19. 22:07
JAVA
노션에서 보기 이전 글 ORM - Hibernate - JPA - QueryDSL을 알아보자 QueryDSL에 대해서 어떤 것인지, 어떠한 구조를 가지고 ORM이 진행되는지를 알아보았다. 작은 서비스를 가정하고, 구현한 상태에서 QueryDSL을 적용하여 간단히 사용해보자. 셋업 Gradle 의존성과 세팅 plugins { id 'com.ewerk.gradle.plugins.querydsl' version '1.0.10' // Q 클래스 생성 플러그인 // ... } def querydslDir = "$buildDir/generated/querydsl" // 생성된 Q 클래스가 저장될 위치를 정의한다. // queryDSL 자체에 대한 config querydsl { jpa = true // jpa = ..
ORM - Hibernate - JPA - QueryDSL을 알아보자
2023. 7. 19. 22:02
JAVA
노션으로 보기 개요 이전 느린 응답 26배 빠르게 개선해보기를 겪으면서, 복잡한 쿼리들을 메서드 체이닝을 이용해서 가져올 수 있었다면(QueryDSL을 썼다면) 이런 느린 쿼리 말고도 연관관계가 깊은 복잡한 쿼리들도 단번에 가져올 수 있지 않을까하는 생각이 들었다. 이번 글에서는 ORM과 JPA에 대해서 간단히 알아보고, QueryDSL의 간단한 적용과 예시를 구현해보고자 한다. 이를 통해서 추후에 직접 서비스에 적용해서 위에서 일어났던 휴먼 에러와 몰라서 생기는 불필요한 호출들을 줄일 수 있으면 좋겠다! ORM부터 Spring Data JPA까지 우선 QueryDSL로 넘어가기 전에, 간단하게 ORM과 Spring Data JPA에 대해서 짚고 가보자. ORM(Object-Relational-Mappi..
느린 응답 26배 빠르게 개선해보기
2023. 7. 16. 12:56
JAVA
노션으로 읽기 -> https://cabi.oopy.io/788c5b3f-32a2-4154-a1d4-d052408f245c 느린 응답 26배 빠르게 개선해보기 개요 cabi.oopy.io 개요 스프링으로 포팅하면서 이전보다 느리게 오는 응답에 대해서 문제점을 분석하고, 이를 해결하기 위해서 DB와 백엔드 코드에서 어떻게 해결할 수 있을지에 대해서 분석해보려고 한다. 겪고 있는 문제 서비스의 웹 뷰에서 사용자가 로그인 후 가장 먼저 하게 되는 행동은 특정 층의 사물함 전체 조회다. 기존 Nest.js 백엔드에서는 100회 평균 약 80ms로 응답속도가 빨랐는데, 스프링 포팅 이후에 해당 호출이 100회 평균 약 520ms로 급격히 상승했다😱 문제 진단 응답 속도 측정해보기 (Postman Runner) 쿼..
테스트를 알아보자 With 단위, 통합, E2E
2023. 7. 6. 16:24
JAVA
OOPY에서 보시면 더욱 편하게 보실 수 있습니다! 테스트에 대해 알아보자 With 단위, 통합, E2E 개요 cabi.oopy.io 개요 새롭게 Java Spring으로 프로젝트 코드를 작성하면서, 테스트가 왜 필요한지, 어떻게 작성해야 하는지 궁금해졌다. TDD(Test-Driven Development, 테스트 주도 개발)라는 말이 있을 정도로 프로그래밍에서 테스트는 중요한 것 같은데 왜인지, 어떤게 있는지 한번 알아보고자 한다. 이 글에서 다루는 테스트는 소프트웨어 애플리케이션의 테스트이다. 테스트란? 프로그래밍에서 테스트(Test)는 개발한 소프트웨어의 동작을 검증하는 과정을 말한다. 테스트는 프로그램의 요구사항(동작)을 명세하고, 품질을 확보하고, 버그를 찾아내고 수정함으로써 소프트웨어의 신뢰..
동시성 문제와 데드락, 테스트와 해결, 그리고 삽질
2023. 6. 6. 21:36
JAVA
이 글은 Notion에서 더 잘 보이게 작성되어 있습니다! 여기에서 공개된 글로 보시면 편하게 보실 수 있습니다..! 개요 한정된 자원인 사물함에 대해 대여 서비스인 Cabi를 진행하면서 동시성 문제를 겪었었다. 트랜잭션과 격리수준에 대해 간략히 설명하고, 이전의 Nest.js에서 해결했던 방법과, 지금 새로이 Spring으로 포팅하면서 해결하고자 한 방법들에 대해서 써보려고 한다. (장문 주의) 동시성 문제? 유명한 문제 중 하나인 **‘식사하는 철학자 문제’**와 같이, 정해진 자원에 대해, 스레드나 프로세스가 동시적인 점유와 조작을 시도했을 때, 의도하지 않은 결과가 발생하는 것을 의미한다. 자세한 내용은 이곳을 참조하면 좋을 것 같다. 문제 상황 까비에서 서비스로 제공하는 사물함의 종류는 1인 상..
스프링에서 HTTP 요청 보내기 - RestTemplate vs WebClient
2023. 6. 1. 11:40
JAVA
블로그에 올리려고 했는데, 너무 안 예쁘게 나와서 OOPY 링크 첨부합니다.. 스프링에서 HTTP 요청 보내기 - RestTemplate vs WebClient 개요 cabi.oopy.io
Spring Security 안쓰고 AOP로 OAuth 구현하기 - 2
2023. 5. 25. 15:35
JAVA
개요 이전 글(Spring Security 안쓰고 AOP로 OAuth 구현하기 - 1) Spring Security를 사용하지 않기에, 일일히 OAuth 2.0의 인증 방식에 맞추어서 구현해야 했다. 우리 서비스의 경우, Google, 42(교육기관 내부 API)를 이용해 OAuth2.0 인증을 구현했다. OAuth 1.0과 2.0의 차이가 궁금하다면 이곳을 참고하면 될 것 같다. OAuth(Open Authorization) 2.0 동작 방식 여러 가지 동작 방식이 있는데, 우리는 일반적으로 사용하는 Authorization Code Grant(코드 권한 부여 방식)을 사용하였다. 여기서 User는 서비스 사용자(브라우저, 클라이언트)이고, Client는 서비스 서버(백엔드)라고 생각하면 될 것 같다...
Spring Security 안쓰고 AOP로 OAuth 구현하기 - 1
2023. 5. 25. 15:34
JAVA
oopy로 보시면 더 깔끔합니다! 개요 기존의 Nest.js에서 JAVA Spring으로 포팅을 진행하게 되면서, 인증 부분을 맡게 되었다. Nest에서는 Passport라는 라이브러리를 통해서 OAuth를 간단하게 구현할 수 있었지만, Spring에서 인증-인가와 관련된 부분은 대부분 Spring Security를 통해서 관리되는 편이다. Spring Security를 적용하기 전에, 우선적으로 Spring Security를 사용하지 않는 방식으로 인증-인가를 구현하고자 하였다. 시큐리티를 쓰지 않은 이유 우선, Spring Security의 러닝 커브가 높았고, 낯설은 부분(필터 체인과 같은)들이 너무나 많았다. 빠르게 구현해야하는 상황에서, 기존의 Guard를 이용한 AOP, 인터셉터와 같은 부분은..
스프링의 싱글톤과 멀티 스레딩
2023. 4. 8. 10:48
JAVA
개요 스프링 시큐리티를 사용하지 않고 인증을 구현해보는 작업을 하던 도중, 비동기적인 유저의 요청에 따라, 싱글톤을 주도적으로 사용하는 스프링이, 어떻게 각각의 컨텍스트들에 대해서 처리(멀티 스레딩)할 수 있는지 궁금해졌다. 싱글톤 싱글톤은 일종의 소프트웨어 디자인 패턴으로서, 생성자가 여러번 호출되더라도 실제로 생성된 객체는 하나이고, 최초의 생성자가 생성한 객체를 리턴하는 방식을 얘기한다. 즉, 프로그램 런타임동안 하나의 인스턴스만 사용한다는 의미이다. 장점 단일성: 단일 인스턴스를 사용하기 때문에, 메모리를 효율적으로 사용할 수 있다. 접근성: 전역에서 접근할 수 있으므로, 애플리케이션의 모든 부분에서 사용할 수 있다. 단점 객체 생성 및 관리가 객체 자체와 긴밀하게 연결되어 의존성 주입이 어려울 ..