프로젝트 리펙토링 (3) - Github API 호출 성능 개선하기 (비동기 처리)
·
Backend/Spring Boot
비동기 처리(Asynchronous)비동기 처리 작업이란 멀티스레드를 사용하여 작업을 분리하고, 작업이 끝날 때까지 대기하지 않고 다른 작업을 처리하는 것을 말한다. Spring Boot에서 비동기 처리는 멀티스레딩 환경에서 비동기적으로 실행되는 작업을 처리하는 것으로, 동기적인 방식과 비교해 처리 속도와 성능을 개선할 수 있다.   사용하는 이유높은 응답성 : 동기적인 방식으로 작업을 처리할 때, 작업이 끝날 때까지 다른 요청을 처리할 수 없다. 예를 들어 외부 서비스와 통신할 때 I/O 작업이 많은 경우 작업이 끝날 때까지 기다리는 대신 다른 요청을 처리하며 시간을 절약할 수 있다.자원의 효율성 : 동기적인 방식으로 작업을 처리할 때는 스레드를 많이 생성하므로 시스템 자원을 많이 사용한다. 비동기처리..
Spring Boot 의 동작 방식
·
Backend/Spring Boot
이번 시간에는 스프링과 스프링 부트가 무엇이며, 스프링 부트는 어떻게 동작하는 지에 대한 공부를 해보겠습니다.스프링 부트의 기본 의존성 중 하나인 spring-boot-starter-web 모듈을 사용하면, 기본적으로 내장 톰캣을 사용하는 스프링 MVC 구조를 기반으로 동작합니다. 클라이언트의 요청이 들어오면 서블릿이 이를 처리해야 하는데, 서블릿은 서블릿 컨테이너에서 관리하고, 톰캣이 서블릿 컨테이너의 역할과 WAS 역할을 담당합니다. 서블릿(Servlet)클라이언트의 요청을 처리하고, 결과를 반환하는 자바의 웹 프로그래밍 기술입니다. 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리합니다. 서블릿 객체는 싱글톤 패턴으로 관리되며, 멀티 스레딩을 지원합니다.   DispatcherServl..
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Java 8 date/time type java.time.LocalDateTime not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310"
·
Backend/Redis
리펙토링 중인 프로젝트의 엔티티에는 챌린지 startedDate, completedDate 컬럼이 존재하는데, 해당 컬럼의 타입은 LocalDateTime이었다. 해당 데이터를 직렬화하고 Redis에 저장한 후, 캐시 데이터를 조회할 때 역직렬화 과정을 거쳐야하는데 Jackson 라이브러리에서 LocalDate, LocalTime, LocalDateTime을 지원하지 않았다. 이를 처리하도록 사용하려면 com.fastxml.jackson.datatype:jsr310 모듈을 추가해야한다는 경고가 나타났고, 아래와 같이 추가해주었다. 그러나, 문제는 해결되지 않았다. Jackson을 공부하면서 ObjectMapper에 대한 이해가 필요함을 느꼈다. implementation 'com.fasterxml.jac..
Could not read JSON:Cannot construct instance of org.springframework.data.domain.PageImpl (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
·
Backend/Redis
두둥.. 에러가 발생했습니다. 발생한 이유는 org.springframework.data.domain.PageImpl 객체를 JSON으로 직렬화하거나 역직렬화하는 과정에서 발생하는 문제였습니다. 특히, Spring에서 캐싱된 Page 객체를 다시 사용할 때 나타나는 문제로, PageImpl 클래스가 기본 생성자나 적절한 생성자를 제공하지 않아 Jackson이 객체를 역직렬화할 수 없기 때문이었습니다.  Page 인터페이스를 구현한 PageImpl 클래스는 기본 생성자가 없으며, Jackson이나 다른 JSON 라이브러리가 객체를 역직렬화할 때 기본 생성자가 필요했고, 이 경우 캐시에서 꺼낸 데이터가 역직렬화되지 않으면서 예외가 발생한 것이었습니다. PageImpl의 기본 생성자도 신경써줘야 하다니 !! ..
Docker Redis 컨테이너 실행 시 redis.conf 파일 생성 오류
·
Backend/Redis
docker 명령어로 redis.conf 파일을 설정하던 중 발생한 오류였다. 내가 작성한 명령어는 아래와 같았다.docker run --name redis-serer -p 6379:6379 -d -v redis-volume:/data -v ~/redis.conf:/etc/redis/redis.conf redis redis-server /etc/redis/redis.confdocker run : 도커 컨테이너 실행  --name redis-serer : 컨테이너 이름을 redis-server로 지정 -p 6379:6379 : 호스트 포트 6379, 컨테이너 포트 6379 (이 설정을 통해 호스트 머신에서 localhost:6379로 접근하면 컨테이너 내부의 redis 서버에 연결할 수 있다.) -d : ..
프로젝트 리펙토링 (2) - 인덱스(index) 사용으로 조회 API 성능 개선
·
Backend/Spring Boot
JMeter 사용 방법Apache JMeter 5.6.3 : Source - zip 파일 다운로드테스트 전 유의사항테스트하는 웹 어플리케이션 서버와 테스트를 진행하는 서버는 서로 달라야 한다.같은 서버를 사용하면 같은 메모리를 점유하기 때문에 정확한 값을 측정할 수 없다.JMeter 실행util\\apache-jmeter-5.6.3\\apache-jmeter-5.6.3\\bin> ./jmeter JMeter 구성요소Thread Group : 테스트에 사용될 스레드 개수, 스레드 1개당 사용자 1명Sampler : 사용자의 액션 (예: 사용자 로그인, 게시물 작성, 게시글 조회 등)Listener : 응답을 받아 리포팅, 검증, 그래프 등 다양한 처리Configuration Elements: Sampler..
CSRF 공격 시나리오 및 방어 방법
·
Backend/Spring Security
CSRF공격 시나리오  1. 사용자가 google.com에 로그인사용자는 google.com에 로그인하여 세션 쿠키를 받습니다. 이 쿠키는 사용자가 google.com에 다시 요청을 보낼 때마다 자동으로 포함됩니다.2. 악의적인 사이트 방문사용자는 이메일 링크, 소셜 미디어 링크 또는 광고 등을 통해 attack.com이라는 악의적인 사이트를 방문합니다.attack.com에는 CSRF 공격을 수행하기 위한 악의적인 스크립트가 포함되어 있습니다.3. 악의적인 요청 생성attack.com의 페이지에 다음과 같은 HTML 코드가 포함되어 있다고 가정합니다." style="display:none">이 코드는 이미지 태그를 사용하여 google.com으로 GET 요청을 보냅니다. style="display:non..
AWS EC2 docker로 Redis 설치하기 (+ Docker 볼륨을 생성, 이를 컨테이너에 마운트하여 데이터가 유지되도록 설정)
·
Backend/Redis
AWS EC2가 설치되었다고 가정하고 진행.Docker 서비스 시작 및 부팅 시 자동으로 시작되도록 설정sudo service docker startsudo systemctl enable docker현재 사용자에 Docker 권한 추가sudo usermod -a -G docker ec2-user   1. 도커에 Redis 설치Docker Redis Image 다운로드$ docker pull redis다운로드 된 Docker Image 확인$ docker imagesRedis 도커 컨테이너 실행docker run -d --name redis-server -p 6379:6379 redisRedis 컨테이너 실행 여부 확인docker psRedis CLI를 사용하여 Redis 서버에 접속docker exec ..
프로젝트 리펙토링 (1) - Facade Pattern 도입
·
Backend/Spring Boot
퍼사드 패턴을 도입하게 된 배경디자이너, 프론트엔드, 백엔드 총 5명으로 구성된 우리 팀은 올해 초부터 쉴 틈 없이 달려왔다. 매주 팀 회의, 파트별 회의, 프론트/백엔드 회의를 각각 1회씩 진행하며, 기획부터 설계, 개발까지 모두 경험했다. 배포 전에는 통합 테스트를 거쳐 최종적으로 이슈를 해결하고 도메인 등록과 배포를 통해 프로젝트를 성공적으로 마무리하였다. 프로젝트가 종료된 후 일부 팀원은 각자의 삶으로 돌아갔다. 어쩌면 당연한 일이지만, 시작이 있으면 끝이 있다는 게 시원섭섭하다. 알면서도 어쩔 수 없는 감정인 듯하다.배포된 서비스를 사용해보고 프로젝트 코드를 살펴보니 일정에 맞추느라 신경 쓰지 못했던 부분, 아쉬웠던 부분, 개선해 보면 좋을 것 같은 부분들이 보였다. 그중에서도 눈에 띈 부분은 ..
Effective Java - 객체 생성과 파괴 item02
·
Backend/Java
생성자에 매개변수가 많다면 빌더를 고려하라.정적 팩터리와 생성자에게 똑같은 제약이 하나 존재하는데, 선택적 매개변수가 많을 때 적절히 대응하기 어렵다는 점이다. 과거 프래그래머들은 점층적 생성자 패턴(telescoping constructor pattern)을 즐겨 사용했다고 한다. 이 클래스의 인스턴스를 만들려면 원하는 매개변수를 모두 포함한 생성자 중 가장 짧은 것을 골라 호출하면 된다. 점층적 생성자 패턴도 쓸 수는 있지만, 매개변수 개수가 많아지면 클라이언트 코드를 작성하거나 읽기 어렵다.  점층적 생성자 패턴public class Person { private final String name; private final int age; private final String addr..
Ngrinder를 활용한 성능 테스트 (localCache)
·
Backend/Spring Boot
캐시(Cache)캐싱은 어디에 적용할 수 있을까?변화가 많지 않은 데이터를 매번 DB에서 데이터를 조회해서 보여주는 것이 비효율적인 경우자주 조회되는 데이터캐시를 사용하면 얻는 점은?읽기(조회) 성능을 향상할 수 있다.RDB의 경우, Disk에 접근해야 하기 때문에 상대적으로 연산 수행이 오래 걸린다. 반면 Redis와 같은 캐시는 메모리에서 동작하기 때문에 상대적으로 빠르게 연산을 수행할 수 있다.무작정 캐시를 적용하면 좋을까?아무데서나 다 사용한다고 좋은 것은 아니다. 데이터가 업데이트될 때 마다 캐시도 함께 업데이트 해주어야 하기 때문이다. 캐시에 데이터가 과하게 쌓일 경우, side effect가 발생할 수 있다.  Ngrinder 설치 및 환경 설정설치 : https://github.com/na..
[Spring Security] PasswordEncoder
·
Backend/Spring Security
일반적인 Spring Security 내부 흐름입니다. 우리는 InMemoryUserDetailsManager를 사용하는 대신에 직접 loadByUsername()을 오버라이딩하여 사용해보도록 하겠습니다.   실습 - User 정보를 SQL 스크립트를 활용하여 수동 입력Config - SecurityConfig@Configurationpublic class ProjectSecurityConfig { @Bean SecurityFilterChain defaultSecurityFilterChain(HttpSecurity http) throws Exception { http.authorizeHttpRequests((requests) -> requests.requ..