Skip to content

Commit d05f5fb

Browse files
authored
Docs: README.md 작성
1 parent 4c6276c commit d05f5fb

File tree

1 file changed

+278
-0
lines changed

1 file changed

+278
-0
lines changed

README.md

Lines changed: 278 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,278 @@
1+
| 최은소 (INFRA) | 오예린 (INFRA) | 권민정 (BE) | 선우예림 (BE) | 황지민 (BE) |
2+
| :---: | :---: | :---: | :---: | :---: |
3+
| <img src="https://avatars.githubusercontent.com/u/93801149?v=4" alt="최은소 프로필" width="180" height="180"> | <img src="https://avatars.githubusercontent.com/YelynnOh" alt="오예린 프로필" width="180" height="180"> | <img src="https://avatars.githubusercontent.com/u/145860909?v=4" alt="권민정 프로필" width="180" height="180"> | <img src="https://avatars.githubusercontent.com/u/54367532?v=4" alt="선우예림 프로필" width="180" height="180"> | <img src="https://avatars.githubusercontent.com/u/88023963?v=4" alt="황지민 프로필" width="180" height="180"> |
4+
| [esc-beep](https://github.com/esc-beep) | [YelynnOh](https://github.com/YelynnOh) | [mjttong](https://github.com/mjttong) | [yerimsw](https://github.com/yerimsw) | [Jimin-Hwang00](https://github.com/Jimin-Hwang00) |
5+
6+
# 프로젝트 소개
7+
8+
## 파일 공유 시스템 **설계**
9+
10+
- 파일을 업로드하고 링크를 통해 공유할 수 있는 기능을 구현한다.
11+
- 업로드된 파일의 메타데이터를 처리하여 별도로 저장한다.
12+
13+
**요구 조건**
14+
15+
- 매일 약 100-200개의 새로운 파일 업로드 예상
16+
- 파일 당 평균 크기는 50MB 예상
17+
- 최대 50GB의 파일 저장 용량 필요
18+
- 파일 업/다운로드 지연 시간은 1분 이내
19+
20+
**심화 조건**
21+
22+
> 심화 조건은 기본 요구 조건을 모두 만족한 후 생각해볼만한 추가적인 구현에 대한 내용입니다.
23+
>
24+
- 대용량 파일 전송: 최대 1GB 크기의 파일 공유 링크 생성 기능
25+
- 접근 제어: 파일 및 폴더 단위의 세부적인 접근 권한 설정 기능
26+
- 버전 관리: 주요 파일에 대한 최대 5개 버전 히스토리 관리
27+
- 파일 검색: 파일명, 내용 기반 검색 기능 제공 (검색 결과 응답 시간 5초 이내)
28+
29+
# 유저 시나리오
30+
31+
![유저 시나리오 -Version5.drawio.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/388131ba-2bfe-46d3-bbef-cf6af069791b/%E1%84%8B%E1%85%B2%E1%84%8C%E1%85%A5_%E1%84%89%E1%85%B5%E1%84%82%E1%85%A1%E1%84%85%E1%85%B5%E1%84%8B%E1%85%A9_-Version5.drawio.png)
32+
33+
# 아키텍처 설계
34+
35+
## 발표 시점
36+
37+
![5차 다이어그램-페이지-1.drawio.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/23c71557-9399-4684-8a1b-24223c790e6c/5%EC%B0%A8_%EB%8B%A4%EC%9D%B4%EC%96%B4%EA%B7%B8%EB%9E%A8-%ED%8E%98%EC%9D%B4%EC%A7%80-1.drawio.png)
38+
39+
1. 전체 아키텍처 설명
40+
1. 전체 VPC에서 Public 서브넷과 Private 서브넷을 분리하여 사용자가 접근할 수 있는 부분과 DB를 저장할 수 있는 부분으로 아키텍처를 분리
41+
2. WAS 역할을 하는 EC2 인스턴스를 Public 서브넷에 배치, DB 역할을 하는 RDS 인스턴스를 Private Subnet에 배치함
42+
2. IGW
43+
1. 인터넷과 Public Subnet을 연결해주는 관문 역할을 하기 위해 배치
44+
3. ALB
45+
1. WAS의 부하를 분산 시킬 수 있는 용도로 ALB를 Public 서브넷에 배치함
46+
2. HTTP 8080 포트로 들어오는 요청에 대해 지정된 2개의 EC2 인스턴스로 트래픽 분산
47+
4. EC2
48+
1. 도커를 이용해 컨테이너화 시킨 SpringBoot 서버(WAS)를 띄우기 위한 인스턴스
49+
2. 총 2개의 인스턴스가 ALB에 연결되어 트래픽을 분산하여 담당하고 있음
50+
5. RDS
51+
1. RDS Primary - RDS Read Replica 구조 확립
52+
1. 읽기 작업이 많은 프로젝트 요구 사항을 반영하기 위해 RDS Primary 이 외에 RDS Read Replica를 추가해 읽기 작업 퍼포먼스 향상
53+
2. RDS Primary와 RDS Read Replica를 서로 다른 가용 영역에 배치
54+
6. Gateway endpoint
55+
1. EC2 인스턴스와 VPC 외부에 위치한 S3를 연결하기 위해 활용
56+
2. 비용 효율성과 S3와의 호환성을 고려해 해당 서비스 선정
57+
7. S3
58+
1. 파일 원본 저장소
59+
2. EC2와 Gateway Endpoint로 연결 되어 있음
60+
8. Monitoring
61+
- 서비스 모니터링을 위해 CloudWatch와 CloudTrail 활용
62+
9. CI/CD
63+
1. CI/CD의 경우 아래의 단계를 거쳐 진행됨
64+
2. 개발자가 GitHub 레포지토리에 코드를 푸시함
65+
3. GitHub Action이 Docker Hub에 도커 이미지를 업로드하고 S3에 프로젝트 압축 파일을 업로드함
66+
4. 이후 Code Deploy는 S3에 게시된 압축 파일을 이용해 EC2 인스턴스에 배포 진행
67+
68+
## 추가 진행 시점
69+
70+
![6차 아키텍처-페이지-1의 복사본.drawio.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/4e9d85ad-8074-4f91-b465-1351e0948e32/6%EC%B0%A8_%EC%95%84%ED%82%A4%ED%85%8D%EC%B2%98-%ED%8E%98%EC%9D%B4%EC%A7%80-1%EC%9D%98_%EB%B3%B5%EC%82%AC%EB%B3%B8.drawio.png)
71+
72+
1. 전체 아키텍처 설명
73+
1. AWS VPC (10.0.0.0/16) 내에서 Public 서브넷과 Private 서브넷을 명확히 분리하여 보안성을 강화
74+
2. WAS 역할을 하는 EC2 인스턴스를 Private 서브넷에 배치하여 직접적인 외부 접근을 차단하며, DB 역할을 하는 RDS 인스턴스 역시 Private Subnet에 배치함
75+
2. Route53
76+
1. `acc6-hotsix.shop` 도메인 사용
77+
3. NAT
78+
1. Private 서브넷의 EC2 인스턴스들이 인터넷과 통신할 수 있도록 NAT Gateway 배치
79+
4. RDS
80+
1. 해커톤 당시 Read Replica는 성능을 위한 서비스이지 가용성을 위한 것은 아니라는 피드백을 받음
81+
2. Multi-AZ 구성으로 설정하여 RDS의 고가용성 보장
82+
3. RDS Primary - RDS Read Replica 구조를 유지하여 읽기 작업 퍼포먼스 향상
83+
5. S3
84+
1. S3 Glacier를 도입하여 장기 보관된 데이터를 비용 효율적으로 저장
85+
6. EC2
86+
1. EC2 인스턴스를 private subnet으로 이동하여 보안 강화
87+
7. Auto Scaling Group
88+
1. 트래픽 변화에 따라 EC2 인스턴스의 수를 자동으로 조절
89+
2. EC2 인스턴스는 시작 템플릿을 통해 생성됨
90+
8. AWS Session Manager
91+
1. 관리자가 EC2 인스턴스에 SSH 키 없이 안전하게 접근할 수 있음
92+
9. 네트워크 접근 제어
93+
1. Security Group을 통해 서브넷 안에서 인스턴스의 트래픽을 제어함
94+
2. NACL을 통해 서브넷에 오가는 트래픽을 제어함
95+
10. CI/CD
96+
1. 개발자가 GitHub 레포지토리에 코드를 푸시함
97+
2. GitHub Action이 Docker 이미지를 ECR에 배포
98+
3. 배포 스크립트를 S3에 업로드
99+
4. CodeDeploy를 통해 애플리케이션 자동 배포
100+
101+
## CI/CD
102+
103+
- github action + Docker + ECR + Codedeploy를 사용한 방식
104+
105+
![image.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/9367a398-1331-454b-b8c0-36c3c0b7cda9/image.png)
106+
107+
- github action이 docker 이미지를 생성해 ECR에 업로드, codedeploy 스크립트를 생성해 S3에 업로드
108+
- S3에 업로드한 스크립트를 codedeploy가 실행하도록 githubaction에서 트리거 전송
109+
- codedeploy 스크립트 실행 후 배포 진행
110+
111+
# 서버 설계
112+
113+
## 사용한 기술 스택
114+
115+
- spring boot
116+
- mysql
117+
118+
## ERD
119+
120+
- 파일 메타데이터 저장
121+
- 로그 저장
122+
123+
## 발표 이후 변화
124+
125+
- SDK v1에서 v2로 버전 업
126+
- 기존의 multipart 및 정적 S3 URL를 사용한 업로드, 다운로드를 모두 presigned URL 방식으로 변경
127+
- CI/CD 재구축
128+
- 예외 처리 전략 변경
129+
130+
## 기능 명세서
131+
132+
| 기능 | 설명 | 예외처리 |
133+
| --- | --- | --- |
134+
| 파일 업로드 | - 업로드 불가능한 파일 타입: 실행 파일, 셸 스크립트, 자바 아카이브 파일 제외
135+
136+
- 파일 경로: ’/’로 시작, 알파벳, 숫자, 밑줄만 포함 | - 유효하지 않은 비밀번호
137+
- 파일 중복: 같은 경로, 동일한 파일명 존재 |
138+
| 파일 다운로드 | - 파일 다운로드 | - 유효하지 않은 비밀번호
139+
- 파일 없음 |
140+
| 파일 수정 | - 기존 파일과 동일한 파일 타입을 가진 파일로 수정 가능
141+
142+
- 수정 범위: 파일명, 파일 경로, 파일 | - 유효하지 않은 비밀번호
143+
- 파일 없음
144+
- 파일 중복: 같은 경로, 동일한 파일명 존재
145+
- 파일 타입 변화: 기존 파일과 수정 파일의 타입이 다름 |
146+
| 파일 조회
147+
(메타 데이터) | - 조회 결과: 파일 ID, 파일 이름, 파일 생성시간, 파일 확장자, 파일 경로, 수정일자, 원본 리소스 위치 | - 유효하지 않은 비밀번호
148+
- 파일 없음 |
149+
| 파일 조회
150+
(파일) | - 조회 결과: 파일 미리보기 | - 유효하지 않은 비밀번호
151+
- 파일 없음 |
152+
| 파일 공유링크 생성 | - 공유 링크 생성: GET Presigned URL 생성 | - 유효하지 않은 비밀번호
153+
- 파일 없음 |
154+
| 파일 삭제 | - 파일 삭제 | - 유효하지 않은 비밀번호
155+
- 파일 없음 |
156+
| 파일 검색 | - 조회 결과: 파일 ID, 파일 이름, 파일 생성시간, 파일 확장자, 파일 경로 | - 조회 가능한 값 없음
157+
- 검색조건 없음 |
158+
| 파일 조회
159+
(페이지) | - 조회 결과: 파일 ID, 파일 이름, 파일 생성시간, 파일 확장자, 파일 경로 | - 조회 가능한 값 없음
160+
- name, time 파라미터에 asc, desc 외의 다른 값 입력 |
161+
| 파일 조회
162+
(전체) | - 조회 결과: 파일 ID, 파일 이름, 파일 생성시간, 파일 확장자, 파일 경로
163+
164+
- 파일 정렬: 파일 이름, 파일 생성 시간 오름차순 정렬 | - 조회 가능한 값 없음 |
165+
| 로그 조회 | - 로그 조회 | - 파일 없음 |
166+
167+
## API
168+
169+
| 기능명 | URL | Http Method | body |
170+
| --- | --- | --- | --- |
171+
| 파일 업로드 | /files | `POST` | file
172+
directory
173+
password |
174+
| 파일 다운로드 | /files/download/{file_id} | `POST` | password |
175+
| 파일 수정 | /files/{file_id} | `PATCH` | file
176+
directory
177+
password |
178+
| 파일 상세 조회(메타데이터) | /files/detail-meta/{file_id} | `POST` | password |
179+
| 파일 상세 조회(파일) | /files/detail-file/{file_id} | `POST` | password |
180+
| 파일 공유링크 | /files/share/{file_id} | `POST` | password |
181+
| 삭제 | /files/delete/{file_id} | `POST` | password |
182+
- presigned URL 방식으로 변경한 API
183+
- 모두 비밀번호가 필요한 API이며, 비밀번호를 form-data로 전달
184+
185+
| 기능명 | URL | Http Method | params |
186+
| --- | --- | --- | --- |
187+
| 전체 조회 | /files/all | `GET` | |
188+
| 조회(페이지 단위) | /files | `GET` | page
189+
name
190+
time |
191+
| 검색 | /files/search | `GET` | name
192+
path
193+
before, after
194+
type
195+
page |
196+
| 로그 조회 | /files/{file_id}/logs | `DELETE` | type
197+
page
198+
size |
199+
- 비밀번호가 필요없으며, 수정하지 않은 API
200+
201+
# 부하 테스트
202+
203+
## 파일 업로드 테스트
204+
205+
![image.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/59622d38-796d-4b10-9b32-9e607fefedac/image.png)
206+
207+
- 5명의 사용자가 동시 접속
208+
- 각 사용자는 3분 동안 계속해서 파일 업로드를 반복 실행
209+
- 각 반복 사이에는 1초의 휴식(`sleep(1)`)이 있음
210+
- 파일은 .txt(1MB), .pdf(50MB), .zip(100MB)로 구성되었으며, 실제로 S3에 업로드를 진행
211+
- 3분 동안 이루어진 45개의 요청에 대해 100% 성공
212+
213+
## 파일 다운로드 테스트
214+
215+
![image.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/dc2fd199-f1f6-494d-8a87-5d18bcaa667b/image.png)
216+
217+
- 2명의 사용자가 동시 접속
218+
- 각 사용자는 3분 동안 계속해서 파일 다운로드를 반복 실행
219+
- 각 반복 사이에는 1초의 휴식(`sleep(1)`)이 있음
220+
- 파일은 .txt(1MB), .pdf(50MB), .zip(100MB)로 구성
221+
- 3분 동안 이루어진 37개의 요청에 대해 75.67% 성공
222+
223+
## 파일 업로드/다운로드 동시 테스트
224+
225+
![image.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/bda4d7f4-1501-4860-8096-2722a272372d/image.png)
226+
227+
- 3명의 사용자가 동시 접속
228+
- 각 사용자는 3분 동안 계속해서 파일 업로드/다운로드를 반복 실행
229+
- 각 반복 사이에는 1초의 휴식(`sleep(1)`)이 있음
230+
- 파일은 .txt(1MB), .pdf(50MB), .zip(100MB)로 구성
231+
- 3분 동안 이루어진 27개의 요청에 대해 86.66% 성공
232+
233+
## 파일 검색 테스트
234+
235+
![image.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/485a3e47-0f7c-4e76-a68e-5d5a9f3d26fc/image.png)
236+
237+
- 2명의 사용자가 동시 접속
238+
- 각 사용자는 3분 동안 계속해서 검색 반복 실행
239+
- 각 반복 사이에는 1초의 휴식(`sleep(1)`)이 있음
240+
- 파일은 .txt(1MB), .pdf(50MB), .zip(100MB)로 구성
241+
- 3분 동안 이루어진 351개의 요청에 대해 100% 성공
242+
243+
## 메타데이터 조회 테스트
244+
245+
![image.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/ac76b844-b286-4e63-a704-74afb0a7c3d1/image.png)
246+
247+
- 1분 동안 사용자가 10명으로 증가 → 5분 동안 사용자가 10명으로 유지 → 1분 동안 사용자가 0명으로 감소
248+
- 각 사용자는 계속해서 메타데이터 조회 반복 실행
249+
- 각 반복 사이에는 1초의 휴식(`sleep(1)`)이 있음
250+
- 파일은 .txt(1MB), .pdf(50MB), .zip(100MB)로 구성
251+
- 7분 동안 이루어진 3133개의 요청에 대해 98.65% 성공
252+
253+
## 파일 조회 테스트
254+
255+
![image.png](https://prod-files-secure.s3.us-west-2.amazonaws.com/b782f691-dec6-485a-a6a8-2827dfef2dd5/c3e6970b-a82e-4359-b483-fa44fccf02b6/image.png)
256+
257+
- 1분 동안 사용자가 5명으로 증가 → 5분 동안 사용자가 5명으로 유지 → 1분 동안 사용자가 0명으로 감소
258+
- 각 사용자는 계속해서 파일 조회 반복 실행
259+
- 각 반복 사이에는 1초의 휴식(`sleep(1)`)이 있음
260+
- 파일은 .txt(1MB), .pdf(50MB), .zip(100MB)로 구성
261+
- 7분 동안 이루어진 3133개의 요청에 대해 95.45% 성공
262+
263+
## 부하 테스트 정리
264+
265+
| | 파일
266+
업로드 | 파일
267+
다운로드 | 업로드/
268+
다운로드 | 파일 검색 | 메타데이터 조회 | 파일 조회 |
269+
| --- | --- | --- | --- | --- | --- | --- |
270+
| 테스트
271+
진행 시간 | 3분 | 3분 | 3분 | 3분 | 7분 | 7분 |
272+
| 평균 사용자 | 5명 | 2명 | 3명 | 2명 | 10명 | 10명 |
273+
| 총 발생 요청 | 45개 | 37개 | 27개 | 351개 | 3133개 | 3133개 |
274+
| 성공률 | 100% | 75.67% | 86.66% | 100% | 98.65% | 95.45% |
275+
- 매일 약 100-200개의 새로운 파일 업로드 예상
276+
- 파일 당 평균 크기는 50MB 예상
277+
278+
상기된 조건을 충족시키는 것을 확인할 수 있음

0 commit comments

Comments
 (0)