CS/Linux

[Linux] 배포관련 아키텍쳐 best practice?

Mini_96 2024. 9. 4. 23:27

네, 좋은 접근 방식입니다. Nginx가 정적 파일을 처리하고 동적 요청만 WAS(Web Application Server)가 처리하는 구조는 매우 효율적이고 일반적으로 사용되는 아키텍처입니다. 이 구조를 개선하고 확장하여 더 강력한 아키텍처를 만들 수 있습니다. 다음은 개선된 구조와 그에 대한 설명입니다:

                                   [CDN]
                                     |
                                     v
[Client] <----> [Load Balancer] <----> [Nginx] <----> [Static Files]
                      |                  |
                      |                  v
                      |          [Caching Layer]
                      |                  |
                      v                  v
                 [Node.js App 1] <----> [Database]
                 [Node.js App 2]
                 [Node.js App 3]

이 구조의 주요 구성 요소와 이점:

  1. CDN (Content Delivery Network):
    • 정적 콘텐츠를 사용자와 가까운 서버에서 제공하여 로딩 속도를 향상시킵니다.
    • 주 서버의 부하를 줄입니다.
  2. Load Balancer:
    • 여러 Nginx 서버로 트래픽을 분산시켜 고가용성을 보장합니다.
    • 서버 장애 시 자동으로 트래픽을 다른 서버로 전환합니다.
  3. Nginx:
    • 정적 파일 서빙: HTML, CSS, JavaScript, 이미지 등을 직접 처리합니다.
    • 리버스 프록시: 동적 요청을 Node.js 애플리케이션으로 전달합니다.
    • SSL 종단: HTTPS 연결을 처리합니다.
  4. Caching Layer:
    • Redis나 Memcached를 사용하여 자주 요청되는 데이터를 캐싱합니다.
    • 데이터베이스 부하를 줄이고 응답 시간을 개선합니다.
  5. Node.js Applications:
    • 수평적 확장: 여러 인스턴스를 실행하여 부하를 분산시킵니다.
    • PM2를 사용하여 프로세스를 관리하고 무중단 배포를 수행합니다.
  6. Database:
    • 필요에 따라 읽기 전용 복제본을 사용하여 읽기 성능을 향상시킬 수 있습니다.

이 구조를 구현하기 위한 주요 단계:

  1. Nginx 설정:
http {
    upstream nodejs_servers {
        server 127.0.0.1:3000;
        server 127.0.0.1:3001;
        server 127.0.0.1:3002;
    }

    server {
        listen 80;
        server_name example.com;

        location / {
            root /var/www/html;
            try_files $uri $uri/ @nodejs;
        }

        location @nodejs {
            proxy_pass http://nodejs_servers;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
        }

        location ~* \.(jpg|jpeg|png|gif|ico|css|js)$ {
            expires 30d;
        }
    }
}
  1. Node.js 애플리케이션 확장:
pm2 start main.js -i max
  1. 캐싱 레이어 추가 (Redis 예시):
const redis = require('redis');
const client = redis.createClient();

app.get('/api/data', (req, res) => {
  const key = 'api:data';
  client.get(key, (err, data) => {
    if (data) {
      return res.json(JSON.parse(data));
    }
    // 데이터베이스에서 데이터를 가져오고 Redis에 캐시
    fetchDataFromDB().then(result => {
      client.setex(key, 3600, JSON.stringify(result));
      res.json(result);
    });
  });
});

이 구조의 장점:

  1. 높은 성능: 정적 파일은 Nginx에서 빠르게 처리되고, 동적 요청은 Node.js에서 효율적으로 처리됩니다.
  2. 확장성: 부하에 따라 Node.js 인스턴스를 쉽게 추가할 수 있습니다.
  3. 가용성: 로드 밸런서와 여러 서버 인스턴스로 고가용성을 확보합니다.
  4. 보안: Nginx가 첫 번째 방어선 역할을 하며, 직접적인 공격으로부터 애플리케이션 서버를 보호합니다.
  5. 유연성: 각 컴포넌트를 독립적으로 확장하고 최적화할 수 있습니다.

이 구조를 기반으로 시작하고, 필요에 따라 점진적으로 각 컴포넌트를 추가하거나 최적화할 수 있습니다. 특정 부분에 대해 더 자세한 정보가 필요하다면 말씀해 주세요.