Skip to content

[feat] 부하테스트 진행#93

Merged
Namsoo315 merged 4 commits intodevelopfrom
feature/#86
Nov 4, 2025
Merged

[feat] 부하테스트 진행#93
Namsoo315 merged 4 commits intodevelopfrom
feature/#86

Conversation

@Namsoo315
Copy link
Copy Markdown
Collaborator

@Namsoo315 Namsoo315 commented Nov 4, 2025

Issues

✔️ Check-list

  • : Label을 지정해 주세요.
  • : Merge할 브랜치를 확인해 주세요.

🗒️ Work Description

부하테스트 (동접 테스트)
인덱싱 사용 O, X로 비교를 하였음.

📷 Screenshot

유저 1000명 : 인덱싱화 안하고 요청 + CPU, 메모리 상한 없이 + DB Max Connection 300

{8328ABA6-EB41-40B8-AB0C-6FB3455B9396}

유저 2000명 : 인덱싱화 하고 요청 + CPU, 메모리 상한 없이 + DB Max Connection 300

{19E9C523-DEE1-470B-A1F2-5D339657C6F9}

유저 2000명 : 인덱싱화 하고 요청 + CPU 4 , 메모리 2 상한 없이 + DB Max Connection 100

{DA9AF924-D748-4C05-9615-4B84A1B43A6E}

📚 Reference

Summary by CodeRabbit

  • New Features

    • NAVER 클라이언트 인증 환경 변수 지원 추가
  • Performance Improvements

    • 게시글 URL 저장소 용량 확대 (255 → 500자)
    • 댓글 조회 성능 최적화를 위한 복합 인덱스 추가
  • Infrastructure

    • 데이터베이스·캐시·메시지 큐 서비스 리소스 제한(메모리/예약) 설정
    • 모니터링/보안 접근 정책 개선 (허용 IP 범위 보완)

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Nov 4, 2025

Walkthrough

Docker Compose에 서비스별 deploy.resources 제한 추가, app 환경변수에 NAVER_CLIENT_ID/SECRET 추가, Prometheus actuator 접근 검증 로직 확장, articles.source_url 길이 확장 및 comments 테이블에 인덱스 2개 추가가 적용되었습니다.

Changes

Cohort / File(s) 변경 요약
Docker 인프라 구성
monew/docker-compose.yml
postgres, redis, mongo 서비스에 deploy.resources(limits 및 reservations) 블록 추가. app 서비스에 NAVER_CLIENT_ID, NAVER_CLIENT_SECRET 환경변수 추가.
보안 및 접근 제어
monew/src/main/java/.../SecurityConfig.java
@Slf4j 추가 및 prometheusAllowIp 기본값(127.0.0.1) 지정. /actuator/prometheus 접근 검증을 단일 IP 비교에서 IPv4/IPv6 localhost, 사설 네트워크 범위 및 설정값을 포함하는 허용 주소 집합 검사로 확장. 기존 필터 순서 유지로 requestIdFilter, headerAuthFilterUsernamePasswordAuthenticationFilter 앞에 배치 유지.
데이터베이스 스키마 최적화
monew/src/main/resources/schema.sql
articles.source_url 컬럼 VARCHAR(255) → VARCHAR(500)로 확장. commentsidx_comment_article_created (article_id, is_deleted, created_at DESC, id)idx_comment_article_like (article_id, is_deleted, like_count DESC, created_at DESC, id) 인덱스 추가.

Sequence Diagram(s)

sequenceDiagram
    autonumber
    participant Client
    participant App as Application
    participant Sec as SecurityConfig
    note right of Sec `#DDEBF7`: Prometheus IP 검증 로직 변경
    Client->>App: GET /actuator/prometheus
    App->>Sec: 요청 IP 확인
    alt IP in [localhost/::1, 127.0.0.1, private ranges, prometheusAllowIp]
        Sec-->>App: AuthorizationDecision(permit)
        App-->>Client: 200 OK (prometheus metrics)
    else
        Sec-->>App: AuthorizationDecision(deny)
        App-->>Client: 403 Forbidden
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

  • 주의 검토 항목:
    • SecurityConfig의 허용 IP 집합이 조직 보안 정책에 부합하는지 확인
    • schema.sql에 추가된 인덱스가 쿼리 패턴과 부하 테스트 시나리오에 적절한지 검토
    • docker-compose.yml의 CPU/메모리 limits/reservations 값이 부하 테스트 목표에 적절한지 검증

Possibly related PRs

Suggested reviewers

  • kimyumin03
  • yuhandemian

요약

개요

부하 테스트 준비를 위해 Docker 컴포즈에서 데이터베이스 및 캐시 서비스의 리소스 제한을 설정하고, Naver 클라이언트 인증 정보를 환경변수로 추가했으며, Prometheus 접근 제어를 확대하고 댓글 조회 성능 개선을 위한 인덱스를 추가했습니다.

변경 사항

응집도 / 파일 변경 요약
Docker 인프라 구성
monew/docker-compose.yml
Postgres, Redis, Mongo 서비스에 deploy.resources 블록 추가 (CPU/메모리 제한 및 예약). app 서비스 환경변수에 NAVER_CLIENT_ID 및 NAVER_CLIENT_SECRET 추가
보안 및 접근 제어
monew/src/main/java/com/spring/monew/auth/config/SecurityConfig.java
@Slf4j 로깅 지원 추가. prometheusAllowIp에 기본값(127.0.0.1) 설정. Prometheus 접근 로직을 정확한 일치 확인에서 IPv4/IPv6 localhost 및 사설 네트워크를 포함한 허용 주소 집합으로 확대. health/info/loggers actuator 접근을 permitAll로 리팩토링
데이터베이스 스키마 최적화
monew/src/main/resources/schema.sql
articles.source_url 컬럼을 VARCHAR(255)에서 VARCHAR(500)으로 확장. comments 테이블에 두 개의 인덱스 추가: idx_comment_article_created (article_id, is_deleted, created_at DESC, id), idx_comment_article_like (article_id, is_deleted, like_count DESC, created_at DESC, id)

예상 코드 리뷰 노력

🎯 3 (보통) | ⏱️ ~20분

  • SecurityConfig.java의 Prometheus 접근 제어 로직: 확대된 허용 주소 검증 로직이 보안 정책과 일치하는지 확인 필요
  • schema.sql의 인덱스 설계: 새로운 인덱스가 기존 쿼리 패턴과 부하 테스트 시나리오를 고려한 최적 설계인지 검토 필요
  • docker-compose.yml의 리소스 제한: 부하 테스트 목표를 고려한 CPU/메모리 값의 적절성 검증

관련 PR

추천 검토자

  • kimyumin03
  • yuhandemian

Pre-merge checks and finishing touches

✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed PR 제목은 부하테스트 진행이라는 명확한 주요 변경 사항을 반영하고 있으며, 링크된 이슈 #86과 일치합니다.
Description check ✅ Passed PR 설명은 템플릿의 주요 섹션(Issues, Check-list, Work Description, Screenshot, Reference)을 모두 포함하고 있으며, 부하테스트 진행 내용과 결과 이미지를 상세히 제공합니다.
Linked Issues check ✅ Passed PR 변경 사항은 batch 부하테스트와 동시 접속자 부하테스트 진행이라는 이슈 #86의 요구사항을 충족합니다. 스키마 인덱싱 추가, 리소스 제한 설정, 환경변수 추가를 통해 부하테스트를 지원합니다.
Out of Scope Changes check ✅ Passed 모든 변경 사항(schema 인덱싱, docker-compose 리소스 설정, 보안 설정, NAVER 환경변수)은 부하테스트 진행 및 시스템 최적화와 관련이 있으며 이슈 #86의 범위 내에 있습니다.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feature/#86

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3d285fd and cafce24.

📒 Files selected for processing (2)
  • monew/src/main/java/com/spring/monew/auth/config/SecurityConfig.java (3 hunks)
  • monew/src/main/resources/schema.sql (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • monew/src/main/resources/schema.sql
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-28T02:10:38.305Z
Learnt from: yuhandemian
Repo: codeit-monew/sb05-monew-team7 PR: 37
File: monew/src/main/java/com/spring/monew/comment/controller/CommentController.java:57-65
Timestamp: 2025-10-28T02:10:38.305Z
Learning: The monew project currently does not implement Spring Security authentication - SecurityConfig exists but uses .anyRequest().permitAll(). All controllers use RequestHeader(name = "Monew-Request-User-ID") UUID userId to receive user identification, not AuthenticationPrincipal.

Applied to files:

  • monew/src/main/java/com/spring/monew/auth/config/SecurityConfig.java
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: build-and-test
🔇 Additional comments (1)
monew/src/main/java/com/spring/monew/auth/config/SecurityConfig.java (1)

27-28: 설정 기본값 추가가 적절합니다

Prometheus 허용 IP에 대한 기본값(127.0.0.1)을 설정한 것은 좋은 관행입니다.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
monew/docker-compose.yml (2)

37-41: 리소스 예약(reservations) 추가 권장

부하테스트 시 안정적인 리소스 할당을 위해 Redis와 Mongo에도 reservations 설정을 추가하는 것이 좋습니다.

다음과 같이 수정하는 것을 권장합니다:

     deploy:
       resources:
         limits:
           cpus: "1.0"
           memory: 512m
+        reservations:
+          cpus: "0.5"
+          memory: 256m

52-56: 리소스 예약(reservations) 추가 권장

Redis와 마찬가지로 Mongo에도 안정적인 리소스 할당을 위해 reservations를 추가하는 것이 좋습니다.

다음과 같이 수정하는 것을 권장합니다:

     deploy:
       resources:
         limits:
           cpus: "2.0"
           memory: 1g
+        reservations:
+          cpus: "1.0"
+          memory: 512m
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1d3a97f and 3d285fd.

📒 Files selected for processing (3)
  • monew/docker-compose.yml (4 hunks)
  • monew/src/main/java/com/spring/monew/auth/config/SecurityConfig.java (2 hunks)
  • monew/src/main/resources/schema.sql (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2025-10-28T02:10:38.305Z
Learnt from: yuhandemian
Repo: codeit-monew/sb05-monew-team7 PR: 37
File: monew/src/main/java/com/spring/monew/comment/controller/CommentController.java:57-65
Timestamp: 2025-10-28T02:10:38.305Z
Learning: The monew project currently does not implement Spring Security authentication - SecurityConfig exists but uses .anyRequest().permitAll(). All controllers use RequestHeader(name = "Monew-Request-User-ID") UUID userId to receive user identification, not AuthenticationPrincipal.

Applied to files:

  • monew/src/main/java/com/spring/monew/auth/config/SecurityConfig.java
🔇 Additional comments (4)
monew/src/main/resources/schema.sql (2)

98-98: 변경사항 승인: URL 컬럼 크기 확장

긴 URL을 수용하기 위한 합리적인 변경입니다. UNIQUE 제약조건이 유지되므로 데이터 무결성에 영향이 없습니다.


287-294: 댓글 조회 쿼리와 완벽하게 정렬된 인덱스 설계 확인됨

코드 검증 결과, 두 인덱스 모두 실제 QueryDSL 쿼리 패턴과 완벽하게 일치합니다.

  • idx_comment_article_created: 생성일시 정렬 쿼리(orderBy=createdAt)에서 (article_id, is_deleted, created_at DESC, id) 순서로 필터링과 정렬을 모두 커버
  • idx_comment_article_like: 좋아요 수 정렬 쿼리(orderBy=likeCount)에서 (article_id, is_deleted, like_count DESC, created_at DESC, id) 순서로 커서 페이지네이션과 안정적인 정렬을 지원

인덱스는 커서 기반 페이지네이션 로직과 정렬 요구사항을 완벽히 만족하며, id 포함으로 커버링 인덱스의 이점까지 제공합니다.

monew/docker-compose.yml (1)

21-28: 적절한 리소스 제한 설정

Postgres에 대한 리소스 제한이 PR 설명의 테스트 시나리오(CPU 4, Memory 2GB)와 일치합니다. limits와 reservations를 모두 설정한 것도 좋은 방식입니다.

monew/src/main/java/com/spring/monew/auth/config/SecurityConfig.java (1)

25-26: 기본값 추가 승인

prometheusAllowIp에 안전한 기본값(127.0.0.1)을 설정한 것은 좋은 변경입니다.

Comment on lines +79 to +80
NAVER_CLIENT_ID: ${NAVER_CLIENT_ID}
NAVER_CLIENT_SECRET: ${NAVER_CLIENT_SECRET}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

환경 변수 설정 확인 필요

네이버 API 자격증명을 환경 변수로 주입하는 방식은 적절합니다. 하지만 docker-compose up 실행 전에 해당 환경 변수가 설정되어 있는지 확인이 필요합니다.

다음을 확인해주세요:

  1. .env 파일 또는 셸 환경에 NAVER_CLIENT_IDNAVER_CLIENT_SECRET이 설정되어 있는지 확인
  2. 프로덕션 환경에서는 Docker Secrets 사용을 고려

🏁 Script executed:

#!/bin/bash
# Description: Check if .env file exists and contains NAVER credentials

if [ -f "monew/.env" ]; then
  echo "Found .env file:"
  grep -E "NAVER_CLIENT_(ID|SECRET)" monew/.env || echo "NAVER credentials not found in .env"
else
  echo ".env file not found. Make sure to set environment variables before running docker-compose."
fi

Length of output: 90



---

🏁 Script executed:

```shell
#!/bin/bash
# Check for environment setup documentation and examples

echo "=== Checking for .env.example or similar ===" 
fd -e env -e example monew/ 2>/dev/null | head -20

echo ""
echo "=== Checking for README or setup docs ==="
fd -i -e md monew/ 2>/dev/null | xargs grep -l "NAVER\|환경 변수\|environment" 2>/dev/null || echo "No matches found"

echo ""
echo "=== Checking docker-compose.yml for comments about credentials ==="
head -100 monew/docker-compose.yml

Length of output: 2406



---

🏁 Script executed:

```shell
#!/bin/bash
# Check root directory for setup documentation

echo "=== Root directory README and docs ==="
ls -la | grep -iE "readme|doc|setup|env|contributing" || echo "No matches in root"

echo ""
echo "=== Checking if root README mentions environment variables ==="
if [ -f "README.md" ]; then
  head -50 README.md
else
  echo "No README.md in root"
fi

echo ""
echo "=== Checking for any .env template files ==="
find . -maxdepth 2 -type f \( -name ".env*" -o -name "*.env" \) 2>/dev/null || echo "No .env template files"

Length of output: 455


.env.example 템플릿 파일 추가 필요

네이버 API 자격증명(NAVER_CLIENT_ID, NAVER_CLIENT_SECRET)이 환경 변수로 주입되도록 설정되어 있으나, 프로젝트에 .env.example 템플릿이 없어 개발자가 어떤 환경 변수를 설정해야 하는지 알 수 없습니다. monew/ 디렉토리에 .env.example 파일을 생성하여 필수 환경 변수를 명시해주세요.

예시:

NAVER_CLIENT_ID=your_naver_client_id
NAVER_CLIENT_SECRET=your_naver_client_secret

개발자는 docker-compose up 실행 전에 이 파일을 복사하여 .env 파일을 만들고 실제 값을 입력해야 합니다.

🤖 Prompt for AI Agents
In monew/docker-compose.yml around lines 79-80 the compose file expects
NAVER_CLIENT_ID and NAVER_CLIENT_SECRET from an environment file but the
repository lacks a .env.example template; create monew/.env.example listing the
required variables (NAVER_CLIENT_ID and NAVER_CLIENT_SECRET) with placeholder
values and a short comment instructing developers to copy it to .env and
populate real credentials before running docker-compose up.

package com.spring.monew.auth.config;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

사용되지 않는 로깅 어노테이션 제거 필요

@Slf4j 어노테이션이 추가되었지만 코드 내에서 log를 사용하는 곳이 없습니다.

다음과 같이 제거하는 것을 권장합니다:

 package com.spring.monew.auth.config;
 
 import lombok.RequiredArgsConstructor;
-import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Value;
-@Slf4j
 @RequiredArgsConstructor
 @Configuration
 @EnableWebSecurity

Also applies to: 17-17

🤖 Prompt for AI Agents
In monew/src/main/java/com/spring/monew/auth/config/SecurityConfig.java around
lines 4 and 17, the Lombok @Slf4j import and annotation are unused; remove the
"import lombok.extern.slf4j.Slf4j;" line and delete the "@Slf4j" annotation on
the class declaration, and then run a build / static-analysis to ensure no
remaining references to log exist and no new unused-import warnings are
introduced.

Comment on lines +36 to +44
boolean allowed =
remoteAddr.equals("127.0.0.1") ||
remoteAddr.equals("0:0:0:0:0:0:0:1") || // IPv6 localhost
remoteAddr.equals("localhost") ||
remoteAddr.startsWith("172.") || // Docker 내부 네트워크
remoteAddr.startsWith("192.168.") ||
remoteAddr.equals(prometheusAllowIp);

return new AuthorizationDecision(allowed);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

프로덕션 환경에서 과도하게 허용적인 Prometheus 접근 제어

Prometheus 메트릭 엔드포인트 접근을 IP 기반으로만 제어하고 있으며, Docker 네트워크 전체(172.*)와 사설 네트워크 전체(192.168.*)를 허용하고 있습니다. 개발 및 테스트 환경에서는 적절하지만, 프로덕션 환경에서는 보안 위험이 있습니다.

다음 개선사항을 고려해주세요:

  1. 환경별 설정 분리: 프로덕션과 개발 환경에서 다른 접근 제어 정책 적용
  2. 더 제한적인 IP 범위: 프로덕션에서는 특정 모니터링 서버 IP만 허용
  3. 추가 인증 계층: IP 기반 필터링 외에 Basic Auth 또는 토큰 기반 인증 추가
// 환경별 설정 예시
@Value("${spring.profiles.active:local}")
private String activeProfile;

// 접근 제어 로직에서
boolean allowed;
if ("prod".equals(activeProfile)) {
  // 프로덕션: 특정 IP만 허용
  allowed = remoteAddr.equals(prometheusAllowIp);
} else {
  // 개발/테스트: 넓은 범위 허용
  allowed = remoteAddr.equals("127.0.0.1") ||
            remoteAddr.equals("0:0:0:0:0:0:0:1") ||
            remoteAddr.startsWith("172.") ||
            remoteAddr.startsWith("192.168.") ||
            remoteAddr.equals(prometheusAllowIp);
}
🤖 Prompt for AI Agents
In monew/src/main/java/com/spring/monew/auth/config/SecurityConfig.java around
lines 36 to 44, the current logic allows broad IP ranges (172.*, 192.168.* and
localhost variants) which is too permissive for production; change to
environment-aware authorization by injecting the active profile (e.g.
@Value("${spring.profiles.active:local}") private String activeProfile) and
branch the decision: if profile equals "prod" only allow the specific monitoring
IP(s) (prometheusAllowIp or a configured list) and reject all others; if
non-prod keep the current relaxed checks; additionally, add an extra auth layer
for the metrics endpoint in prod (Basic Auth or token-based check) and ensure
prometheusAllowIp is validated/parsed as a single IP or CIDR list rather than
matching prefixes.

@Namsoo315 Namsoo315 merged commit c4e92aa into develop Nov 4, 2025
1 of 2 checks passed
@coderabbitai coderabbitai bot mentioned this pull request Nov 5, 2025
6 tasks
Namsoo315 added a commit that referenced this pull request Nov 11, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat] 부하테스트 진행

2 participants