diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index ebc73673..9589c8c0 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -72,7 +72,7 @@ jobs: envs: >- DB_PASSWORD,GCS_BUCKET,GCS_BACKUP_BUCKET, KAKAO_CLIENT_ID,KAKAO_CLIENT_SECRET,KAKAO_REDIRECT_URI_PROD,KAKAO_REDIRECT_URI_STAGING,KAKAO_ADMIN_KEY, - JWT_SECRET_KEY,FIREBASE_SERVICE_ACCOUNT_KEY + JWT_SECRET_KEY,FIREBASE_SERVICE_ACCOUNT_KEY,FCM_FAKE_LATENCY_MS script: | chmod +x /home/ubuntu/cockple/scripts/deploy.sh bash /home/ubuntu/cockple/scripts/deploy.sh \ @@ -89,3 +89,5 @@ jobs: KAKAO_ADMIN_KEY: ${{ secrets.KAKAO_ADMIN_KEY }} JWT_SECRET_KEY: ${{ secrets.JWT_SECRET_KEY }} FIREBASE_SERVICE_ACCOUNT_KEY: ${{ secrets.FIREBASE_SERVICE_ACCOUNT_KEY }} + # [부하테스트용] FCM 지연(ms) 토글. GitHub Variable로 관리(미설정 시 빈값→deploy.sh에서 0). PR 없이 값 변경+deploy 재실행으로 on/off. + FCM_FAKE_LATENCY_MS: ${{ vars.FCM_FAKE_LATENCY_MS }} diff --git a/docker-compose.yml b/docker-compose.yml index 2a883bb6..18bb6ed4 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -79,6 +79,8 @@ services: environment: JAVA_TOOL_OPTIONS: "-Xms128m -Xmx512m" SPRING_PROFILES_ACTIVE: staging + # [부하테스트용] FCM 인위적 지연(ms). 미설정 시 0=비활성. staging 전용. + FCM_FAKE_LATENCY_MS: ${FCM_FAKE_LATENCY_MS:-0} DB_PASSWORD: ${DB_PASSWORD} GCS_BUCKET: ${GCS_BUCKET} KAKAO_CLIENT_ID: ${KAKAO_CLIENT_ID} diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 6e9a5fa7..8502513b 100644 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -26,6 +26,7 @@ KAKAO_REDIRECT_URI_STAGING=${KAKAO_REDIRECT_URI_STAGING} KAKAO_ADMIN_KEY=${KAKAO_ADMIN_KEY} JWT_SECRET_KEY=${JWT_SECRET_KEY} FIREBASE_SERVICE_ACCOUNT_KEY=${FIREBASE_SERVICE_ACCOUNT_KEY} +FCM_FAKE_LATENCY_MS=${FCM_FAKE_LATENCY_MS:-0} EOF echo "${FIREBASE_SERVICE_ACCOUNT_KEY}" > /home/ubuntu/cockple/firebase-service-account.json diff --git a/src/main/java/umc/cockple/demo/domain/notification/fcm/FcmService.java b/src/main/java/umc/cockple/demo/domain/notification/fcm/FcmService.java index ff1f9e71..30e0ab31 100644 --- a/src/main/java/umc/cockple/demo/domain/notification/fcm/FcmService.java +++ b/src/main/java/umc/cockple/demo/domain/notification/fcm/FcmService.java @@ -8,6 +8,7 @@ import com.google.firebase.messaging.WebpushFcmOptions; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import umc.cockple.demo.domain.chat.enums.ChatRoomType; @@ -24,6 +25,9 @@ public class FcmService { private final MemberRepository memberRepository; private final FirebaseMessaging firebaseMessaging; + @Value("${fcm.fake-latency-ms:0}") + private long fakeLatencyMs; + @Transactional public void registerFcmToken(Long memberId, String fcmToken) { Member member = memberRepository.findById(memberId) @@ -33,6 +37,10 @@ public void registerFcmToken(Long memberId, String fcmToken) { } public void sendNotification(Member member, String title, String content) { + if (applyFakeLatencyAndSkip(member.getId())) { + return; + } + String fcmToken = member.getFcmToken(); if (fcmToken == null || fcmToken.isBlank()) { log.info("FCM 토큰 없음 - memberId: {}, 알림 전송 생략", member.getId()); @@ -58,6 +66,10 @@ public void sendNotification(Member member, String title, String content) { public void sendChatNotification(Member member, String title, String content, Long chatRoomId, ChatRoomType chatRoomType) { + if (applyFakeLatencyAndSkip(member.getId())) { + return; + } + String fcmToken = member.getFcmToken(); if (fcmToken == null || fcmToken.isBlank()) { log.info("FCM 토큰 없음 - memberId: {}, 채팅 알림 전송 생략", member.getId()); @@ -86,6 +98,22 @@ public void sendChatNotification(Member member, String title, String content, } } + /** + * 부하테스트용 FCM 지연 주입. + */ + private boolean applyFakeLatencyAndSkip(Long memberId) { + if (fakeLatencyMs <= 0) { + return false; + } + try { + Thread.sleep(fakeLatencyMs); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + } + log.info("[FCM][FAKE] 지연주입 {}ms 후 실전송 스킵 - memberId: {}", fakeLatencyMs, memberId); + return true; + } + /** * 채팅 알림 클릭 시 이동할 경로(상대경로)를 생성한다. * webpush.fcm_options.link 로 전달되어 FCM이 클릭 시 네이티브로 이동시킨다. diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 258ef906..903b6e69 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -85,6 +85,9 @@ jwt: access-token-validity: 900000 refresh-token-validity: 1209600000 +fcm: + fake-latency-ms: 0 + logging: level: org.hibernate.SQL: WARN