Skip to content

Commit 8084957

Browse files
authored
Merge: UX개선과 이미지기능 구현
대격변: UX개선과 이미지기능 구현
2 parents 8b8e785 + 824d174 commit 8084957

99 files changed

Lines changed: 3199 additions & 1666 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

build.gradle

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ plugins {
44
id 'io.spring.dependency-management' version '1.1.7'
55
}
66

7-
group = 'io.EJangs'
8-
version = '0.0.1'
7+
group = 'io.ejangs'
8+
version = '1.0.0'
99

1010
java {
1111
toolchain {
@@ -60,6 +60,12 @@ dependencies {
6060
testImplementation 'com.h2database:h2'
6161
testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
6262
testImplementation 'org.awaitility:awaitility:4.2.0'
63+
64+
implementation 'com.github.gavlyukovskiy:datasource-proxy-spring-boot-starter:1.12.1'
65+
66+
implementation platform('software.amazon.awssdk:bom:2.42.35')
67+
implementation 'software.amazon.awssdk:s3'
68+
6369
}
6470

6571
tasks.named('test') {

infra/docker-compose.stg.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ services:
5252
container_name: docsa-mysql-stg
5353
restart: unless-stopped
5454
env_file: .stg.env
55+
ports:
56+
- "127.0.0.1:3307:3306"
5557
volumes:
5658
- stg_mysql_data:/var/lib/mysql
5759
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro

infra/docker-compose.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ services:
3232
container_name: docsa-mysql
3333
restart: unless-stopped
3434
env_file: .env
35+
ports:
36+
- "127.0.0.1:3308:3306"
3537
volumes:
3638
- mysql_data:/var/lib/mysql
3739
- ./mysql/my.cnf:/etc/mysql/conf.d/my.cnf:ro

perf/cleanup_perf_docs.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ MODE="${MODE:-all}" # single | multi | all
1515
USER_PASSWORD="${USER_PASSWORD:-Testtest1}"
1616
TEST_EMAIL="${TEST_EMAIL:-test@test.com}"
1717

18-
USER_PREFIX="${USER_PREFIX:-perfdel}"
18+
USER_PREFIX="${USER_PREFIX:-perfuser}"
1919
USER_DOMAIN="${USER_DOMAIN:-test.com}"
2020
USER_COUNT="${USER_COUNT:-100}"
2121
SEARCH_PAGE_SIZE="${SEARCH_PAGE_SIZE:-100}"

perf/delete/README.md

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,31 @@ MONGO_URI='...' MYSQL_USERNAME='devbae' MYSQL_PASSWORD='' SPRING_PROFILES_ACTIVE
3131
MAIL_USERNAME='...' MAIL_PASSWORD='...'
3232
```
3333

34-
## 1) Prepare users (no script)
34+
## 1) Prepare users
3535

36-
유저 생성은 애플리케이션의 `TestUserInitializer`를 사용합니다.
36+
유저 생성은 애플리케이션의 `PerfDataInitializer`를 사용합니다.
37+
삭제 벤치용으로 유저만 만들 때는 `DOCS_PER_USER`를 0으로 둡니다.
3738

3839
```bash
3940
PERF_SEED_USER_COUNT=100
41+
PERF_SEED_DOCS_PER_USER=0
42+
```
43+
44+
`PerfDataInitializer`로 문서까지 직접 주입할 때는 아래 옵션도 같이 사용합니다.
45+
이 경우 문서, 브랜치, 커밋, 간선, save, Mongo block/commitBlockSequence/saveContent가 생성됩니다.
46+
47+
```bash
48+
PERF_SEED_RUN_ID=run01
49+
PERF_SEED_DOCS_PER_USER=3
50+
PERF_SEED_BRANCHES_PER_DOC=2
51+
PERF_SEED_COMMITS_PER_BRANCH=6
52+
PERF_SEED_BLOCKS_PER_SAVE=20
53+
PERF_SEED_BLOCKS_PER_COMMIT=20
4054
```
4155

4256
유저 패턴:
4357

44-
- `perfdel_u001@test.com` ~ `perfdel_u100@test.com`
58+
- `perfuser_u001@test.com` ~ `perfuser_u100@test.com`
4559
- 비밀번호: `Testtest1`
4660

4761
## 2) Seed realistic dataset
@@ -51,7 +65,7 @@ PERF_SEED_USER_COUNT=100
5165
```bash
5266
RUN_ID=run01 \
5367
BASE_URL=http://localhost:8080 \
54-
USER_PREFIX=perfdel USER_DOMAIN=test.com USER_PASSWORD=Testtest1 \
68+
USER_PREFIX=perfuser USER_DOMAIN=test.com USER_PASSWORD=Testtest1 \
5569
USER_COUNT=100 DOCS_PER_USER=3 \
5670
MAIN_COMMITS=6 FEATURE_COMMITS=4 BLOCKS_PER_COMMIT=20 \
5771
SEED_VUS=20 \
@@ -69,7 +83,7 @@ k6 run perf/delete/seed_dataset.js
6983
```bash
7084
RUN_ID=run01 \
7185
BASE_URL=http://localhost:8080 \
72-
USER_PREFIX=perfdel USER_DOMAIN=test.com USER_PASSWORD=Testtest1 \
86+
USER_PREFIX=perfuser USER_DOMAIN=test.com USER_PASSWORD=Testtest1 \
7387
USER_COUNT=100 DOCS_PER_USER=3 \
7488
DELETE_VUS=30 \
7589
k6 run perf/delete/delete_only_benchmark.js \
@@ -88,7 +102,7 @@ k6 run perf/delete/delete_only_benchmark.js \
88102

89103
1. 브랜치 checkout
90104
2. 서버 실행
91-
3. 유저 준비(`PERF_SEED_USER_COUNT` 적용된 상태)
105+
3. 유저 준비(`PERF_SEED_USER_COUNT`, `PERF_SEED_DOCS_PER_USER=0` 적용된 상태)
92106
4. 데이터 생성 (`seed_dataset.js`)
93107
5. 삭제 벤치 실행 (`delete_only_benchmark.js`)
94108
6. 결과 파일 저장
@@ -120,7 +134,7 @@ node perf/delete/compare_delete_summary.mjs \
120134
```bash
121135
BASE_URL=http://localhost:8080 \
122136
MODE=multi \
123-
USER_PREFIX=perfdel USER_DOMAIN=test.com USER_COUNT=100 \
137+
USER_PREFIX=perfuser USER_DOMAIN=test.com USER_COUNT=100 \
124138
USER_PASSWORD=Testtest1 \
125139
bash perf/cleanup_perf_docs.sh
126140
```
@@ -131,7 +145,7 @@ staging HTTPS(자체 서명 인증서)면:
131145
BASE_URL=https://<stg-domain-or-ip>:8443 \
132146
INSECURE_TLS=1 \
133147
MODE=multi \
134-
USER_PREFIX=perfdel USER_DOMAIN=test.com USER_COUNT=100 \
148+
USER_PREFIX=perfuser USER_DOMAIN=test.com USER_COUNT=100 \
135149
USER_PASSWORD=Testtest1 \
136150
bash perf/cleanup_perf_docs.sh
137151
```

perf/delete/delete_only_benchmark.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { check } from 'k6';
44
import { Rate, Trend } from 'k6/metrics';
55

66
const BASE_URL = __ENV.BASE_URL || 'http://localhost:8080';
7-
const USER_PREFIX = __ENV.USER_PREFIX || 'perfdel';
7+
const USER_PREFIX = __ENV.USER_PREFIX || 'perfuser';
88
const USER_DOMAIN = __ENV.USER_DOMAIN || 'test.com';
99
const USER_PASSWORD = __ENV.USER_PASSWORD || 'Testtest1';
1010
const USER_COUNT = Number(__ENV.USER_COUNT || 50);

perf/delete/seed_dataset.js

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { check } from 'k6';
44
import { Rate, Trend } from 'k6/metrics';
55

66
const BASE_URL = __ENV.BASE_URL || 'http://localhost:8080';
7-
const USER_PREFIX = __ENV.USER_PREFIX || 'perfdel';
7+
const USER_PREFIX = __ENV.USER_PREFIX || 'perfuser';
88
const USER_DOMAIN = __ENV.USER_DOMAIN || 'test.com';
99
const USER_PASSWORD = __ENV.USER_PASSWORD || 'Testtest1';
1010
const USER_COUNT = Number(__ENV.USER_COUNT || 50);
@@ -132,12 +132,10 @@ function buildCommitBody(title, branchId) {
132132
for (let i = 0; i < BLOCKS_PER_COMMIT; i += 1) {
133133
const blockId = `${title}-b${i}-${Math.floor(Math.random() * 1e6)}`;
134134
blocks.push({
135+
id: blockId,
136+
type: 'paragraph',
135137
data: {
136-
id: blockId,
137-
type: 'paragraph',
138-
data: {
139-
text: `${title}-text-${i}`,
140-
},
138+
text: `${title}-text-${i}`,
141139
},
142140
});
143141
blockOrders.push(blockId);

perf/read/README.md

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Document List Performance Benchmark
2+
3+
목표:
4+
5+
- 문서 목록 조회 경로의 읽기 성능을 별도로 측정
6+
- `sidebar`(최근 활동만)와 `full list`(preview 포함), `search`(preview 포함)를 분리 비교
7+
- 문서 수, branch 수, preview 조립 비용이 응답 시간에 미치는 영향을 확인
8+
9+
## Files
10+
11+
- `perf/delete/seed_dataset.js`
12+
- 목록 테스트에 사용할 문서/브랜치/커밋 데이터를 생성
13+
- `perf/read/doc_list_benchmark.js`
14+
- `sidebar`, `full list`, `search` 읽기 성능 측정
15+
16+
## Why this benchmark
17+
18+
현재 목록 조회는 `Doc` 페이지 조회 후, 각 문서마다 최근 branch를 찾고 preview를 조립합니다.
19+
`sidebar`는 JPA 연관 로딩 비용, `full list``search`는 여기에 Mongo preview 조립 비용까지 추가로 확인할 수 있습니다.
20+
21+
## 1) Prepare users
22+
23+
유저 생성은 애플리케이션의 `PerfDataInitializer`를 사용합니다.
24+
API seed 스크립트로 문서를 만들 때는 여기서는 유저만 준비합니다.
25+
26+
```bash
27+
PERF_SEED_USER_COUNT=50
28+
PERF_SEED_DOCS_PER_USER=0
29+
```
30+
31+
유저 패턴:
32+
33+
- `perfuser_u001@test.com` ~ `perfuser_u050@test.com`
34+
- 비밀번호: `Testtest1`
35+
36+
## 2) Seed dataset
37+
38+
삭제 벤치에서 쓰던 seed 스크립트를 그대로 재사용합니다.
39+
중요한 건 목록 조회 시 문서별 branch/commit이 충분히 많아지도록 데이터를 만드는 것입니다.
40+
41+
```bash
42+
RUN_ID=read01 \
43+
BASE_URL=http://localhost:8080 \
44+
USER_PREFIX=perfuser USER_DOMAIN=test.com USER_PASSWORD=Testtest1 \
45+
USER_COUNT=50 DOCS_PER_USER=5 \
46+
MAIN_COMMITS=8 FEATURE_COMMITS=5 BLOCKS_PER_COMMIT=100 \
47+
SEED_VUS=20 \
48+
k6 run perf/delete/seed_dataset.js
49+
```
50+
51+
애플리케이션 initializer로 DB에 직접 주입할 수도 있습니다. 이 방식은 API 호출 비용 없이
52+
문서, 브랜치, 커밋, 간선, save, Mongo block/commitBlockSequence/saveContent를 생성합니다.
53+
54+
```bash
55+
PERF_SEED_RUN_ID=read01 \
56+
PERF_SEED_USER_COUNT=50 \
57+
PERF_SEED_DOCS_PER_USER=5 \
58+
PERF_SEED_BRANCHES_PER_DOC=2 \
59+
PERF_SEED_COMMITS_PER_BRANCH=8 \
60+
PERF_SEED_BLOCKS_PER_SAVE=100 \
61+
PERF_SEED_BLOCKS_PER_COMMIT=100
62+
```
63+
64+
권장 기준:
65+
66+
- `DOCS_PER_USER`: 5 이상
67+
- `MAIN_COMMITS`: 8 이상
68+
- `FEATURE_COMMITS`: 5 이상
69+
- `BLOCKS_PER_COMMIT`: 100 이상
70+
71+
## 3) Run list benchmark
72+
73+
```bash
74+
RUN_ID=read01 \
75+
BASE_URL=http://localhost:8080 \
76+
USER_PREFIX=perfuser USER_DOMAIN=test.com USER_PASSWORD=Testtest1 \
77+
USER_COUNT=50 DOCS_PER_USER=5 PAGE_SIZE=10 \
78+
SEARCH_PREFIX=PDEL \
79+
SIDEBAR_VUS=10 FULL_LIST_VUS=10 SEARCH_VUS=10 \
80+
k6 run perf/read/doc_list_benchmark.js
81+
```
82+
83+
`PerfDataInitializer`로 직접 주입한 데이터는 문서 제목 prefix가 `PERF`이므로 검색 벤치에서
84+
아래처럼 맞춥니다.
85+
86+
```bash
87+
SEARCH_PREFIX=PERF
88+
```
89+
90+
결과 파일:
91+
92+
- `perf/read/results/doc_list_benchmark_<RUN_ID>.json`
93+
94+
핵심 지표:
95+
96+
- `op_doc_sidebar_ms`
97+
- `op_doc_list_ms`
98+
- `op_doc_search_ms`
99+
- `http_req_duration`
100+
- `http_req_failed`
101+
102+
## 4) Recommended comparison order
103+
104+
1. `sidebar` vs `full list`
105+
2. `full list` vs `search`
106+
3. 같은 조건에서 `PAGE_SIZE=10`, `20`, `50` 비교
107+
108+
해석 기준:
109+
110+
- `sidebar`보다 `full list`가 크게 느리면 preview 조립 비용 영향이 큼
111+
- `search`까지 더 느리면 목록 조립 비용 + 검색 쿼리 비용이 함께 작동
112+
- `PAGE_SIZE` 증가에 따라 p95가 급격히 오르면 per-doc 조립 비용이 병목일 가능성이 큼

0 commit comments

Comments
 (0)