Open
Conversation
[deploy] 피드 / 정산 / 결제 수정사항 반영
…into feat/feed/hyun
…into test/search/chan
…into test/search/chan
[deploy] 자동 정산 기능 / 테스트 코드 추가
- 모든 테스트에 UT-NT-XXX 형식의 @DisplayName 추가하여 네이밍 표준화 완료 - NotificationServiceTest의 캐싱 이슈로 인한 반복 실행 실패 문제 해결 - UT-NT-059, 060, 064: 서비스 캐싱 대신 DB 직접 조회로 검증 방식 변경 - @DirtiesContext 및 flush() 추가로 테스트 격리성 개선 - 사용하지 않는 성능 테스트 파일 정리 (LimitTest, QuickPerformanceTest, SimpleLoadTest) - 테스트 환경 설정 일관성 개선 (@import(TestConfig.class) 추가)
…into feat/feed/hyun
[refactor] 테스트 코드 작성 및 코드 리팩토링
[feat] querydsl 추가
test: 채팅 api 테스트 코드 추가
[test] 채팅 테스트 코드 추가 / 채팅 기능 리팩토링
- develop 브랜치의 최신 변경사항 병합 - 알림 관련 기능은 기존 구현 유지 - ErrorCode에 누락된 알림 관련 에러 코드 추가 - DATABASE_OPERATION_FAILED - NOTIFICATION_PROCESSING_FAILED - SSE_CLEANUP_FAILED - INVALID_EVENT_ID - INVALID_NOTIFICATION_DATA - DTO getter 메소드 이름 수정 - getNotificationId() -> getId() - getFcmSent() -> isFcmSent() - Club, Feed, Search 등은 develop 브랜치 버전 사용
- TestQueryDslConfig 제거 (develop 브랜치에 없는 파일) - QuerydslConfig는 develop 브랜치 버전 유지
- monitoring 폴더 및 관련 설정 파일 삭제 - scripts 폴더 및 SQL 스크립트 파일 삭제 - docker-compose.monitoring.yml 파일 삭제 - insert_10million_full_batch.sql 파일 삭제 - build 폴더의 QueryDSL Q엔티티 클래스 삭제
[test] 알림 테스트 코드 추가 / 알림 기능 리팩토링
1. 복합 인덱스: idx_feed_club_feedid, idx_feed_club_popularity 추가 2. 캐시 레이어: pass1/result 키 분리, 첫 페이지 집중 캐싱 3. 인기 피드 분리: popularity_score 컬럼 + 5분 주기 스케줄러로 사전계산 4. 커서 페이징: OFFSET 제거, feed_id < cursor 인덱스 스캔으로 일정 성능
- FeedRepositoryCustomImpl: UNION ALL 네이티브 쿼리 추가 - 클럽별 개별 쿼리가 (club_id, feed_id) 인덱스를 완벽 활용 - IN절 20+개 merge sort 병목 제거 - MysqlFeedStorageAdapter: 모든 개인/인기 피드 조회를 UNION ALL로 전환 - k6 feed-personal-focus-test.js: 개인/인기 피드 집중 테스트 (5분, 800VU) - ec2-loadtest.sh: feed-focus 도메인 옵션 추가
- SQL 동적 생성 대신 고정 prepared statement 반복 실행 - MySQL prepared statement 캐싱 활용 가능 - 인기 피드 UNION ALL은 성능 개선 확인되어 유지 (2.11s → 534ms)
- findAccessibleClubIds가 네이티브 쿼리라 Integer 반환 (type erasure) - for (Number clubIdRaw : clubIds)로 안전한 변환 처리
12개 모듈(api + common + 10 domain)을 onlyone-api 단일 모듈로 병합.
- 단일 bootJar/단일 포트 8080 배포에서 멀티 모듈의 실질적 이점 없음
- 순환 의존성(compileOnly 우회), build.gradle 12개 중복 관리 비용 제거
- 패키지 구조(domain/{chat,club,feed,...})로 도메인 경계 유지
- 309 main + 70 test Java 파일, 컴파일 검증 완료
- 와일드카드 import(java.util.*) → 명시적 import로 변환 - 인라인 FQN(java.util.HashMap, java.time.Instant) → import 선언으로 이동 - import 순서: domain 패키지 알파벳순 정렬 (exception → entity → service 순) - 변수명 통일: f → factory (KafkaConsumerConfig) - 불필요한 import 제거: @NotNull (WalletRepository) - 공백/들여쓰기 정리: 연속 빈 줄, trailing whitespace - JpaRepository 제네릭 공백: <Settlement,Long> → <Settlement, Long> - 네이티브 쿼리 포맷: 소문자 → 대문자 SQL 키워드 통일
- DbConfig: requiresNewTransactionTemplate 별도 @bean 추출 - SettlementEventProcessor: PlatformTransactionManager 직접 주입 → @qualifier로 빈 주입 - FeedCacheService: app.feed.cache.enabled 설정으로 캐시 on/off 제어 (기본 false) → 성능 테스트 시 순수 RDB 성능 측정 가능 → 프로덕션에서는 app.feed.cache.enabled: true로 활성화
- 불필요 k6 테스트 16개 삭제 (~5000 lines) - 피드 테스트 404-as-success 제거, null guard 추가, 동적 클럽 ID - 시드 SQL settlement version 컬럼 추가 (Hibernate @Version) - application.yml 로그 레벨 조정 (진행/에러 추적용) - application-prod.yml 누락 설정 추가 - ec2-seed-data.sh MongoDB 참조 제거 - ec2-collect-results.sh SSH 키 경로 수정
- ec2-setup-k6.sh: mongosh 설치 제거 - ec2-setup-app.sh: MongoDB 연결 체크 제거 - ec2-loadtest.sh: MongoDB 체크, all/feed-focus 케이스 제거 - REPO_URL choigpt/OnlyOne-Back으로 변경
1. Subquery → LEFT JOIN: 알림 목록/카운트 쿼리 3개 상관 서브쿼리 제거 2. DELETE 2-step → SELECT+DELETE: row lock 경합 감소 3. SSE 타임아웃 30s → 300s: 재연결 빈도 10배 감소 4. Recovery 스킵 가드: SSE 미연결 유저 복구 시 불필요한 DB 조회 차단
http.get+timeout 방식은 SSE duration = timeout 값으로 잡히는 문제 해결. sse.open() 이벤트 핸들러로 connected 시점(TTFB) 정확히 측정.
xk6-sse의 client.on('open') 콜백이 호출되지 않는 환경에서
첫 이벤트 수신 및 response.status 200으로 connected 판정 fallback 추가.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
sse.open()에 timeout 파라미터 전달하고 error 콜백에서 client.close()를 호출하여 타임아웃 후 함수 반환을 보장. 이전에는 maxEvents 미도달 시 서버 SSE timeout(300s)까지 sse.open()이 블록되어 P6 SSE Flood 0% 발생.
- 알림 목록/unread 쿼리 3개에서 user_notification_state LEFT JOIN 제거 → 워터마크를 사전 조회 후 파라미터로 전달, notification 단독 쿼리 - markAllAsRead: SELECT MAX + INSERT 2단계 → INSERT...SELECT 단일문 → shared lock 유지 시간 제거 - 효과: write(markAll) ↔ read(list/unread) 간 InnoDB lock 경합 원천 차단
- sendMessage: existsBy + findById 2쿼리 → findUserInfoIfMember 단일 쿼리 - ChatRoomQueryService: existsById 제거 (existsBy로 충분) - MessageQueryService: findByIdWithClub 3테이블 JOIN FETCH → findChatRoomName 경량 쿼리 - HikariCP: 300 → 400, minimum-idle: 50 → 80
- 댓글 생성/삭제 시 comment_count UPDATE를 @TransactionalEventListener + @async로 분리 (feed row X-lock 제거 → 댓글 생성 p95 5.75s → 260ms) - commentCountExecutor: 전용 스레드풀 max=10 (커넥션 소비 제한) - findByIdsWithRelations: feedImages JOIN FETCH 제거 (@batchsize(100) 활용) - 개인피드 정렬 createdAt → feedId (covering index 활용) - 인기피드 7일 필터 → popularityScore > 0 (인덱스 스캔) - covering index 선언: idx_feed_club_del_feedid_covering - k6: 리피드/댓글 409 Conflict 정상 처리
991241a to
a86023c
Compare
- WalletTransaction: derived query → JPQL JOIN FETCH Payment (N+1 제거) - idx_wallet_tx_wallet_status_created (wallet_id, status, created_at DESC) - idx_wallet_tx_wallet_type_status (wallet_id, type, status) - idx_user_settlement_settlement_created (settlement_id, created_at DESC) - idx_settlement_schedule_id (schedule_id)
- 호출부 없는 dead code — 모든 경로가 findByUserWithoutLock() 사용 - 불필요한 row lock 가능성 제거
- applyPaymentResult: wallet 엔티티 로딩 → 프로젝션(walletId+balance) 전환 - WalletRepository: WalletIdAndBalance 프로젝션 인터페이스 추가 - DataSourceRoutingConfig: readOnly TX는 read-pool로 라우팅 (이미 구현, 커밋 누락분) - HikariCP: write 350 + read 350 = 700 (MySQL max_connections 800)
- Club/Schedule/Settlement/Wallet/Feed/Search/User/Chat 조회 캐싱 - 변경 빈도에 맞춘 TTL: 30s(지갑) ~ 5min(클럽/검색/일정상세) - CacheEvict: 댓글 생성/삭제, 프로필 수정 시 무효화
- ~/.env-onlyone 자동 source - build 인자로 pull+빌드 모드 지원 - health check 자동 대기 (60초)
- NotificationQueryService: list(30s), unreadCount(60s) @Cacheable - NotificationCommandService: mark/delete/create 시 @CacheEvict
- 전 k6 테스트에 vu(), dur(), startAfter() 적용 (VU_SCALE/DUR_SCALE) - helpers.js USER_COUNT 기본값을 TOTAL_USERS와 동기화 - 500x MySQL 시드: 466M rows (500K users, 50M feeds, 100M comments 등) - 500x MongoDB 시드: 150M docs (100M notifications, 50M messages) - 알림 @Cacheable 제거 + NotificationUndeliveredCache Redis LIST 캐싱 - 워터마크 mark-all (MongoDB O(1) upsert) - CommentCountEventListener 비동기 갱신, AsyncConfig 개선 - SSE MissedNotificationRecovery 개선
- seed-settlement-boost.sql: settlement 69K→500K, user_settlement 5M (100K 유저 분산) - seed-mongo-100x.sh: OOM 방지 chunk 방식 MongoDB 시드 (알림 20M + 메시지 12.5M) - finance-loadtest.js: clubForSchedule에 TOTAL_CLUBS modulo 적용
8372061 to
5340984
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
#️⃣ Issue Number
📝 요약(Summary)
팀원 전체 pull 받고 merge, conflict resolved and then push
🛠️ PR 유형
어떤 변경 사항이 있나요?
📸스크린샷 (선택)
💬 공유사항 to 리뷰어
✅ PR Checklist
PR이 다음 요구 사항을 충족하는지 확인하세요.
Summary by CodeRabbit
New Features
Changes
Bug Fixes
Chores
✏️ Tip: You can customize this high-level summary in your review settings.