
부트캠프 팀 프로젝트로 Spring Boot 기반 MSA 서비스 TripMate를 AWS에 배포하면서 겪은 트러블슈팅을 기록합니다.
설계 단계에서 예상하지 못했던 문제들이 배포 과정에서 터져나왔고, 하나씩 해결했던 내용을 기록합니다.
Jenkins EC2 (퍼블릭) — CI/CD 서버 + Bastion Host
각 서비스 EC2 (프라이빗) — 서비스별 독립 배포
RDS PostgreSQL — 공유 DB
ElastiCache Redis OSS — 세션/캐시
Kafka EC2 — 이벤트 브로커
Eureka EC2 — 서비스 디스커버리
Jenkins 최신 버전이 Java 21을 요구하는데 프로젝트는 Java 17을 사용합니다.
문제
Jenkins 실행 → Java 21 필요
Gradle 빌드 → Java 17 필요
해결
systemctl edit jenkins로 Jenkins 실행 환경을 Java 21로 고정/var/lib/jenkins/.gradle/gradle.properties에 Java 17 경로 명시org.gradle.java.installations.paths=/usr/lib/jvm/java-17-amazon-corretto.x86_64
교훈 — Jenkins와 빌드 환경의 Java 버전이 다를 수 있다. 두 가지를 별도로 관리해야 한다.
AWS 콘솔에서 ElastiCache 생성 시 Valkey를 권장하기에 선택했습니다. Valkey는 Redis OSS v7.0과 완벽 호환되는 오픈소스로 비용도 최대 33% 저렴하다는 안내가 있었습니다.
문제
Unable to connect to Redis
Connection timed out: tripmate-redis.serverless.apn2.cache.amazonaws.com:6379
원인 — Valkey 서버리스는 전송 중 데이터 암호화(TLS)가 강제 적용되며 이 설정을 변경할 수 없습니다. 따라서 6379 포트가 아닌 6380(TLS) 포트로만 접근 가능합니다.
TLS 설정으로 해결하지 않은 이유
TLS를 적용하려면 각 서비스의 Redis 클라이언트 설정에 SSL 설정을 추가해야 합니다.
@Configuration
public class RedisConfig {
.
. // ssl 관련 설정들
.
}
참고 : https://alstn113.tistory.com/41
서비스가 10개인 상황에서 전부 수정 후 재배포가 필요했고,
수정 범위가 크다고 판단했습니다.
해결 — Valkey 서버리스 대신 Valkey 노드 기반 클러스터 캐시로 전환했습니다. 노드 기반은 생성 시 전송 중 암호화(TLS) 비활성화가 가능하여 기존 6379 포트로 TLS 없이 사용할 수 있습니다.
교훈 — Valkey 자체가 문제가 아니라 서버리스 배포 옵션이 문제였습니다. 서버리스는 TLS가 강제라 추가 설정이 불가피했고, 노드 기반 클러스터 캐시로 전환하여 기존 구성을 유지하면서 Valkey의 비용 절감 이점도 유지했습니다.
보안 그룹 변경 후 Kafka 연결이 끊겼습니다.
문제
Group coordinator 43.200.28.227:29092 is unavailable
원인 — .env에 Kafka 퍼블릭 IP가 설정되어 있었는데, 보안 그룹 변경으로 외부 접근이 차단됐습니다.
해결 — 같은 VPC 내에서는 프라이빗 IP로 통신
KAFKA_BOOTSTRAPS={Kafka-EC2-프라이빗-IP}:29092
교훈 — 같은 VPC 내 서비스 간 통신은 반드시 프라이빗 IP를 사용해야 합니다. 퍼블릭 IP는 보안 그룹 변경에 취약합니다.
Gateway에서 서비스로 라우팅 시 80번 포트로 접근하는 문제가 발생했습니다.
문제
connection timed out: /172.31.35.186:80
원인 — application.yml의 non-secure-port: 80 설정이 Eureka에 등록되는 포트 정보에 영향을 줬습니다.
해결 — non-secure-port: 8080으로 변경, 실제 실행 포트와 일치시킴
교훈 — Eureka 인스턴스 설정의 포트 정보는 실제 서비스 포트와 반드시 일치해야 합니다.
여러 서비스가 동시에 뜨면서 RDS 커넥션이 고갈됐습니다.
문제
remaining connection slots are reserved for roles with privileges of the "rds_reserved" role
원인
HikariCP 기본값: 10개
서비스 10개 × 10 = 100 커넥션
RDS db.t4g.micro max_connections: 약 112
→ 한계치 도달
해결 — 각 서비스 application-prod.yml에 HikariCP 설정 추가
spring:
datasource:
hikari:
maximum-pool-size: 5
minimum-idle: 2
10개 × 5 = 50 커넥션 → 여유 있게 운영
교훈 — MSA 환경에서는 서비스 수 × 커넥션 풀 크기를 DB 최대 커넥션과 비교해서 설정해야 합니다.
빌드가 반복되면서 Jenkins workspace가 쌓여 디스크 공간이 부족해졌습니다.
문제
Disk space is below threshold of 1.00 GiB
Built-In Node offline
해결 — Jenkinsfile에 빌드 후 자동 정리 추가
post {
always {
cleanWs()
sh 'docker system prune -f'
}
}
교훈 — Jenkins 빌드마다 workspace와 Docker 이미지가 쌓입니다. 자동 정리 설정은 필수입니다.
GitHub PR 머지
→ Webhook → Jenkins 트리거
→ Gradle 빌드
→ Docker 이미지 빌드 & DockerHub 푸시
→ 각 서비스 프라이빗 EC2 SSH 접속 후 배포
→ docker pull & run
10개 서비스 전부 자동 배포 완성.
로컬에서 잘 되던 것이 AWS에 올리면 안 되는 이유는 대부분 네트워크 설정, 환경변수, 버전 차이 세 가지였습니다. 배포 환경에서 직접 부딪혀보지 않으면 알 수 없는 것들입니다.
삽질한 시간이 결국 가장 많이 배운 시간이었습니다.