Skip to content

KT-AIVLE-04/backend

Repository files navigation

πŸ—οΈ Marketing Platform Backend

Spring Boot 기반 λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ μ•„ν‚€ν…μ²˜

CI/CD Java Spring Boot Docker

AI 기반 μ†Œμ…œλ―Έλ””μ–΄ λ§ˆμΌ€νŒ… μžλ™ν™” ν”Œλž«νΌμ˜ λ°±μ—”λ“œ μ‹œμŠ€ν…œ


πŸ“‹ λͺ©μ°¨


πŸ—οΈ λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ μ•„ν‚€ν…μ²˜

μ‹œμŠ€ν…œ ꡬ쑰

Main

핡심 섀계 원칙

  • 단일 μ±…μž„: 각 μ„œλΉ„μŠ€λŠ” νŠΉμ • λΉ„μ¦ˆλ‹ˆμŠ€ 도메인에 집쀑
  • 독립 배포: μ„œλΉ„μŠ€λ³„ 독립적인 배포 및 μŠ€μΌ€μΌλ§
  • 데이터 독립성: 각 μ„œλΉ„μŠ€λŠ” 자체 λ°μ΄ν„°λ² μ΄μŠ€ 보유
  • μž₯μ•  격리: ν•œ μ„œλΉ„μŠ€μ˜ μž₯μ• κ°€ 전체 μ‹œμŠ€ν…œμ— 영ν–₯을 μ£Όμ§€ μ•ŠμŒ

πŸ› οΈ 기술 μŠ€νƒ

Core Framework

  • Java 17 - LTS λ²„μ „μœΌλ‘œ μ•ˆμ •μ„±κ³Ό μ„±λŠ₯ 보μž₯
  • Spring Boot 3.5.4 - μ΅œμ‹  ν”„λ ˆμž„μ›Œν¬ 기반 λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€
  • Spring Cloud 2025.0.0 - λ§ˆμ΄ν¬λ‘œμ„œλΉ„μŠ€ 인프라 톡합

Microservice Infrastructure

  • Spring Cloud Gateway - API κ²Œμ΄νŠΈμ›¨μ΄, λΌμš°νŒ…, λ‘œλ“œ λ°ΈλŸ°μ‹±
  • Spring Security 6.x - λ³΄μ•ˆ 및 인증 처리
  • Spring Data JPA - 데이터 μ ‘κ·Ό 계측

Database & Cache

  • MySQL 8.0 - μ£Ό λ°μ΄ν„°λ² μ΄μŠ€ (각 μ„œλΉ„μŠ€λ³„ 독립 μŠ€ν‚€λ§ˆ)
  • Redis 7.2 - μ„Έμ…˜ μ €μž₯, 토큰 관리, 캐싱

Message Queue & Storage

  • Apache Kafka 7.4.3 - 이벀트 슀트리밍, μ„œλΉ„μŠ€ κ°„ 비동기 톡신
  • AWS S3 - λ―Έλ””μ–΄ 파일 μ €μž₯μ†Œ
  • AWS CloudFront - κΈ€λ‘œλ²Œ CDN

DevOps & Build

  • Gradle 8.x - λ©€ν‹°λͺ¨λ“ˆ ν”„λ‘œμ νŠΈ λΉŒλ“œ 도ꡬ
  • Docker & Docker Compose - μ»¨ν…Œμ΄λ„ˆν™” 및 μ˜€μΌ€μŠ€νŠΈλ ˆμ΄μ…˜
  • GitHub Actions - CI/CD νŒŒμ΄ν”„λΌμΈ

External APIs

  • YouTube Data API v3 - λ™μ˜μƒ μ—…λ‘œλ“œ 및 관리
  • Google OAuth2 - μ†Œμ…œ 둜그인
  • Kakao OAuth2 - μ†Œμ…œ 둜그인
  • FastAPI AI Service - AI μ½˜ν…μΈ  생성

πŸ”Œ μ„œλΉ„μŠ€ ꡬ성

포트 ꡬ성

μ„œλΉ„μŠ€ 개발 포트 Docker λ‚΄λΆ€ μ™ΈλΆ€ μ ‘κ·Ό μƒνƒœ
Gateway 8080 8080 :8080 βœ… 싀행쀑
Auth Service 8081 8081 λ‚΄λΆ€ μ „μš© βœ… 싀행쀑
Store Service 8082 8082 λ‚΄λΆ€ μ „μš© βœ… 싀행쀑
Content Service 8083 8083 λ‚΄λΆ€ μ „μš© βœ… 싀행쀑
SNS Service 8084 8084 λ‚΄λΆ€ μ „μš© βœ… 싀행쀑
Shorts Service 8085 8085 λ‚΄λΆ€ μ „μš© βœ… 싀행쀑
Analytics Service 8086 8086 λ‚΄λΆ€ μ „μš© βœ… 싀행쀑

πŸ”’ λ³΄μ•ˆ 섀계: Gatewayλ₯Ό ν†΅ν•œ 단일 μ§„μž…μ μœΌλ‘œ λ‚΄λΆ€ μ„œλΉ„μŠ€ 보호

μ„œλΉ„μŠ€λ³„ μ—­ν• 

πŸ” Gateway (API Gateway)

μ£Όμš” μ±…μž„:

  • λͺ¨λ“  μ™ΈλΆ€ μš”μ²­μ˜ 단일 μ§„μž…μ 
  • JWT 토큰 검증 및 μ‚¬μš©μž 인증
  • μ„œλΉ„μŠ€λ³„ μš”μ²­ λΌμš°νŒ… 및 λ‘œλ“œ λ°ΈλŸ°μ‹±
  • CORS μ •μ±… 관리
  • Rate Limiting 및 μš”μ²­ μ œν•œ

핡심 κΈ°λŠ₯:

  • 동적 λΌμš°νŒ…: /api/auth/** β†’ Auth Service
  • 토큰 기반 인증: JWT Access Token 검증
  • μ‚¬μš©μž μ»¨ν…μŠ€νŠΈ μ „νŒŒ: 헀더λ₯Ό ν†΅ν•œ μ‚¬μš©μž 정보 전달
πŸ‘€ Auth Service (인증/인가)

μ£Όμš” μ±…μž„:

  • μ‚¬μš©μž νšŒμ›κ°€μž…, 둜그인, λ‘œκ·Έμ•„μ›ƒ
  • JWT 토큰 생성 및 관리
  • OAuth2 μ†Œμ…œ 둜그인 (Google, Kakao)
  • μ‚¬μš©μž ν”„λ‘œν•„ 관리
  • λ³΄μ•ˆ μ •μ±… 관리 (계정 잠금, μ‹€νŒ¨ 좔적)

핡심 κΈ°λŠ₯:

  • 토큰 관리: Access Token (2μ‹œκ°„), Refresh Token (14일)
  • 토큰 λΈ”λž™λ¦¬μŠ€νŠΈ: Redis 기반 λ‘œκ·Έμ•„μ›ƒ 토큰 λ¬΄νš¨ν™”
  • μ†Œμ…œ 둜그인: OAuth2 Provider 연동
πŸͺ Store Service (λ§€μž₯ 관리)

μ£Όμš” μ±…μž„:

  • λ§€μž₯ 정보 CRUD (생성, 쑰회, μˆ˜μ •, μ‚­μ œ)
  • 업쒅별 λΆ„λ₯˜ 관리 (μŒμ‹μ , 카페, νŒ¨μ…˜, λ·°ν‹°, 기술)
  • μœ„μΉ˜ 기반 μ„œλΉ„μŠ€ (μœ„λ„/경도 μ’Œν‘œ)
  • λ§€μž₯ 검증 및 승인 ν”„λ‘œμ„ΈμŠ€

핡심 κΈ°λŠ₯:

  • 지리적 검색: μœ„μΉ˜ 기반 λ§€μž₯ 검색
  • μ—…μ’… λΆ„λ₯˜: ν‘œμ€€ν™”λœ μ—…μ’… μ½”λ“œ 관리
  • λ§€μž₯ 검증: μ‚¬μ—…μž 정보 확인
πŸ“ Content Service (μ½˜ν…μΈ  관리)

μ£Όμš” μ±…μž„:

  • 이미지/λΉ„λ””μ˜€ μ—…λ‘œλ“œ 및 μ €μž₯
  • λ―Έλ””μ–΄ 메타데이터 μΆ”μΆœ 및 관리
  • 썸넀일 μžλ™ 생성
  • AWS S3 연동 및 CloudFront CDN 관리

핡심 κΈ°λŠ₯:

  • 파일 μ—…λ‘œλ“œ: λ©€ν‹°νŒŒνŠΈ μ—…λ‘œλ“œ 지원
  • μžλ™ μ΅œμ ν™”: 이미지 μ••μΆ• 및 리사이징
  • CDN 연동: κΈ€λ‘œλ²Œ μ½˜ν…μΈ  배포
πŸ“± SNS Service (μ†Œμ…œλ―Έλ””μ–΄ 연동)

μ£Όμš” μ±…μž„:

  • YouTube 채널 관리 및 연동
  • λ™μ˜μƒ μžλ™ μ—…λ‘œλ“œ
  • SNS 계정 OAuth 관리
  • κ²Œμ‹œλ¬Ό μ˜ˆμ•½ 및 μŠ€μΌ€μ€„λ§

핡심 κΈ°λŠ₯:

  • YouTube API: λ™μ˜μƒ μ—…λ‘œλ“œ, μˆ˜μ •, μ‚­μ œ
  • 채널 동기화: 채널 정보 μ‹€μ‹œκ°„ 동기화
  • 배치 μ—…λ‘œλ“œ: λŒ€λŸ‰ μ½˜ν…μΈ  μ˜ˆμ•½ κ²Œμ‹œ
πŸ€– Shorts Service (AI μ½˜ν…μΈ  생성)

μ£Όμš” μ±…μž„:

  • AI 기반 μ‹œλ‚˜λ¦¬μ˜€ μžλ™ 생성
  • 이미지/λΉ„λ””μ˜€ μ½˜ν…μΈ  생성
  • 비동기 μž‘μ—… 처리 및 μ§„ν–‰λ₯  좔적
  • FastAPI AI μ„œλ²„ 연동

핡심 κΈ°λŠ₯:

  • μ‹œλ‚˜λ¦¬μ˜€ 생성: GPT 기반 μ½˜ν…μΈ  μž‘μ„±
  • 비동기 처리: κΈ΄ μž‘μ—…μ˜ λ°±κ·ΈλΌμš΄λ“œ 처리
  • μ§„ν–‰λ₯  좔적: μ‹€μ‹œκ°„ μž‘μ—… μƒνƒœ λͺ¨λ‹ˆν„°λ§
πŸ“Š Analytics Service (뢄석)

μ£Όμš” μ±…μž„:

  • μ‹€μ‹œκ°„ μ„±κ³Ό 뢄석 및 λŒ€μ‹œλ³΄λ“œ
  • AI 기반 감정 뢄석
  • 배치 처리λ₯Ό ν†΅ν•œ νžˆμŠ€ν† λ¦¬μ»¬ 데이터 뢄석
  • μ„±κ³Ό μ§€ν‘œ 좔적 (쑰회수, νŒ”λ‘œμ›Œ, λŒ“κΈ€ λ“±)

핡심 κΈ°λŠ₯:

  • μ‹€μ‹œκ°„ 뢄석: Kafka 슀트림 기반 μ‹€μ‹œκ°„ 데이터 처리
  • 배치 뢄석: λŒ€μš©λŸ‰ 데이터 일괄 처리
  • 감정 뢄석: λŒ“κΈ€ 및 λ°˜μ‘ 감정 뢄석

🐳 Docker ν™˜κ²½

개발 ν™˜κ²½ vs 운영 ν™˜κ²½

개발 ν™˜κ²½ (docker-compose.yml)

services:
  # 개발용 - 호슀트 포트 직접 바인딩
  gateway:
    ports:
      - "8080:8080"  # μ™ΈλΆ€ μ ‘κ·Ό κ°€λŠ₯
  
  auth-service:
    ports:  
      - "8081:8081"  # 개발/ν…ŒμŠ€νŠΈμš© 직접 μ ‘κ·Ό
  
  # ... 기타 μ„œλΉ„μŠ€λ“€

운영 ν™˜κ²½ (docker-compose.prod.yml)

services:
  gateway:
    ports:
      - "8080:8080"  # μ™ΈλΆ€ μ ‘κ·Ό (λ‘œλ“œλ°ΈλŸ°μ„œ λ’€)
    
  auth-service:
    # 포트 바인딩 μ—†μŒ - Gatewayλ₯Ό ν†΅ν•΄μ„œλ§Œ μ ‘κ·Ό
    expose:
      - "8081"
    networks:
      - backend-network
  
  # ... 기타 μ„œλΉ„μŠ€λ“€ (λͺ¨λ‘ λ‚΄λΆ€ λ„€νŠΈμ›Œν¬λ§Œ μ‚¬μš©)

πŸš€ λΉ λ₯Έ μ‹œμž‘

사전 μš”κ΅¬μ‚¬ν•­

# ν•„μˆ˜ μ†Œν”„νŠΈμ›¨μ–΄ 버전 확인
java --version        # Java 17+
docker --version      # Docker 20.10+
docker-compose --version  # Docker Compose 2.0+

둜컬 개발 ν™˜κ²½ μ„€μ •

1. μ €μž₯μ†Œ 클둠

git clone https://github.com/KT-AIVLE-04/backend.git
cd marketing

2. ν™˜κ²½λ³€μˆ˜ μ„€μ •

# ν™˜κ²½ 파일 생성
cp .env.example .env

# ν•„μˆ˜ ν™˜κ²½λ³€μˆ˜ μ„€μ •
vim .env
πŸ“„ .env 파일 μ˜ˆμ‹œ
# Database Configuration
MYSQL_ROOT_PASSWORD=rootpassword
MYSQL_DATABASE=marketing_platform
MYSQL_USER=marketing_user
MYSQL_PASSWORD=marketing_password

# Redis Configuration
REDIS_PASSWORD=redis_password

# JWT Configuration
JWT_SECRET_KEY=your-256-bit-secret-key
JWT_ACCESS_EXPIRATION=7200     # 2 hours
JWT_REFRESH_EXPIRATION=1209600 # 14 days

# OAuth2 Configuration
GOOGLE_CLIENT_ID=your-google-client-id
GOOGLE_CLIENT_SECRET=your-google-client-secret
KAKAO_CLIENT_ID=your-kakao-client-id
KAKAO_CLIENT_SECRET=your-kakao-client-secret

# YouTube API
YOUTUBE_API_KEY=your-youtube-api-key

# AWS Configuration
AWS_ACCESS_KEY_ID=your-aws-access-key
AWS_SECRET_ACCESS_KEY=your-aws-secret-key
AWS_REGION=ap-northeast-2
S3_BUCKET_NAME=your-s3-bucket
CLOUDFRONT_DOMAIN=your-cloudfront-domain

# AI Service
AI_SERVICE_URL=http://ai-service:8000

3. 인프라 μ„œλΉ„μŠ€ μ‹€ν–‰

# MySQL, Redis, Kafka μ‹€ν–‰
docker-compose up -d mysql redis kafka zookeeper

# μ„œλΉ„μŠ€ μƒνƒœ 확인
docker-compose ps

4. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ λΉŒλ“œ 및 μ‹€ν–‰

# 전체 ν”„λ‘œμ νŠΈ λΉŒλ“œ
./gradlew clean build

# μ„œλΉ„μŠ€λ³„ κ°œλ³„ μ‹€ν–‰ (개발용)
./gradlew :gateway:bootRun &
./gradlew :auth-service:bootRun &
./gradlew :store-service:bootRun &
./gradlew :content-service:bootRun &
./gradlew :sns-service:bootRun &
./gradlew :shorts-service:bootRun &
./gradlew :analytics-service:bootRun &

5. Docker Compose 전체 μ‹€ν–‰ (ꢌμž₯)

# 전체 μ‹œμŠ€ν…œ μ‹€ν–‰
docker-compose up -d

# 둜그 확인
docker-compose logs -f

# νŠΉμ • μ„œλΉ„μŠ€ 둜그만 확인
docker-compose logs -f gateway auth-service

μ‹€ν–‰ 확인

# Health Check
curl http://localhost:8080/actuator/health

# API Gateway μƒνƒœ
curl http://localhost:8080/actuator/gateway/routes

# 각 μ„œλΉ„μŠ€ Swagger UI μ ‘κ·Ό
# http://localhost:8080/auth/swagger-ui.html
# http://localhost:8080/store/swagger-ui.html
# http://localhost:8080/content/swagger-ui.html

βš™οΈ ν™˜κ²½ μ„€μ •

μ„œλΉ„μŠ€λ³„ μ„€μ • 파일

각 μ„œλΉ„μŠ€λŠ” 독립적인 application.yml νŒŒμΌμ„ κ°€μ§‘λ‹ˆλ‹€:

πŸ” Gateway μ„€μ •
server:
  port: 8080

spring:
  application:
    name: gateway
  cloud:
    gateway:
      routes:
        - id: auth-service
          uri: http://auth-service:8081
          predicates:
            - Path=/api/auth/**
          filters:
            - StripPrefix=2
            
        - id: store-service  
          uri: http://store-service:8082
          predicates:
            - Path=/api/store/**
          filters:
            - StripPrefix=2
            - AuthFilter

      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "*"
            allowedMethods: "*"
            allowedHeaders: "*"

management:
  endpoints:
    web:
      exposure:
        include: health,info,gateway
πŸ‘€ Auth Service μ„€μ •
server:
  port: 8081

spring:
  application:
    name: auth-service
  datasource:
    url: jdbc:mysql://mysql:3306/marketing_auth
    username: ${MYSQL_USER}
    password: ${MYSQL_PASSWORD}
  
  data:
    redis:
      host: redis
      port: 6379
      password: ${REDIS_PASSWORD}
      
  security:
    oauth2:
      client:
        registration:
          google:
            client-id: ${GOOGLE_CLIENT_ID}
            client-secret: ${GOOGLE_CLIENT_SECRET}
            
jwt:
  secret: ${JWT_SECRET_KEY}
  access-expiration: ${JWT_ACCESS_EXPIRATION:7200}
  refresh-expiration: ${JWT_REFRESH_EXPIRATION:1209600}

ν”„λ‘œνŒŒμΌλ³„ μ„€μ •

# 개발 ν™˜κ²½
spring.profiles.active=dev

# ν…ŒμŠ€νŠΈ ν™˜κ²½  
spring.profiles.active=test

# 운영 ν™˜κ²½
spring.profiles.active=prod

πŸ“Š λ°μ΄ν„°λ² μ΄μŠ€ 섀계

ERD (Entity Relationship Diagram)

Main


πŸ“š API λ¬Έμ„œ

Swagger UI μ ‘κ·Ό

각 μ„œλΉ„μŠ€λ³„ API λ¬Έμ„œλŠ” Gatewayλ₯Ό 톡해 μ ‘κ·Όν•  수 μžˆμŠ΅λ‹ˆλ‹€:

μ„œλΉ„μŠ€ Swagger UI μ„€λͺ…
Gateway localhost:8080/swagger-ui.html 전체 API κ²Œμ΄νŠΈμ›¨μ΄
Auth localhost:8080/auth/swagger-ui.html 인증/인가 API
Store localhost:8080/store/swagger-ui.html λ§€μž₯ 관리 API
Content localhost:8080/content/swagger-ui.html μ½˜ν…μΈ  관리 API
SNS localhost:8080/sns/swagger-ui.html SNS 연동 API
Shorts localhost:8080/shorts/swagger-ui.html AI μ½˜ν…μΈ  생성 API
Analytics localhost:8080/analytics/swagger-ui.html 뢄석 API

API 인증

λͺ¨λ“  API μš”μ²­μ€ JWT 토큰 인증이 ν•„μš”ν•©λ‹ˆλ‹€ (인증 API μ œμ™Έ):

# 1. 둜그인으둜 토큰 νšλ“
curl -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "password123"
  }'

# Response
{
  "accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "refreshToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "expiresIn": 7200
}

# 2. API μš”μ²­ μ‹œ 헀더에 토큰 포함
curl -X GET http://localhost:8080/api/store/my-stores \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

πŸ”„ CI/CD νŒŒμ΄ν”„λΌμΈ

GitHub Actions μ›Œν¬ν”Œλ‘œμš°

우리의 CI/CDλŠ” λ³€κ²½λœ μ„œλΉ„μŠ€λ§Œ μ„ νƒμ μœΌλ‘œ λ°°ν¬ν•˜λŠ” μŠ€λ§ˆνŠΈν•œ νŒŒμ΄ν”„λΌμΈμž…λ‹ˆλ‹€

배포 μ „λž΅

1. Path-based Filtering

# λ³€κ²½λœ κ²½λ‘œμ— 따라 μ„œλΉ„μŠ€ 감지
filters:
  gateway:
    - 'gateway/**'
  auth:
    - 'auth-service/**'
  common:
    - 'common/**'     # common λ³€κ²½ μ‹œ λͺ¨λ“  μ„œλΉ„μŠ€ μž¬λΉŒλ“œ
  compose:
    - 'docker-compose.prod.yml'  # Docker μ„€μ • λ³€κ²½

2. Matrix Parallel Deployment

strategy:
  fail-fast: false
  matrix:
    # λ™μ μœΌλ‘œ μƒμ„±λ˜λŠ” 맀트릭슀
    include:
      - service: "gateway"
        module: "gateway" 
        image: "aivle-gateway"
        compose: "gateway"
        build: true
      - service: "auth-service"
        module: "auth-service"
        image: "aivle-auth"
        compose: "auth-service" 
        build: true

3. 슀마트 배포 쑰건

쑰건 행동 μ„€λͺ…
μ„œλΉ„μŠ€ μ½”λ“œ λ³€κ²½ ν•΄λ‹Ή μ„œλΉ„μŠ€λ§Œ λΉŒλ“œ/배포 효율적인 배포
common λͺ¨λ“ˆ λ³€κ²½ λͺ¨λ“  μ„œλΉ„μŠ€ μž¬λΉŒλ“œ μ˜μ‘΄μ„± μ•ˆμ •μ„±
docker-compose λ³€κ²½ μ„€μ •λ§Œ μ—…λ°μ΄νŠΈ μ»¨ν…Œμ΄λ„ˆ μž¬μ‹œμž‘
[full-redeploy] PR 전체 μ„œλΉ„μŠ€ 재배포 κ°•μ œ 전체 배포

4. 배포 ν”„λ‘œμ„ΈμŠ€

# 1. λ³€κ²½ 감지 및 맀트릭슀 생성
echo "Changed services: gateway, auth-service"

# 2. 병렬 λΉŒλ“œ (λ³€κ²½λœ μ„œλΉ„μŠ€λ§Œ)
./gradlew :gateway:clean :gateway:build
./gradlew :auth-service:clean :auth-service:build

# 3. Docker 이미지 λΉŒλ“œ & ν‘Έμ‹œ  
docker build -t username/aivle-gateway:latest gateway/
docker push username/aivle-gateway:latest

# 4. AWS μ„œλ²„ 배포
docker-compose pull gateway auth-service
docker-compose up -d --no-deps gateway auth-service

# 5. ν—¬μŠ€μ²΄ν¬ 및 정리
docker image prune -f

배포 ν™˜κ²½

AWS 인프라

  • EC2: Ubuntu μ„œλ²„μ— Docker Compose둜 배포
  • RDS: MySQL 8.0 κ΄€λ¦¬ν˜• λ°μ΄ν„°λ² μ΄μŠ€
  • ElastiCache: Redis ν΄λŸ¬μŠ€ν„°
  • S3: λ―Έλ””μ–΄ 파일 μ €μž₯μ†Œ
  • CloudFront: κΈ€λ‘œλ²Œ CDN

λ³΄μ•ˆ μ„€μ •

# GitHub Secrets에 μ €μž₯된 ν™˜κ²½λ³€μˆ˜λ“€
secrets:
  DOCKER_USERNAME: Docker Hub μ‚¬μš©μžλͺ…
  DOCKER_PASSWORD: Docker Hub νŒ¨μŠ€μ›Œλ“œ  
  AWS_SECRET_HOST: EC2 μ„œλ²„ IP
  AWS_SECRET_ACCESS_KEY: EC2 SSH ν‚€
  APPLICATION_YML_*: 각 μ„œλΉ„μŠ€λ³„ μ„€μ • 파일
  CLOUDFRONT_PRIVATE_KEY: CloudFront μ„œλͺ… ν‚€

배포 λͺ¨λ‹ˆν„°λ§

# 배포 μƒνƒœ 확인
curl http://your-server:8080/actuator/health

# μ„œλΉ„μŠ€λ³„ μƒνƒœ 확인  
docker-compose ps

# 둜그 λͺ¨λ‹ˆν„°λ§
docker-compose logs -f --tail=100 gateway auth-service

πŸ“ ν”„λ‘œμ νŠΈ ꡬ쑰

backend/
β”œβ”€β”€ πŸ“„ README.md                    # 이 파일
β”œβ”€β”€ πŸ“„ build.gradle                 # 루트 λΉŒλ“œ μ„€μ •
β”œβ”€β”€ πŸ“„ settings.gradle               # λ©€ν‹°λͺ¨λ“ˆ μ„€μ •
β”œβ”€β”€ πŸ“„ docker-compose.yml           # 개발용 Docker Compose
β”œβ”€β”€ πŸ“„ docker-compose.prod.yml      # 운영용 Docker Compose
β”œβ”€β”€ πŸ“„ .env.example                 # ν™˜κ²½λ³€μˆ˜ ν…œν”Œλ¦Ώ
β”œβ”€β”€ πŸ“„ .gitignore                   # Git λ¬΄μ‹œ 파일
β”‚
β”œβ”€β”€ πŸ“ .github/
β”‚   └── πŸ“ workflows/
β”‚       └── πŸ“„ deploy.yml           # CI/CD νŒŒμ΄ν”„λΌμΈ
β”‚
β”œβ”€β”€ πŸ“ gradle/                      # Gradle Wrapper
β”‚   └── πŸ“ wrapper/
β”œβ”€β”€ πŸ“„ gradlew                      # Gradle Wrapper 슀크립트
β”œβ”€β”€ πŸ“„ gradlew.bat                  # Windows용 Gradle 슀크립트
β”‚
β”œβ”€β”€ πŸ“ common/                      # 곡톡 λͺ¨λ“ˆ
β”‚   β”œβ”€β”€ πŸ“„ README.md
β”‚   β”œβ”€β”€ πŸ“„ build.gradle
β”‚   └── πŸ“ src/
β”‚       └── πŸ“ main/java/com/marketing/common/
β”‚           β”œβ”€β”€ πŸ“ config/          # 곡톡 μ„€μ •
β”‚           β”œβ”€β”€ πŸ“ dto/             # 곡톡 DTO
β”‚           β”œβ”€β”€ πŸ“ exception/       # 곡톡 μ˜ˆμ™Έ 처리
β”‚           └── πŸ“ util/            # μœ ν‹Έλ¦¬ν‹° 클래슀
β”‚
β”œβ”€β”€ πŸ“ gateway/                     # API Gateway
β”‚   β”œβ”€β”€ πŸ“„ README.md
β”‚   β”œβ”€β”€ πŸ“„ build.gradle
β”‚   β”œβ”€β”€ πŸ“„ Dockerfile
β”‚   └── πŸ“ src/
β”‚       β”œβ”€β”€ πŸ“ main/
β”‚       β”‚   β”œβ”€β”€ πŸ“ java/com/marketing/gateway/
β”‚       β”‚   β”‚   β”œβ”€β”€ πŸ“ config/      # Gateway μ„€μ •
β”‚       β”‚   β”‚   β”œβ”€β”€ πŸ“ filter/      # μ»€μŠ€ν…€ ν•„ν„°
β”‚       β”‚   β”‚   └── πŸ“„ GatewayApplication.java
β”‚       β”‚   └── πŸ“ resources/
β”‚       β”‚       └── πŸ“„ application.yml
β”‚       └── πŸ“ test/
β”‚
β”œβ”€β”€ πŸ“ auth-service/                # 인증 μ„œλΉ„μŠ€
β”œβ”€β”€ πŸ“ store-service/               # λ§€μž₯ 관리 μ„œλΉ„μŠ€
β”œβ”€β”€ πŸ“ content-service/             # μ½˜ν…μΈ  관리 μ„œλΉ„μŠ€  
β”œβ”€β”€ πŸ“ sns-service/                 # SNS 연동 μ„œλΉ„μŠ€
β”œβ”€β”€ πŸ“ shorts-service/              # AI μ½˜ν…μΈ  생성 μ„œλΉ„μŠ€
β”œβ”€β”€ πŸ“ analytics-service/           # 뢄석 μ„œλΉ„μŠ€
β”‚
β”œβ”€β”€ πŸ“ docs/                        # λ¬Έμ„œ
    β”œβ”€β”€ πŸ“„ api-documentation.md     # API λͺ…μ„Έμ„œ
    β”œβ”€β”€ πŸ“„ database-schema.md       # DB μŠ€ν‚€λ§ˆ
    β”œβ”€β”€ πŸ“„ deployment-guide.md      # 배포 κ°€μ΄λ“œ
    └── πŸ“ images/                  # λ‹€μ΄μ–΄κ·Έλž¨ 이미지


πŸ’» 개발 κ°€μ΄λ“œ

μ½”λ”© μ»¨λ²€μ…˜

Java μ½”λ”© μŠ€νƒ€μΌ

  • Google Java Style Guide μ€€μˆ˜
  • 4 spaces λ“€μ—¬μ“°κΈ° (νƒ­ μ‚¬μš© κΈˆμ§€)
  • Line length: 100자 μ œν•œ
  • Package naming: com.marketing.{service}.{layer}

넀이밍 μ»¨λ²€μ…˜

// βœ… 쒋은 μ˜ˆμ‹œ
@RestController
@RequestMapping("/api/stores")
public class StoreController {
    
    @GetMapping("/{storeId}")
    public ResponseEntity<StoreDto> getStoreById(@PathVariable Long storeId) {
        // ...
    }
}

// ❌ λ‚˜μœ μ˜ˆμ‹œ  
@RestController
public class storecontroller {
    
    @GetMapping("/getStore/{id}")
    public ResponseEntity<StoreDto> getstore(@PathVariable Long id) {
        // ...
    }
}

Git μ›Œν¬ν”Œλ‘œμš°

브랜치 μ „λž΅

main
β”œβ”€β”€ develop
β”‚   β”œβ”€β”€ feature/auth-jwt-implementation
β”‚   β”œβ”€β”€ feature/store-crud-api  
β”‚   β”œβ”€β”€ feature/shorts-ai-integration
β”‚   └── hotfix/auth-token-validation
└── release
    └── release/v1.0.0

컀밋 λ©”μ‹œμ§€ μ»¨λ²€μ…˜ (Conventional Commits)

# ν˜•μ‹: [scope] type: description

# κΈ°λŠ₯ μΆ”κ°€
[auth] feat: implement JWT token refresh mechanism

# 버그 μˆ˜μ •
[store] fix: resolve null pointer exception in store search

# λ¬Έμ„œ μ—…λ°μ΄νŠΈ
[readme] docs: update API endpoint documentation

# λ¦¬νŒ©ν† λ§
[common] refactor: extract common exception handling logic 

# ν…ŒμŠ€νŠΈ μΆ”κ°€
[auth] test: add unit tests for login service 

# λΉŒλ“œ/배포 κ΄€λ ¨
[github] ci: add parallel deployment for changed services 

Pull Request κ°€μ΄λ“œλΌμΈ

πŸ“‹ PR ν…œν”Œλ¦Ώ
## 🎯 λ³€κ²½ 사항
- [ ] μƒˆλ‘œμš΄ κΈ°λŠ₯ μΆ”κ°€
- [ ] 버그 μˆ˜μ •  
- [ ] λ¬Έμ„œ μ—…λ°μ΄νŠΈ
- [ ] λ¦¬νŒ©ν† λ§
- [ ] ν…ŒμŠ€νŠΈ μΆ”κ°€

## πŸ“‹ 상세 λ‚΄μš©
### λ³€κ²½λœ λ‚΄μš©
- API μ—”λ“œν¬μΈνŠΈ μΆ”κ°€: `POST /api/stores`
- λ§€μž₯ 생성 μ‹œ μœ νš¨μ„± 검사 둜직 κ΅¬ν˜„
- μœ„μΉ˜ 기반 검색 κΈ°λŠ₯ μΆ”κ°€

### ν…ŒμŠ€νŠΈ μ™„λ£Œ 사항
- [ ] λ‹¨μœ„ ν…ŒμŠ€νŠΈ 톡과
- [ ] 톡합 ν…ŒμŠ€νŠΈ 톡과  
- [ ] API λ¬Έμ„œ μ—…λ°μ΄νŠΈ
- [ ] 둜컬 ν™˜κ²½ ν…ŒμŠ€νŠΈ μ™„λ£Œ

## πŸ”— κ΄€λ ¨ 이슈
Closes #123

## πŸ“· μŠ€ν¬λ¦°μƒ· (UI λ³€κ²½ μ‹œ)
![image](screenshot-url)

## πŸš€ 배포 λ…ΈνŠΈ
- λ°μ΄ν„°λ² μ΄μŠ€ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜ ν•„μš”: `V001__create_stores_table.sql`
- ν™˜κ²½λ³€μˆ˜ μΆ”κ°€: `MAPS_API_KEY`

## πŸ“ λ¦¬λ·°μ–΄μ—κ²Œ
- νŠΉλ³„νžˆ κ²€ν† κ°€ ν•„μš”ν•œ λΆ€λΆ„: μœ„μΉ˜ 검색 μ•Œκ³ λ¦¬μ¦˜μ˜ μ„±λŠ₯
- ν…ŒμŠ€νŠΈ 데이터: `test-data.sql` μ°Έμ‘°

πŸ”§ νŠΈλŸ¬λΈ”μŠˆνŒ…

자주 λ°œμƒν•˜λŠ” λ¬Έμ œλ“€

πŸ”₯ 포트 좩돌 였λ₯˜

문제: Address already in use: bind

ν•΄κ²°:

# 1. 포트 μ‚¬μš© ν”„λ‘œμ„ΈμŠ€ 확인
lsof -i :8080
netstat -tlnp | grep :8080

# 2. ν”„λ‘œμ„ΈμŠ€ μ’…λ£Œ
kill -9 <PID>

# 3. Docker μ»¨ν…Œμ΄λ„ˆ 정리
docker-compose down
docker system prune -f
πŸ—„οΈ λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° μ‹€νŒ¨

문제: Connection refused: connect

ν•΄κ²°:

# 1. MySQL μ»¨ν…Œμ΄λ„ˆ μƒνƒœ 확인
docker-compose ps mysql

# 2. 둜그 확인
docker-compose logs mysql

# 3. λ°μ΄ν„°λ² μ΄μŠ€ μž¬μ‹œμž‘
docker-compose restart mysql

# 4. μ—°κ²° ν…ŒμŠ€νŠΈ
mysql -h localhost -P 3306 -u marketing_user -p
πŸ”‘ JWT 토큰 κ΄€λ ¨ 였λ₯˜

문제: Invalid JWT token λ˜λŠ” Token expired

ν•΄κ²°:

# 1. Redis μΊμ‹œ 확인
docker-compose exec redis redis-cli
> keys *
> get refresh_token:user_123

# 2. 토큰 μž¬λ°œκΈ‰
curl -X POST http://localhost:8080/api/auth/refresh \
  -H "Content-Type: application/json" \
  -d '{"refreshToken": "..."}'

# 3. λ‘œκ·Έμ•„μ›ƒ ν›„ 재둜그인
curl -X POST http://localhost:8080/api/auth/logout
🐳 Docker λ©”λͺ¨λ¦¬/λ””μŠ€ν¬ λΆ€μ‘±

문제: No space left on device

ν•΄κ²°:

# 1. μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” μ»¨ν…Œμ΄λ„ˆ 정리
docker container prune -f

# 2. μ‚¬μš©ν•˜μ§€ μ•ŠλŠ” 이미지 정리  
docker image prune -a -f

# 3. λ³Όλ₯¨ 정리
docker volume prune -f

# 4. 전체 μ‹œμŠ€ν…œ 정리 (주의!)
docker system prune -a -f --volumes

# 5. λ””μŠ€ν¬ μ‚¬μš©λŸ‰ 확인
docker system df
df -h
⚑ μ„œλΉ„μŠ€ κ°„ 톡신 였λ₯˜

문제: Connection refused between services

ν•΄κ²°:

# 1. λ„€νŠΈμ›Œν¬ μƒνƒœ 확인
docker network ls
docker network inspect backend_default

# 2. μ„œλΉ„μŠ€ κ°„ μ—°κ²° ν…ŒμŠ€νŠΈ
docker-compose exec gateway ping auth-service
docker-compose exec gateway curl http://auth-service:8081/actuator/health

# 3. DNS 확인
docker-compose exec gateway nslookup auth-service

# 4. 포트 바인딩 확인
docker-compose ps

둜그 뢄석

κ΅¬μ‘°ν™”λœ 둜그 확인

# 전체 μ„œλΉ„μŠ€ 둜그 (μ΅œμ‹  100쀄)
docker-compose logs -f --tail=100

# νŠΉμ • μ„œλΉ„μŠ€ 둜그
docker-compose logs -f gateway auth-service

# μ—λŸ¬ 둜그만 필터링
docker-compose logs | grep ERROR

# νŠΉμ • μ‹œκ°„λŒ€ 둜그
docker-compose logs --since="2024-01-15T10:00:00"

둜그 λ ˆλ²¨λ³„ 뢄석

  • ERROR: μ¦‰μ‹œ ν•΄κ²° ν•„μš”ν•œ μ‹¬κ°ν•œ 였λ₯˜
  • WARN: μ£Όμ˜κ°€ ν•„μš”ν•œ 상황, λͺ¨λ‹ˆν„°λ§ ν•„μš”
  • INFO: 정상적인 λΉ„μ¦ˆλ‹ˆμŠ€ ν”Œλ‘œμš° 둜그
  • DEBUG: 개발/λ””λ²„κΉ…μš© 상세 둜그 (운영 ν™˜κ²½μ—μ„œλŠ” λΉ„ν™œμ„±ν™”)

비상 λŒ€μ‘

μ„œλΉ„μŠ€ κΈ΄κΈ‰ μž¬μ‹œμž‘

# 1. νŠΉμ • μ„œλΉ„μŠ€λ§Œ μž¬μ‹œμž‘
docker-compose restart gateway auth-service

# 2. 전체 μ‹œμŠ€ν…œ μž¬μ‹œμž‘ (λ°μ΄ν„°λŠ” 보쑴)
docker-compose restart

# 3. μ™„μ „νžˆ 재배포 (주의: 데이터 손싀 κ°€λŠ₯)
docker-compose down
docker-compose pull
docker-compose up -d

둀백 절차

# 1. 이전 Docker μ΄λ―Έμ§€λ‘œ λ‘€λ°±
docker-compose stop gateway
docker run -d --name gateway_backup username/aivle-gateway:previous-tag
docker-compose start gateway

# 2. Git μ½”λ“œ λ‘€λ°±
git log --oneline -10
git reset --hard <commit-hash>
git push --force-with-lease origin release

🀝 κΈ°μ—¬ν•˜κΈ°

버그 발견, κΈ°λŠ₯ μ œμ•ˆ, λ˜λŠ” κ°œμ„ μ‚¬ν•­μ΄ μžˆλ‹€λ©΄ μ–Έμ œλ“ μ§€ 이슈λ₯Ό λ“±λ‘ν•΄μ£Όμ„Έμš”!

πŸ› 버그 리포트 β€’ πŸ’‘ κΈ°λŠ₯ μ œμ•ˆ β€’ πŸ“š λ¬Έμ„œ κ°œμ„ 


πŸ—οΈ Built with Spring Boot and Microservice Architecture

Β© 2025 KT AIVLE School 7κΈ° - Chaos Team

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 7

Languages