LEVEL 58 QUEST
서비스 확장 전략
수평/수직 확장, 로드 밸런싱, DB 레플리카, CDN, 마이크로서비스, 매출 스케일링 전략까지 SaaS 성장을 위한 확장 전략을 다룹니다.
수평 확장 vs 수직 확장
스케일링의 두 가지 방향
수직 확장(Scale Up)은 서버 사양을 올리는 것이고, 수평 확장(Scale Out)은 서버 수를 늘리는 것입니다. SaaS 초기에는 수직 확장이 간단하지만, 성장하면 수평 확장이 필수가 됩니다.
| 항목 | 수직 확장 (Scale Up) | 수평 확장 (Scale Out) |
|---|---|---|
| 방법 | CPU/RAM/SSD 업그레이드 | 서버 수 증가 |
| 장점 | 코드 변경 없음, 간단 | 무한 확장 가능, 장애 대응 |
| 단점 | 물리적 한계, 단일 장애점 | 세션/파일 공유 필요, 복잡 |
| 비용 | 급격히 증가 | 선형 증가 |
| 추천 시점 | 주 50만원 이하 | 주 200만원 이상 |
| 다운타임 | 재시작 필요 | 무중단 가능 |
// 수평 확장 대비: 세션을 DB로 이관
// 여러 서버에서 세션을 공유하려면 파일 기반 세션은 불가능
class DbSessionHandler implements \SessionHandlerInterface {
private $pdo;
public function __construct($pdo) {
$this->pdo = $pdo;
}
public function open($path, $name): bool { return true; }
public function close(): bool { return true; }
public function read($id): string|false {
$stmt = $this->pdo->prepare("
SELECT data FROM sessions WHERE id = ? AND expires_at > NOW()
");
$stmt->execute([$id]);
$row = $stmt->fetch(PDO::FETCH_ASSOC);
return $row ? $row['data'] : '';
}
public function write($id, $data): bool {
$stmt = $this->pdo->prepare("
INSERT INTO sessions (id, data, expires_at)
VALUES (?, ?, DATE_ADD(NOW(), INTERVAL 24 HOUR))
ON DUPLICATE KEY UPDATE data = VALUES(data), expires_at = VALUES(expires_at)
");
return $stmt->execute([$id, $data]);
}
public function destroy($id): bool {
$stmt = $this->pdo->prepare("DELETE FROM sessions WHERE id = ?");
return $stmt->execute([$id]);
}
public function gc($maxLifetime): int|false {
$stmt = $this->pdo->prepare("DELETE FROM sessions WHERE expires_at );
$stmt->execute();
return $stmt->rowCount();
}
}
// 세션 핸들러 등록
$handler = new DbSessionHandler($pdo);
session_set_save_handler($handler, true);
session_start();
로드 밸런싱 개념
Nginx 로드 밸런서 설정
로드 밸런서는 들어오는 요청을 여러 서버에 분산합니다. 한 서버가 죽어도 나머지 서버가 트래픽을 처리하므로 가용성이 높아집니다. Nginx를 로드 밸런서로 사용하는 것이 가장 일반적입니다.
# nginx.conf - 로드 밸런서 설정
upstream saas_backend {
# 라운드 로빈 (기본) - 순서대로 분배
server 192.168.1.10:80 weight=3; # 메인 서버 (3배 트래픽)
server 192.168.1.11:80 weight=2; # 서브 서버
server 192.168.1.12:80 weight=1; # 백업 서버
server 192.168.1.13:80 backup; # 장애 시에만 활성화
# 헬스 체크
keepalive 32;
}
server {
listen 443 ssl;
server_name api.myapp.com;
location / {
proxy_pass http://saas_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# 타임아웃 설정
proxy_connect_timeout 5s;
proxy_read_timeout 30s;
}
}
// health_check.php - 헬스 체크 엔드포인트
// 로드 밸런서가 이 URL로 서버 상태를 확인
header('Content-Type: application/json');
$checks = [];
// 1. DB 연결 확인
try {
$pdo = new PDO($dsn, $user, $pass);
$pdo->query('SELECT 1');
$checks['db'] = 'ok';
} catch (Exception $e) {
$checks['db'] = 'fail';
}
// 2. 디스크 공간 확인
$freeGB = round(disk_free_space('/') / 1073741824, 1);
$checks['disk_free_gb'] = $freeGB;
$checks['disk'] = $freeGB > 1 ? 'ok' : 'fail';
// 3. PHP 프로세스 수 확인
$checks['php'] = 'ok';
// 전체 상태 판정
$healthy = !in_array('fail', $checks);
http_response_code($healthy ? 200 : 503);
echo json_encode([
'status' => $healthy ? 'healthy' : 'unhealthy',
'checks' => $checks,
'server' => gethostname(),
'time' => date('c'),
]);
🔒
여기까지는 미리보기입니다
서비스 확장 전략
무료 가입하면 이어서 볼 수 있고, 강의를 완료할 때마다 XP와 레벨이 쌓입니다.
Google로 3초 만에 시작 →🧵 Threads로 시작무료 공개 강의 둘러보기 (Lv.1~3)무료 가입하면 이어서 볼 수 있고, 강의를 완료할 때마다 XP와 레벨이 쌓입니다.