Oracle 마이크로 서버

Category
Status
Published
Tags
Oracle Cloud
Server
성능최적화
LRU
Description
Published
Slug

1. 서버 전체 구성도

인터넷 ↓ ┌─────────────────────────────────────────────────────────┐ │ Oracle Cloud 마이크로 인스턴스 (무료) │ │ • CPU: 1 vCPU (AMD EPYC 7551) │ │ • RAM: 1GB │ │ • Storage: 47GB │ │ • OS: Ubuntu 22.04 LTS │ │ • IP: 144.24.79.13 │ └─────────────────────────────────────────────────────────┘ ↓ ┌─────────────────────────────────────────────────────────────┐ │ Docker 컨테이너 환경 │ │ ┌─────────────┬─────────────┬────────────────────────────┐ │ │ │ - Backend │ - Redis │ - Nginx (Reverse Proxy) │ │ │ │ Node.js │ Cache │ Load Balancer │ │ │ │ Express │ In-Memory │ Static Files │ │ │ │ Port: 3001 │ Port: 6379 │ Port: 80/443 │ │ │ └─────────────┴─────────────┴────────────────────────────┘ │ └─────────────────────────────────────────────────────────────┘

2. Docker 컨테이너 구성

 
컨테이너
이미지
메모리 제한
CPU 제한
역할
Backend
Node.js 18 Alpine
200MB
0.7
API 서버 + AI 분석
Redis
Redis 7 Alpine
80MB
0.2
캐싱 시스템
Nginx
Nginx Alpine
50MB
0.1
리버스 프록시
Alpine(알파인)은 운영체제(OS) Alpine Linux(알파인 리눅스) 의미
Alpine Linux: 경량화와 보안에 초점을 맞춰 개발된 미니멀한 Linux 배포판.
일반적인 등산 장비가 아닌, 필수적인 것만 챙겨 가볍게 오르는 '알파인 스타일' 등반처럼,
이 운영체제도 꼭 필요한 핵심 기능만 담고 있음

Alpine 버전 장점

일반적인 Node.js 이미지(node:18)는 Debian 같은 범용 OS를 기반으로 하여 기능이 많은 대신 용량이 큼.
  1. 매우 작은 크기: 일반적인 Node.js 이미지의 크기가 수백 MB인 것에 비해, Alpine 기반 이미지는 수십 MB에 불과. 이로 인해 빌드 및 배포 속도가 빨라지고 저장 공간을 절약할 수 있음
  1. 보안 강화: 운영체제에 포함된 패키지와 라이브러리가 적기 때문에, 잠재적인 보안 취약점(공격 지점)이 그만큼 줄어듦
  1. 단순함: 꼭 필요한 요소만 포함되어 있어 환경이 깔끔하고 예측 가능성이 높음
 

3. 메모리/CPU 최적화 기법

메모리 최적화

1. Node.js 메모리 제한

# Dockerfile에서 CMD ["node", "--max-old-space-size=128", "dist/app.js"] # Docker Compose에서 environment: - NODE_OPTIONS=--max-old-space-size=128 mem_limit: 200m

2. Redis 경량화

# 64MB만 사용 + LRU 정책 redis-server --maxmemory 64mb --maxmemory-policy allkeys-lru
 

3. Alpine Linux 사용

  • 기본 Ubuntu: ~72MB → Alpine: ~5MB
  • 불필요한 패키지 모두 제거

4. Multi-stage 빌드

# 빌드 스테이지: 개발 도구 포함 FROM node:18-alpine AS builder # 런타임 스테이지: 필수 파일만 FROM node:18-alpine
 

CPU 최적화

1. 워커 프로세스 최적화

worker_processes 1; # CPU 1개에 맞춤 worker_connections 512;

2. 연결 재사용

keepalive 2; # 연결 재사용으로 CPU 절약

3. Gzip 압축

gzip on; # CPU 사용해서 대역폭 절약

 

4. 데이터베이스 (SQLite) 구조

저장 위치

/app/data/criti-ai.db (컨테이너 내부) ↓ Docker Volume: app_data (호스트에 영구 저장)

주요 테이블

analysis_cache -- 분석 결과 캐시 (24시간) users -- 사용자 정보 challenges -- 챌린지 데이터 challenge_results -- 사용자 답안 결과 user_badges -- 배지 시스템 analysis_stats -- 일일 통계

SQLite 선택 이유

  • 메모리 효율성: PostgreSQL 대비 적은 메모리 사용
  • 단순성: 별도 DB 서버 불필요
  • 성능: 단일 사용자 환경에서 충분히 빠름
  • 안정성: 파일 기반으로 백업 쉬움
 

5. 캐싱 시스템

요청 처리 흐름 1. 사용자 요청 ↓ 2. Redis 캐시 확인 (0.1초) ↓ cache miss 3. SQLite DB 캐시 확인 (0.3초) ↓ cache miss 4. 메모리 캐시 확인 (0.01초) ↓ cache miss 5. Gemini AI 분석 (3-10초) ↓ 6. 모든 캐시에 저장 ↓ 7. 사용자에게 응답

캐시 저장 우선순위

  1. Redis (1순위): 빠른 접근 + 만료 관리
  1. SQLite (2순위): 영구 보관 + 통계 활용
  1. Memory (3순위)

 

6. API 엔드포인트 전체 목록

분석 API (/api/analysis)

엔드포인트
메소드
설명
응답 시간
/analyze
POST
뉴스 기사 AI 분석
0.1초 (캐시) ~ 30초 (AI)
/quick-check
POST
빠른 신뢰도 체크
0.1초

챌린지 API (/api/challenge)

엔드포인트
메소드
설명
기능
/challenges
GET
모든 챌린지 조회
난이도별 필터
/challenges/:id
GET
특정 챌린지 조회
상세 정보
/challenges/:id/submit
POST
답안 제출 및 채점
배지 지급
/progress/:userId
GET
사용자 진행도
레벨/배지 시스템
/generate
POST
AI 챌린지 생성
Gemini AI 활용
/stats
GET
전체 통계
대시보드용

시스템 API

엔드포인트
설명
모니터링
/health
서버 상태 확인
1분마다 체크

7. 실행 과정

1. 서버 부팅

1. Ubuntu 시스템 부팅 2. Docker 서비스 시작 3. docker-compose.micro.yml 실행 4. 이미지 다운로드 (최초만) 5. 컨테이너 생성 및 시작

2. 컨테이너 초기화

Backend ├── Node.js 프로세스 시작 ├── Prisma DB 연결 ├── Redis 연결 대기 ├── Gemini API 키 검증 └── Express 서버 시작 (포트 3001) Redis ├── Redis 서버 시작 (포트 6379) ├── 64MB 메모리 할당 └── LRU 정책 활성화 Nginx ├── 설정 파일 로드 ├── 백엔드 연결 확인 └── 포트 80 리스닝 시작

3. 서비스 준비 완료

 
 

요청 처리 과정

사용자가 뉴스 분석 요청 시
1. 크롬 확장 → Background Script 2. Background Script → Nginx (포트 80) 3. Nginx → Backend (포트 3001) 4. Backend → Redis 캐시 확인 5. 캐시 없으면 → Gemini AI 호출 6. 결과를 3단계 캐시에 저장 7. 사용자에게 응답 반환

응답 속도 최적화

  1. 캐시 우선: 대부분요청은 캐시에서 처리 (0.1초)
  1. 연결 재사용: Keep-Alive로 연결 오버헤드 최소화
  1. Gzip 압축: 응답 크기 감소
 
 

메모리 최적화

  1. Node.js 힙 제한: 128MB로 고정
  1. Redis 메모리 제한: 64MB + LRU 정책
  1. Alpine Linux: 최소 OS 이미지
  1. Multi-stage Build: 런타임 이미지 최소화
 

CPU 최적화

  1. 워커 프로세스: CPU 코어 수에 맞춤
  1. 비동기 처리: Node.js 이벤트 루프 활용
  1. 캐싱 전략: CPU 집약적 AI 분석 최소화