- ✨ About Project
- 🛠️ Tech Stacks
- 🖼️ Architecture & Pattern
- 🗂️ ERD & User Scenario
- ☑️ Trouble Shooting
- 🔥 Performance Enhancement
- 👥 Contributors

저희 팀 원툴은 3D 도면 모델을 주로 사용하는 건축업계 종사자들을 위한 도면 서비스를 제공합니다.
- 필요한 도면만 빠르게
- 도면 구매를 보다 간편하게
- 내가 만든 도면 판매를 안전하게
현재 건축 업계에선 아래와 같은 문제점이 있어요.
- 건축 업계에서의 도면 유통 한계
- 교육용 도면 배포 환경 구축
팀 원툴은 건축 업계의 도면 사용을 활성화하기 위해 노력하고 있습니다.
- 프로젝트 이름: 원툴 Onetool
- 개발 기간: 2024.03 ~ 2024.12
- 성과
이름 | 성과 | 일시 |
---|---|---|
세종대캠퍼스타운 창업아이디아톤 | 대상 | 2024.07.31 |
세종대학교 IT컨퍼런스 | 우수상 (5/15팀) | 2024.09.26 |
세종대 캠퍼스타운 창업세미나 모의 IR | 우수상 (2등/50팀) | 2024.09.11 |
세종대 피칭&멘토링대회 | 우수상 (3등/6명) | 2024.09.11 |
세종대 창업 컨설팅 | 수료 | 2024.08.14 |
[Language & Frameworks]
[DB]
[DevOps]
요구 사항 | 선택지 | 기술 선택 이유 |
---|---|---|
💽Database | 1. MySQL 2. PostgreSQL 3. MariaDB 4. MongoDB 5. Redis |
- 도면 목록 및 검색 최적화를 위해 인덱스, 캐시, 버퍼 풀 등의 성능 최적화 기능을 제공하는 MySQL 사용 - 결제 및 구매 내역와 같은 중요한 데이터를 위한 InnoDB의 ACID 트랜잭션 사용 - Redis의 인메모리 데이터 저장 방식으로 토큰 조회 및 삽입 성능 개선 - 인증 코드의 자동 삭제를 위한 Redis의 TTL 기능 사용 |
🖥️Monitoring | 1. Jmeter 2. Prometheus 3. AWS CloudWatch |
- 설치 용이성과 비용적 장점을 가진 Prometheus 사용 - Expert 설치를 통한 풀링 방식으로 메트릭 수집이 용이 |
🛠️CI/CD | 1. Github Actions 2. Jenkins |
- 별도의 서버 구축이 필요없는 Github Actions 사용 - YAML 기반 간편하고 쉬운 스크립트 작성 |

- Q. 개발 서버와 운영 서버를 나눈 이유가 무엇인가요?
- 저희는 판매 기능을 제공합니다.
- 이런 기능은 실제 배포된 환경에서 정상적으로 작동하는지 확인이 필요합니다.
- Q. ALB와 Nginx를 두 개 모두 사용하나요?
- 공식 서비스에선 품질 보증이 가능한 AWS 서비스를 사용했습니다.
- 하지만, 비용 문제가 발생했고 품질이 중요하지 않은 개발 서버까지 ALB를 도입할 필요성이 없었습니다.
- 따라서, 비용이 발생하지 않는 Nginx를 개발 서버에 도입했습니다.
- Q. 왜
Service
와Business
레이어가 나뉘어 있나요?- 각 도메인 Service 내에서 중복되는 코드(DB 접근 및 DTO 매핑)가 많다는 것을 파악하였습니다.
- 따라서, 핵심 비즈니스 로직은 Business에, 비즈니스 로직으로 보기 애매한 중복 로직은 Service에 담았습니다.
- Q.
Repository 인터페이스
는 왜 사용되나요?- 저희는 라이브러리에 종속되는 것을 지양합니다. JpaRepository는 RDB에 국한되기 때문에 추후 NoSQL로의 마이그레이션에 폐쇄적입니다.
- 따라서, Repository 인터페이스에 역할을 정하고, 이를 상속받는 JpaRepository를 사용 중입니다.

이름 | 태그 | URL |
---|---|---|
RestAssured가 포트를 찾지 못하는 문제 | Spring, Test, RestAssured | URL |
커넥션이 Read-Only인 문제 | Spring, JPA | URL |
JWT의 Claim이 Long인데 Double로 인식되는 버그 | JWT | URL |
MySQL 루트 비밀번호 분실 시, 초기화 | AWS, MySQL | URL |
permitAll() 적용해도 Filter 통과되는 문제 | Spring | URL |
리액트에서만 CORS 발생 문제 | Axios | URL |
서브 모듈 카피가 작동하지 않는 문제 | Git | URL |
Spring security Auhentication이 저장되지 않는 버그 | Spring Security | URL |
Redis 저장 시, 공백이 앞쪽에 붙는 버그 | Redis | URL |
도커 컴포즈에서 이미지를 pull하지 못하는 문제 | Docker | URL |
RequestMatcher가 작동하지 않는 문제 | Spring Security | URL |
Controller Mock 테스트 시, 빈 주입이 안되는 문제 | Spring, Test, Mockito | URL |
Jwt 토큰이 제대로 작동하지 않는 문제 | JWT | URL |
@CreationTimestamp로 생성된 일자가 DTO에 담기지 않는 문제 | Spring, JPA | URL |
도커 이미지에 업데이트가 반영되지 않는 문제 | 🐋Docker | URL |
WebSocket 시, 경로를 MVC가 인식하지 못하는 문제 | Spring, WebSocket | URL |
-
커버링 인덱스로 검색 쿼리 속도 향상 (🔗PR#182)
커버링 인덱스
를 이용해 검색 기능의 수행 시간이 637ms → 473ms로 약34%
향상- Count 쿼리의 인덱스 사용 시, 미비한 차이로 인한 불필요한 인덱스 사용 방지
-
WebSocket 기반 다대다 채팅 시스템 구현 (🔗PR#234)
- 부하테스트를 통한 읽기, 쓰기 처리량 기반 데이터베이스 선정(MySQL, MongoDB, PostgreSQL 비교)
- 내부 메시지 큐 시스템의 동시 쓰기로 인한 에러를,
@Async
를 통해 해결하여 TPS가 6.7/s → 11.9/s로 약77%
향상
-
대용량 데이터의 키워드 기반 검색 최적화 (🔗아티클)
- MySQL의
Full-Text Index
를 도입하여 문장 토큰화 기반 인덱싱 도입 - 100만 건 데이터 기준 검색 수행 시간을 16,981ms → 0.224ms 약
99.9%
성능
- MySQL의
-
Fake 기법을 통해 테스트 속도 개선 (🔗PR#209)
- 빈 컨텍스트 사용 대신
Fake
를 이용하여 컨텍스트 멤버 생성 기능의 테스트 속도를 990ms에서 460ms로46%
향상 - 테스트의 대부분을 차지하는 단위 테스트의 수행 속도를 평균
36%
개선
- 빈 컨텍스트 사용 대신
-
N+1 문제 해결로 실행 쿼리 감소 (🔗PR#115)
- 다대일 관계의 적은 중복 문제 해결을 위해
inner join
을 사용하여 키워드 검색 쿼리를 6개 → 4개 감소
- 다대일 관계의 적은 중복 문제 해결을 위해
Front | Back | Back | Back | Back |
---|---|---|---|---|
강인권 | 이동훈 | 윤성원 | 정다영 | 이동호 |