From e13576ade3210796a6c5fec9af8719981da5e362 Mon Sep 17 00:00:00 2001 From: LeeJeongHeon02 Date: Sun, 1 Mar 2026 01:33:10 +0900 Subject: [PATCH 1/5] =?UTF-8?q?Feat:=20Docker=20=EB=8F=84=EC=9E=85=20?= =?UTF-8?q?=EB=B0=8F=20deploy=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 76 +++++++++++++++++------------- Dockerfile | 14 ++++++ build.gradle | 4 ++ docker-compose.yml | 15 ++++++ prometheus.yml | 10 ++++ src/main/resources/application.yml | 45 +++++++----------- 6 files changed, 105 insertions(+), 59 deletions(-) create mode 100644 Dockerfile create mode 100644 docker-compose.yml create mode 100644 prometheus.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 379abe4..7c7147e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -2,7 +2,7 @@ name: CI/CD Pipeline on: push: - branches: [ develop, feat/23-fix-deploy ] + branches: [ develop, feat/98-load-test ] jobs: build: @@ -46,12 +46,26 @@ jobs: runs-on: ubuntu-latest steps: + - uses: actions/checkout@v3 + - name: Download build artifact uses: actions/download-artifact@v4 with: name: digitalTok path: build/libs/ + # 3. Docker Hub 로그인 (새로 추가한 Secret 사용) + - name: Log in to Docker Hub + uses: docker/login-action@v2 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + # 4. 도커 이미지 빌드 및 푸시 + - name: Build and Push Docker Image + run: | + docker build -t ${{ secrets.DOCKER_USERNAME }}/digitaltok-server:latest . + docker push ${{ secrets.DOCKER_USERNAME }}/digitaltok-server:latest # env 추가 및 run.sh 생성 - name: Deploy to EC2 env: @@ -61,42 +75,40 @@ jobs: run: | echo "$EC2_SSH_KEY" > private_key.pem chmod 600 private_key.pem - jar_file=$(find build/libs -name '*.jar' ! -name '*plain.jar' | head -n 1) - - # 파일 전송 - scp -i private_key.pem -o StrictHostKeyChecking=no "$jar_file" $EC2_USERNAME@$EC2_HOST:/home/$EC2_USERNAME/digitalTok.jar - # 실행 스크립트 생성 (run.sh) - cat < run.sh + # EC2에서 실행할 스크립트 (run.sh) 작성 + cat < run.sh #!/bin/bash - # 1. 기존 자바 프로세스 강제 종료 - pgrep java | xargs -r kill -9 - sleep 5 + # 1. 최신 이미지 다운로드 + docker pull ${{ secrets.DOCKER_USERNAME }}/digitaltok-server:latest - # DB 및 AWS 환경변수 설정 - export DB_URL='${{ secrets.DB_URL }}' - export DB_USERNAME='${{ secrets.DB_USERNAME }}' - export DB_PASSWORD='${{ secrets.DB_PASSWORD }}' - export AWS_ACCESS_KEY='${{ secrets.AWS_ACCESS_KEY }}' - export AWS_SECRET_KEY='${{ secrets.AWS_SECRET_KEY }}' - export SPRING_CLOUD_AWS_REGION_STATIC=ap-northeast-2 + # 2. 기존 실행 중인 컨테이너가 있다면 중지 및 삭제 + docker stop digitaltok-server || true + docker rm digitaltok-server || true - # 이메일 환경변수 설정 - export MAIL_USERNAME='${{ secrets.MAIL_USERNAME }}' - export MAIL_PASSWORD='${{ secrets.MAIL_PASSWORD }}' + # 3. 새 컨테이너 백그라운드 실행 (-e 로 기존 Secret 주입) + # --network host 옵션: EC2 서버의 네트워크를 그대로 사용하여 로컬 DB(3306)와 통신하기 쉽게 만듭니다. + docker run -d --name digitaltok-server \ + --network host \ + -e DB_URL='${{ secrets.DB_URL }}' \ + -e DB_USERNAME='${{ secrets.DB_USERNAME }}' \ + -e DB_PASSWORD='${{ secrets.DB_PASSWORD }}' \ + -e AWS_ACCESS_KEY='${{ secrets.AWS_ACCESS_KEY }}' \ + -e AWS_SECRET_KEY='${{ secrets.AWS_SECRET_KEY }}' \ + -e SPRING_CLOUD_AWS_REGION_STATIC='ap-northeast-2' \ + -e MAIL_USERNAME='${{ secrets.MAIL_USERNAME }}' \ + -e MAIL_PASSWORD='${{ secrets.MAIL_PASSWORD }}' \ + -e JWT_SECRET_KEY='${{ secrets.JWT_SECRET_KEY }}' \ + -e TZ='Asia/Seoul' \ + ${{ secrets.DOCKER_USERNAME }}/digitaltok-server:latest - # 서버 실행 명령어 - # -Djwt.secret 옵션으로 스프링이 찾는 이름에 맞춰서 값을 직접 넣어줌 - nohup java -Duser.timezone=Asia/Seoul \ - -Djwt.secret='${{ secrets.JWT_SECRET_KEY }}' \ - -Djwt.access-token-validity-in-seconds=1800 \ - -Djwt.refresh-token-validity-in-seconds=604800 \ - -jar /home/$EC2_USERNAME/digitalTok.jar > app.log 2>&1 & - EOF + # 4. 쌓여있는 안 쓰는 옛날 도커 이미지 삭제 (EC2 용량 확보) + docker image prune -a -f + EOF # 스크립트 전송 및 실행 - scp -i private_key.pem -o StrictHostKeyChecking=no run.sh $EC2_USERNAME@$EC2_HOST:/home/$EC2_USERNAME/run.sh - ssh -i private_key.pem -o StrictHostKeyChecking=no $EC2_USERNAME@$EC2_HOST "chmod +x /home/$EC2_USERNAME/run.sh && sh /home/$EC2_USERNAME/run.sh" - - rm -f private_key.pem run.sh \ No newline at end of file + scp -i private_key.pem -o StrictHostKeyChecking=no run.sh $EC2_USERNAME@$EC2_HOST:/home/$EC2_USERNAME/run.sh + ssh -i private_key.pem -o StrictHostKeyChecking=no $EC2_USERNAME@$EC2_HOST "chmod +x /home/$EC2_USERNAME/run.sh && sh /home/$EC2_USERNAME/run.sh" + + rm -f private_key.pem run.sh \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..f92363d --- /dev/null +++ b/Dockerfile @@ -0,0 +1,14 @@ +# 1. Java 17 환경을 베이스로 사용 (가볍고 많이 쓰는 alpine 버전) +FROM eclipse-temurin:17-jdk-alpine + +# 2. 작업할 디렉토리 설정 +WORKDIR /app + +# 3. 로컬에서 빌드된 jar 파일을 도커 컨테이너 안의 /app.jar로 복사 +COPY build/libs/digitalTok.jar app.jar + +# 4. 서버가 사용할 8080 포트 개방 +EXPOSE 8080 + +# 5. 도커 컨테이너가 켜질 때 실행할 명령어 (java -jar app.jar) +ENTRYPOINT ["java", "-jar", "app.jar"] \ No newline at end of file diff --git a/build.gradle b/build.gradle index 578b482..00d405c 100644 --- a/build.gradle +++ b/build.gradle @@ -62,6 +62,10 @@ dependencies { // 이메일 발송 라이브러리 implementation 'org.springframework.boot:spring-boot-starter-mail' + + // 부하 테스트 및 모니터링 + implementation 'org.springframework.boot:spring-boot-starter-actuator' + implementation 'io.micrometer:micrometer-registry-prometheus' } tasks.named('test') { diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..29769a6 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,15 @@ +version: '3.8' + +services: + mysql: + image: mysql:8.0 + container_name: digitaltok-mysql + ports: + - "3307:3306" + environment: + MYSQL_ROOT_PASSWORD: rootpassword + MYSQL_DATABASE: digitaltok + MYSQL_USER: localuser + MYSQL_PASSWORD: localpassword + volumes: + - ./local-mysql-data:/var/lib/mysql # 컨테이너를 지워도 데이터가 날아가지 않도록 내 컴퓨터 폴더와 연결 (영속성) \ No newline at end of file diff --git a/prometheus.yml b/prometheus.yml new file mode 100644 index 0000000..928c5ca --- /dev/null +++ b/prometheus.yml @@ -0,0 +1,10 @@ +# prometheus.yml +global: + scrape_interval: 15s + +scrape_configs: + - job_name: 'digitaltok-spring-boot' + metrics_path: '/actuator/prometheus' + static_configs: + # host.docker.internal은 Docker 컨테이너 안에서 내 컴퓨터(호스트)의 localhost를 가리키는 주소 + - targets: ['host.docker.internal:8080'] \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 56b671c..0d051e0 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,12 +1,13 @@ spring: datasource: - url: ${DB_URL} - username: ${DB_USERNAME} - password: ${DB_PASSWORD} + url: jdbc:mysql://localhost:3307/digitaltok?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&characterEncoding=UTF-8 + username: localuser # docker-compose.yml에서 설정한 유저 + password: localpassword # docker-compose.yml에서 설정한 비밀번호 driver-class-name: com.mysql.cj.jdbc.Driver + jpa: hibernate: - ddl-auto: update # create는 매번 데이터를 날리므로 update 추천 + ddl-auto: update properties: hibernate: format_sql: true @@ -14,7 +15,6 @@ spring: storage: type: s3 - # 최신 버전에서 cloud는 spring 밑에 있어야함 cloud: aws: s3: @@ -26,29 +26,13 @@ spring: credentials: access-key: ${AWS_ACCESS_KEY} secret-key: ${AWS_SECRET_KEY} - #profiles: - # active: prod - # ... ?? ?? ... - # security: - # oauth2: - # client: - # registration: - # kakao: - # client-authentication-method: client_secret_post - # client-id: { ?? client-id } - # client-secret: { ?? client-secret } - # redirect-uri: http://{ ?? ec2 public ip ?? }:8080/login/oauth2/code/kakao - # authorization-grant-type: authorization_code - # scope: profile_nickname - # client-name: Kakao - # ... ?? ?? ... - #이메일 서버 설정 (Gmail 예시) + # mail은 spring 하위로 mail: host: smtp.gmail.com port: 587 - username: ${MAIL_USERNAME} # 발송할 이메일 주소 - password: ${MAIL_PASSWORD} # 구글 앱 비밀번호 + username: ${MAIL_USERNAME} + password: ${MAIL_PASSWORD} properties: mail: smtp: @@ -60,9 +44,16 @@ spring: timeout: 5000 writetimeout: 5000 - # JWT 설정 jwt: - # 시스템 환경 변수 중 JWT_SECRET_KEY 값을 가져오고, 없으면 기본값(뒷부분)을 씁니다. secret: ${JWT_SECRET_KEY} access-token-validity-in-seconds: 3600 - refresh-token-validity-in-seconds: 1209600 \ No newline at end of file + refresh-token-validity-in-seconds: 1209600 + +management: + endpoints: + web: + exposure: + include: prometheus, health, info, metrics + metrics: + tags: + application: digitaltok-server \ No newline at end of file From f0795b0b9003aff6f73b071e1cf802060b70cae9 Mon Sep 17 00:00:00 2001 From: LeeJeongHeon02 Date: Sun, 1 Mar 2026 02:23:17 +0900 Subject: [PATCH 2/5] =?UTF-8?q?fix:=20deploy=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 7c7147e..ac1072e 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -54,7 +54,7 @@ jobs: name: digitalTok path: build/libs/ - # 3. Docker Hub 로그인 (새로 추가한 Secret 사용) + # 3. Docker Hub 로그인 - name: Log in to Docker Hub uses: docker/login-action@v2 with: From a7cc1c997d52a43f37b6216e910a35d2488b927b Mon Sep 17 00:00:00 2001 From: LeeJeongHeon02 Date: Sun, 1 Mar 2026 02:33:17 +0900 Subject: [PATCH 3/5] =?UTF-8?q?fix:=20deploy=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .github/workflows/deploy.yml | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ac1072e..46a0ef6 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -77,38 +77,38 @@ jobs: chmod 600 private_key.pem # EC2에서 실행할 스크립트 (run.sh) 작성 - cat < run.sh + cat < run.sh #!/bin/bash # 1. 최신 이미지 다운로드 - docker pull ${{ secrets.DOCKER_USERNAME }}/digitaltok-server:latest + docker pull ${{ secrets.DOCKER_USERNAME }}/digitaltok-server:latest # 2. 기존 실행 중인 컨테이너가 있다면 중지 및 삭제 - docker stop digitaltok-server || true - docker rm digitaltok-server || true + docker stop digitaltok-server || true + docker rm digitaltok-server || true # 3. 새 컨테이너 백그라운드 실행 (-e 로 기존 Secret 주입) # --network host 옵션: EC2 서버의 네트워크를 그대로 사용하여 로컬 DB(3306)와 통신하기 쉽게 만듭니다. - docker run -d --name digitaltok-server \ - --network host \ - -e DB_URL='${{ secrets.DB_URL }}' \ - -e DB_USERNAME='${{ secrets.DB_USERNAME }}' \ - -e DB_PASSWORD='${{ secrets.DB_PASSWORD }}' \ - -e AWS_ACCESS_KEY='${{ secrets.AWS_ACCESS_KEY }}' \ - -e AWS_SECRET_KEY='${{ secrets.AWS_SECRET_KEY }}' \ - -e SPRING_CLOUD_AWS_REGION_STATIC='ap-northeast-2' \ - -e MAIL_USERNAME='${{ secrets.MAIL_USERNAME }}' \ - -e MAIL_PASSWORD='${{ secrets.MAIL_PASSWORD }}' \ - -e JWT_SECRET_KEY='${{ secrets.JWT_SECRET_KEY }}' \ - -e TZ='Asia/Seoul' \ - ${{ secrets.DOCKER_USERNAME }}/digitaltok-server:latest + docker run -d --name digitaltok-server \ + --network host \ + -e DB_URL='${{ secrets.DB_URL }}' \ + -e DB_USERNAME='${{ secrets.DB_USERNAME }}' \ + -e DB_PASSWORD='${{ secrets.DB_PASSWORD }}' \ + -e AWS_ACCESS_KEY='${{ secrets.AWS_ACCESS_KEY }}' \ + -e AWS_SECRET_KEY='${{ secrets.AWS_SECRET_KEY }}' \ + -e SPRING_CLOUD_AWS_REGION_STATIC='ap-northeast-2' \ + -e MAIL_USERNAME='${{ secrets.MAIL_USERNAME }}' \ + -e MAIL_PASSWORD='${{ secrets.MAIL_PASSWORD }}' \ + -e JWT_SECRET_KEY='${{ secrets.JWT_SECRET_KEY }}' \ + -e TZ='Asia/Seoul' \ + ${{ secrets.DOCKER_USERNAME }}/digitaltok-server:latest # 4. 쌓여있는 안 쓰는 옛날 도커 이미지 삭제 (EC2 용량 확보) - docker image prune -a -f - EOF + docker image prune -a -f + EOF # 스크립트 전송 및 실행 - scp -i private_key.pem -o StrictHostKeyChecking=no run.sh $EC2_USERNAME@$EC2_HOST:/home/$EC2_USERNAME/run.sh - ssh -i private_key.pem -o StrictHostKeyChecking=no $EC2_USERNAME@$EC2_HOST "chmod +x /home/$EC2_USERNAME/run.sh && sh /home/$EC2_USERNAME/run.sh" + scp -i private_key.pem -o StrictHostKeyChecking=no run.sh $EC2_USERNAME@$EC2_HOST:/home/$EC2_USERNAME/run.sh + ssh -i private_key.pem -o StrictHostKeyChecking=no $EC2_USERNAME@$EC2_HOST "chmod +x /home/$EC2_USERNAME/run.sh && sh /home/$EC2_USERNAME/run.sh" - rm -f private_key.pem run.sh \ No newline at end of file + rm -f private_key.pem run.sh \ No newline at end of file From 5b5d2f3a5806c77a1eca1b2970526171e5d267e5 Mon Sep 17 00:00:00 2001 From: LeeJeongHeon02 Date: Sun, 1 Mar 2026 17:20:40 +0900 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20load=20test=20=EC=9E=91=EC=84=B1=20?= =?UTF-8?q?=EB=B0=8F=20Health=20Controller=20=EA=B0=9C=EB=B0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 24 +++++- load-test.js | 80 +++++++++++++++++++ prometheus.yml | 8 +- .../com/digital_tok/HealthController.java | 15 ++++ .../global/config/SecurityConfig.java | 3 +- 5 files changed, 123 insertions(+), 7 deletions(-) create mode 100644 load-test.js create mode 100644 src/main/java/com/digital_tok/HealthController.java diff --git a/docker-compose.yml b/docker-compose.yml index 29769a6..7df2b5b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -12,4 +12,26 @@ services: MYSQL_USER: localuser MYSQL_PASSWORD: localpassword volumes: - - ./local-mysql-data:/var/lib/mysql # 컨테이너를 지워도 데이터가 날아가지 않도록 내 컴퓨터 폴더와 연결 (영속성) \ No newline at end of file + - ./local-mysql-data:/var/lib/mysql # 컨테이너를 지워도 데이터가 날아가지 않도록 내 컴퓨터 폴더와 연결 (영속성) + + mysql-exporter: + image: prom/mysqld-exporter + container_name: mysql-exporter + environment: + - DATA_SOURCE_NAME=user:password@(mysql:3306)/ + ports: + - "9104:9104" + + prometheus: + image: prom/prometheus + container_name: prometheus + volumes: + - ./prometheus.yml:/etc/prometheus/prometheus.yml + ports: + - "9090:9090" + + grafana: + image: grafana/grafana + container_name: grafana + ports: + - "3000:3000" \ No newline at end of file diff --git a/load-test.js b/load-test.js new file mode 100644 index 0000000..48b2c24 --- /dev/null +++ b/load-test.js @@ -0,0 +1,80 @@ +// import http from 'k6/http'; +// import { check, sleep } from 'k6'; +// +// export const options = { +// vus: 1000, // 동시에 접속하는 가상 유저 +// duration: '1m', // 1분 동안 계속 요청 +// }; +// +// export default function () { +// // 현재 프로젝트에 구현된 HealthController의 경로를 테스트합니다. +// const res = http.get('http://localhost:8080/health'); +// +// check(res, { +// 'status is 200': (r) => r.status === 200, +// }); +// +// sleep(1); // 1초 쉬고 다시 요청 +// } + +import http from 'k6/http'; +import { check, sleep } from 'k6'; + +export const options = { + vus: 500, + duration: '1m', +}; + +export function setup() { + const loginUrl = 'http://localhost:8080/api/auth/login'; + const payload = JSON.stringify({ + email: 'string', // 1. 반드시 DB에 있는 계정이어야 함 + password: 'string', // 2. 비밀번호가 맞는지 확인 + }); + + const params = { + headers: { 'Content-Type': 'application/json' }, + }; + + const res = http.post(loginUrl, payload, params); + + // [디버깅 코드 추가] 응답이 비어있거나 에러가 났는지 확인 + console.log(`[Setup] Status: ${res.status}`); + console.log(`[Setup] Body: ${res.body}`); + + if (res.status !== 200 || !res.body) { + console.error('로그인 실패! 서버 로그(IntelliJ)를 확인하세요.'); + return { token: null }; + } + + try { + const responseBody = res.json(); + // ApiResponse 구조에 맞게 접근: responseBody.result.accessToken + if (responseBody && responseBody.result && responseBody.result.accessToken) { + return { token: responseBody.result.accessToken }; + } + } catch (e) { + console.error(`JSON 파싱 실패: ${e.message}. 응답 내용: ${res.body}`); + } + + return { token: null }; +} + +export default function (data) { + if (!data || !data.token) { + // 토큰이 없으면 테스트를 수행하지 않음 + return; + } + + const url = 'http://localhost:8080/api/templates/subway'; + const params = { + headers: { + 'Authorization': `Bearer ${data.token}`, + 'Content-Type': 'application/json', + }, + }; + + const res = http.get(url, params); + check(res, { 'status is 200': (r) => r.status === 200 }); + sleep(0.5); +} \ No newline at end of file diff --git a/prometheus.yml b/prometheus.yml index 928c5ca..ef8c150 100644 --- a/prometheus.yml +++ b/prometheus.yml @@ -1,10 +1,8 @@ -# prometheus.yml global: - scrape_interval: 15s + scrape_interval: 5s # 5초마다 데이터 수집 scrape_configs: - - job_name: 'digitaltok-spring-boot' + - job_name: 'digitaltok-server' metrics_path: '/actuator/prometheus' static_configs: - # host.docker.internal은 Docker 컨테이너 안에서 내 컴퓨터(호스트)의 localhost를 가리키는 주소 - - targets: ['host.docker.internal:8080'] \ No newline at end of file + - targets: ['host.docker.internal:8080', 'localhost:8080'] # Spring 서버 주소 (network host 모드 기준) \ No newline at end of file diff --git a/src/main/java/com/digital_tok/HealthController.java b/src/main/java/com/digital_tok/HealthController.java new file mode 100644 index 0000000..186b218 --- /dev/null +++ b/src/main/java/com/digital_tok/HealthController.java @@ -0,0 +1,15 @@ +package com.digital_tok; + +import com.digital_tok.global.apiPayload.ApiResponse; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class HealthController { + + @GetMapping("/health") + public ApiResponse healthCheck() { + // 프로젝트의 공통 응답 형식인 ApiResponse를 사용하여 성공 메시지를 반환합니다. + return ApiResponse.onSuccessResultOnly("잘 작동중입니다~~"); + } +} \ No newline at end of file diff --git a/src/main/java/com/digital_tok/global/config/SecurityConfig.java b/src/main/java/com/digital_tok/global/config/SecurityConfig.java index daab57d..f4a6e32 100644 --- a/src/main/java/com/digital_tok/global/config/SecurityConfig.java +++ b/src/main/java/com/digital_tok/global/config/SecurityConfig.java @@ -49,7 +49,8 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { // URL별 접근 권한 설정 .authorizeHttpRequests(auth -> auth // 인증 없이 접근 가능한 경로 (로그인, 회원가입, 스웨거 등) - .requestMatchers("/api/auth/**", "/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**", "/health").permitAll() + .requestMatchers("/api/auth/**", "/swagger-ui/**", "/v3/api-docs/**", "/swagger-resources/**", + "/health", "/actuator/prometheus").permitAll() // 그 외 모든 요청은 인증(로그인) 필요 .anyRequest().authenticated() From 852e374cd3d76bedf364f8b30f33dae2ef9670c1 Mon Sep 17 00:00:00 2001 From: LeeJeongHeon02 Date: Mon, 2 Mar 2026 21:47:40 +0900 Subject: [PATCH 5/5] =?UTF-8?q?fix:=20yml=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 4 +-- load-test.js | 8 +++--- .../com/digital_tok/HealthController.java | 15 ---------- src/main/resources/application.yml | 28 +++++++++---------- 4 files changed, 19 insertions(+), 36 deletions(-) delete mode 100644 src/main/java/com/digital_tok/HealthController.java diff --git a/docker-compose.yml b/docker-compose.yml index 7df2b5b..0878452 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -7,9 +7,9 @@ services: ports: - "3307:3306" environment: - MYSQL_ROOT_PASSWORD: rootpassword MYSQL_DATABASE: digitaltok MYSQL_USER: localuser + MYSQL_ROOT_PASSWORD: rootpassword MYSQL_PASSWORD: localpassword volumes: - ./local-mysql-data:/var/lib/mysql # 컨테이너를 지워도 데이터가 날아가지 않도록 내 컴퓨터 폴더와 연결 (영속성) @@ -18,7 +18,7 @@ services: image: prom/mysqld-exporter container_name: mysql-exporter environment: - - DATA_SOURCE_NAME=user:password@(mysql:3306)/ + - DATA_SOURCE_NAME=localuser:localpassword@(mysql:3306)/digitaltok ports: - "9104:9104" diff --git a/load-test.js b/load-test.js index 48b2c24..f01dda5 100644 --- a/load-test.js +++ b/load-test.js @@ -21,14 +21,14 @@ import http from 'k6/http'; import { check, sleep } from 'k6'; export const options = { - vus: 500, + vus: 100, duration: '1m', }; export function setup() { - const loginUrl = 'http://localhost:8080/api/auth/login'; + const loginUrl = 'http://localhost:8080/api/v1/auth/login'; const payload = JSON.stringify({ - email: 'string', // 1. 반드시 DB에 있는 계정이어야 함 + email: 'user@example.com', // 1. 반드시 DB에 있는 계정이어야 함 password: 'string', // 2. 비밀번호가 맞는지 확인 }); @@ -66,7 +66,7 @@ export default function (data) { return; } - const url = 'http://localhost:8080/api/templates/subway'; + const url = 'http://localhost:8080/api/v1/templates/subway'; const params = { headers: { 'Authorization': `Bearer ${data.token}`, diff --git a/src/main/java/com/digital_tok/HealthController.java b/src/main/java/com/digital_tok/HealthController.java deleted file mode 100644 index 186b218..0000000 --- a/src/main/java/com/digital_tok/HealthController.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.digital_tok; - -import com.digital_tok.global.apiPayload.ApiResponse; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; - -@RestController -public class HealthController { - - @GetMapping("/health") - public ApiResponse healthCheck() { - // 프로젝트의 공통 응답 형식인 ApiResponse를 사용하여 성공 메시지를 반환합니다. - return ApiResponse.onSuccessResultOnly("잘 작동중입니다~~"); - } -} \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e11f263..06b8df4 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,5 +1,5 @@ server: - forward-headers-strategy: framework # Nginx 헤더 신뢰 설정 + forward-headers-strategy: framework app: server-url: ${SERVER_URL:http://localhost:8080} @@ -11,9 +11,9 @@ spring: max-request-size: 10MB datasource: - url: jdbc:mysql://localhost:3307/digitaltok?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=Asia/Seoul&characterEncoding=UTF-8 - username: localuser # docker-compose.yml에서 설정한 유저 - password: localpassword # docker-compose.yml에서 설정한 비밀번호 + url: ${DB_URL} + username: ${DB_USERNAME} + password: ${DB_PASSWORD} driver-class-name: com.mysql.cj.jdbc.Driver jpa: @@ -35,10 +35,10 @@ spring: stack: auto: false credentials: + # 기본값을 임시로 넣어 에러 방지 access-key: ${AWS_ACCESS_KEY} secret-key: ${AWS_SECRET_KEY} - # mail은 spring 하위로 mail: host: smtp.gmail.com port: 587 @@ -51,20 +51,18 @@ spring: starttls: enable: true required: true - connectiontimeout: 5000 - timeout: 5000 - writetimeout: 5000 jwt: + # JWT 시크릿 키는 최소 32글자 이상의 긴 문자열이어야 합니다. secret: ${JWT_SECRET_KEY} access-token-validity-in-seconds: 3600 refresh-token-validity-in-seconds: 1209600 management: - endpoints: - web: - exposure: - include: prometheus, health, info, metrics - metrics: - tags: - application: digitaltok-server \ No newline at end of file + endpoints: + web: + exposure: + include: prometheus, health, info, metrics + metrics: + tags: + application: digitaltok-server \ No newline at end of file