Skip to content

Commit

Permalink
Update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
BlueBerrySoda authored May 22, 2024
1 parent f8d3faa commit 077ed13
Showing 1 changed file with 22 additions and 2 deletions.
24 changes: 22 additions & 2 deletions back/README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
![image](https://github.com/kookmin-sw/capstone-2024-30/assets/55117706/be6e2f51-ade6-4453-9ba1-07ae10ec4bfa)### 기능적 고려 사항
### 기능적 고려 사항

### 성능적 고려 사항

Expand Down Expand Up @@ -39,9 +39,13 @@ Write 전략은 Write Around 전략을 활용했다. 데이터를 쓸 때, Redis

#### Race Condition 해결

프로젝트에서 답변의 추천기능을 구현하면서 추천 / 추천 해제 기능을 만들었다. 문제가 있다면 추천수, 조회수와 같은 기능은 하나의 필드에 대해 수많은 트랜젝션 요청이 오가는 기능이기 때문에 이경우 자원에 접근하는 것에 대한 Race Condition, 동시성 문제가 발생하게 된다. 이러한 경우를 해결하기 위해서 Redis를 사용하였다. Redis는 싱글 스레드로 자원에 대한 Race Condition 문제를 해결할 수 있기 때문이다. Redis에 요청을 보낼 countTemplate를 선언하고 이를 통해서 Redis에 객체와 답변의 추천수를 저장하고 일정시간마다 이렇게 Cache에 저장된 내용을 DB에 반영시키도록 하였다. 이렇게 Redis에 저장된 변경 사항은 30초 간격으로 DB에 반영되는 방식으로 구현하였다.

현재 방법도 동시성 문제를 해결하는 방법이지만 내가 추천한 답변의 추천수가 즉시 반영되어 보여지지는 않는다. 이는 데이터를 읽어올때는 캐시에서 찾는 방식이 아니기 때문이다. 추후에는 캐시에서 값을 찾도록 구현하고 Redis Lock과 Redis Trasaction을 사용한 관리나 RDS의 트랜잭션 단위를 조절하는 방법도 고려해봐야 한다.

#### N+1 문제

<br>
여러 참조관계를 가진 테이블이 존재하고 비즈니스 로직에서 이들을 Join하여 호출하는 상황이 많이 있었으며 이때 N+1문제가 발생하였다. 이를 해결하기 위해 Fetch Join을 사용하거나 Projection 주입을 사용하는 경우의 Inner Join과 같이 여러 경우의 N+1의 해결 방법을 모색하여 적용하였다. 이로 인해 서버 비즈니스 로직의 성능향상이 이루어질 수 있었다. 이 과정에서 여러 시행 착오가 있었다. 기존의 방식은 Projection을 사용하여 DTO를 바탕으로 JPA 검색을 사용하는 방식이었는데 이 경우 Fetch Join이나 EntityGraph로는 해결이 불가능하다. @Projection을 사용한 해결 방안도 있으나 좀 더 고민해본 결과 Join의 목적에서 N+1문제를 야기할 필드값이 큰 문제가 없어 InnerJoin으로도 충분히 해결되는 범주였다는 것을 깨달았다.

### 안정성 고려 사항

Expand Down Expand Up @@ -82,10 +86,26 @@ Write 전략은 Write Around 전략을 활용했다. 데이터를 쓸 때, Redis

#### Test Container

Test Containers는 통합 테스트에서 사용되는 자바 라이브러리로, Docker 컨테이너를 통해 데이터베이스, 메시징 큐, 웹 서버 등의 외부 리소스를 손쉽게 설정하고 관리할 수 있다. 이를 통해 개발자는 테스트 환경을 실제 운영 환경과 유사하게 구성할 수 있으며, 테스트의 신뢰성과 재현성을 높일 수 있다. 주요 특징으로는 코드 내에서 직접 Docker 컨테이너를 제어할 수 있는 API 제공, 다양한 프리셋과 유연한 구성 옵션, 테스트 실행 시 필요한 컨테이너를 자동으로 시작하고 종료하는 기능, 각종 데이터베이스(MySQL, PostgreSQL 등)와의 통합 지원, 그리고 쿠버네티스 환경에서도 사용 가능한 확장성 등이 있다. Test Containers는 JUnit과 같은 테스트 프레임워크와도 통합되어, 단위 테스트와 통합 테스트를 쉽고 일관성 있게 작성할 수 있다는 장점도 있다.

우리가 실제 서비스하는 RDS를 가지고 테스트를 진행한다면, 매우 위험할 것이다. 따라서, Test Container를 이용하여 독립된 환경에서 안전하게 테스트를 진행하도록 하였다.

#### Jacoco

JaCoCo는 자바 애플리케이션의 코드 커버리지를 측정하는 데 사용되는 오픈 소스 라이브러리이다. 코드 커버리지는 테스트가 애플리케이션의 소스 코드에서 얼마나 많은 부분을 실행하는지를 나타내는 지표로, 소프트웨어 테스트의 품질을 평가하는 중요한 요소이다. JaCoCo는 개발자들이 테스트의 효과를 분석하고, 테스트 범위를 확장하여 보다 신뢰성 있는 소프트웨어를 개발할 수 있도록 돕는다.

Jacoco를 이용하여 쉽게 테스트 코드 커버리지를 측정하고, 이를 html로 추출해서 팀원들이 쉽게 볼 수 있도록 구성하기 위해 택하였다.

#### Apache Jmeter

Apache JMeter는 자바 기반의 오픈 소스 소프트웨어로, 웹 애플리케이션 및 다양한 서비스의 성능 테스트와 부하 테스트를 수행하기 위해 사용된다. JMeter는 초기에는 웹 애플리케이션을 테스트하기 위해 개발되었으나, 현재는 데이터베이스, FTP 서버, 웹 서비스, JMS, LDAP, SMTP, POP3, IMAP 서버 등 다양한 프로토콜 또한 지원한다.

프로젝트에서 동시성 문제 테스트와 같이 대규모 부하 테스트를 위해서 사용하게 되었다.

#### JUnits

JUnit은 자바 프로그래밍 언어를 위한 오픈 소스 단위 테스트 프레임워크로, 개발자가 자바 애플리케이션의 소프트웨어 테스트를 자동화하고 효율적으로 수행할 수 있게 합니다. JUnit은 테스트 주도 개발(TDD)을 촉진하며, 코드 변경 시 발생할 수 있는 버그를 조기에 발견하고 수정하는 데 유용하다. 주요 기능으로는 어노테이션을 사용한 간편한 테스트 정의, Test Suite을 통한 여러 테스트의 그룹화, 다양한 메서드를 통한 테스트 결과 검증, 테스트 실행 중 예외 상황 처리, 그리고 테스트 실행 결과를 시각적으로 보여주는 리포트 기능 등이 있다. JUnit은 모듈화된 코드 테스트를 장려하며, 지속적 통합(CI) 도구와의 통합을 통해 자동화된 빌드 프로세스에서도 중요한 역할을 한다. 직관적이고 사용하기 쉬운 API 덕분에 개발자들이 테스트 케이스를 작성하고 유지보수하는 데 걸리는 시간을 줄이는 데 도움이 된다.

<br>

### 현실적 제한 및 개선 필요 사항
Expand Down

0 comments on commit 077ed13

Please sign in to comment.