Concurrency

2025. 3. 2. 14:35Spring Microservice

📌 Concurrency (동시성 처리)

(Twelve-Factor App 원칙: 프로세스 모델을 사용한 확장성 확보)

클라우드 네이티브 애플리케이션은 수직적 확장(Scale-Up)이 아니라, 수평적 확장(Scale-Out)을 사용하여 확장해야 합니다.
즉, 단일 프로세스를 더 크게 만드는 것이 아니라, 여러 개의 프로세스를 생성하여 트래픽을 분산하는 방식이 바람직합니다.

🔹 1. 확장(Scaling) 방식의 차이

📌 아래 다이어그램은 수직적 확장(Scale-Up)과 수평적 확장(Scale-Out)의 차이를 보여줍니다.

출처 : Spring Microservices in Action 2nd Edition

 

✅ (1) 수직적 확장(Scale-Up)

  • CPU, RAM 등의 하드웨어 자원을 증가시켜 애플리케이션을 더 크게 확장.
  • 단일 서버의 성능을 향상하여 부하를 처리.
  • 하지만, 하드웨어 성능의 한계가 존재하며, 비용이 기하급수적으로 증가.

📌 예제

확장 전 확장 후
1 CPU / 1GB RAM 4 CPU / 4GB RAM

 

🚨 문제점:
서버 성능 향상 가능하지만, 비용이 높고 한계가 존재.
✅ 단일 인스턴스 의존 → 서버 장애 시 전체 서비스 중단 위험.

✅ (2) 수평적 확장(Scale-Out)

  • 하드웨어 성능을 증가시키는 대신, 애플리케이션 인스턴스를 여러 개 실행하여 트래픽을 분산.
  • 로드 밸런서를 통해 트래픽을 여러 인스턴스로 분배.
  • 컨테이너 오케스트레이션(Kubernetes) 및 오토스케일링(Auto Scaling) 활용 가능.

📌 예제

확장 전 확장 후
1 CPU / 1GB RAM (4개 인스턴스) 1 CPU / 1GB RAM × 4

 

장점:

  • 자동 확장 가능 (Auto Scaling) → 요청량이 증가하면 인스턴스를 동적으로 추가
  • 고가용성(High Availability) 보장 → 특정 인스턴스 장애 발생 시, 나머지 인스턴스가 요청 처리
  • 비용 최적화 가능 → 클라우드 환경에서는 유휴 리소스를 최소화하여 비용 절감 가능

🔹 2. 마이크로서비스에서 Scale-Out을 구현하는 방법

✅ (1) 로드 밸런서를 활용한 트래픽 분산

로드 밸런서는 여러 개의 서비스 인스턴스 중 하나로 트래픽을 자동 분배합니다.

 

📌 Nginx를 활용한 로드 밸런서 예제

upstream my_microservices {
    server service1:8080;
    server service2:8080;
    server service3:8080;
}

server {
    listen 80;
    location / {
        proxy_pass http://my_microservices;
    }
}

 

📌 AWS ALB(Application Load Balancer) 활용 예제

aws elbv2 create-load-balancer --name my-load-balancer --type application

Scale-Out 적용 시 로드 밸런서를 사용하여 트래픽을 자동 분배할 수 있음.

✅ (2) Kubernetes를 활용한 오토스케일링(Auto Scaling)

Kubernetes(HPA, Horizontal Pod Autoscaler)를 활용하면, 애플리케이션 부하에 따라 자동으로 인스턴스를 확장할 수 있습니다.

📌 Kubernetes HPA 설정 예제

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-microservice-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-microservice
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50

트래픽 증가 시, 자동으로 10개까지 확장 가능.
CPU 사용량이 50%를 초과하면 새로운 인스턴스가 자동으로 추가됨.

✅ (3) Spring Boot에서 Scale-Out을 고려한 개발

Spring Boot 애플리케이션을 Scale-Out 하려면,
세션을 공유하지 않고, Stateless(무상태)하게 설계해야 합니다.

 

📌 Redis를 활용한 세션 스토리지 예제

spring:
  session:
    store-type: redis
  redis:
    host: redis-cluster
    port: 6379

 

📌 OAuth2를 활용한 Stateless 인증 구현

security:
  oauth2:
    resource:
      jwt:
        key-uri: https://my-auth-server.com/oauth/token

세션이 아닌 Redis 또는 JWT를 활용하여, Scale-Out이 가능하도록 설계해야 함.

🔹 3. Scale-Up vs Scale-Out 비교

방식 Scale-Up (수직적 확장) Scale-Out (수평적 확장)
확장 방법 서버 성능(CPU, RAM) 증가 서버 인스턴스 수 증가
확장 한계 물리적 한계 존재 무한 확장 가능 (이론적으로)
비용 초기 비용 높음 비용 효율적 (Auto Scaling)
고가용성(HA) 단일 장애 발생 시 전체 다운 장애 발생 시 트래픽을 다른 인스턴스로 분산
클라우드 친화성 제한적 클라우드 네이티브 아키텍처에 적합

📌 결론: Scale-Out을 적용하는 핵심 원칙

1️⃣ Scale-Up(수직적 확장)보다 Scale-Out(수평적 확장)이 바람직함
2️⃣ 로드 밸런서를 활용하여 트래픽을 자동 분배해야 함
3️⃣ Kubernetes HPA(Auto Scaling)를 활용하여 부하에 따라 자동 확장하도록 설계
4️⃣ Stateless(무상태) 방식으로 개발하여, 여러 인스턴스가 동시에 실행될 수 있도록 해야 함
5️⃣ 세션을 개별 서비스가 아닌 Redis, JWT 등의 외부 저장소에서 관리하여 확장성 확보

 

🔹 이를 통해 대규모 트래픽에도 대응 가능한 확장성 높은 마이크로서비스를 구축할 수 있습니다! 🚀

'Spring Microservice' 카테고리의 다른 글

Dev/prod parity  (0) 2025.03.02
Disposability  (0) 2025.03.02
Port binding  (0) 2025.03.02
Processes  (0) 2025.03.02
Backing Services  (0) 2025.03.02