포도가게의 개발일지

[Node] Chat Server 부하줄이기(분산처리)[2] 본문

프로젝트

[Node] Chat Server 부하줄이기(분산처리)[2]

grape.store 2022. 2. 2. 20:51
반응형

[Node] Chat Server 부하줄이기(분산처리)[1]에서는 서로 다른 서버로 연결되는 버튼을 만들어 수동으로 유저를 서버에 분리해줬다.

하지만 실제 서비스에서는 트래픽을 분산 시키기 위하여 로드 밸런스를 이용하여 정책을 통해 서버에 분산하게 된다.

 

2번째 목표로 Nginx를 리버스 프록시서버로 사용하여 로드밸런스를 통해 유저를 서버에 분산 시킬 것이다.

CORS Error

- Access-Control-Allow-Origin header가 없다고 한다. 추가해주자

CORS가 뭘까?

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라우저에 알려주는 체제입니다. 웹 애플리케이션은 리소스가 자신의 출처(도메인, 프로토콜, 포트)와 다를 때 교차 출처 HTTP 요청을 실행합니다.

 

보안 상의 이유로, 브라우저는 스크립트에서 시작한 교차 출처 HTTP 요청을 제한합니다. 

 

교차 출처 요청의 예시: https://domain-a.com의 프론트 엔드 JavaScript 코드가 XMLHttpRequest를 사용하여 https://domain-b.com/data.json을 요청하는 경우.

Access-Control-Allow-Origin: <origin> | *

Access-Control-Allow-Origin 은 단일 출처를 지정하여 브라우저가 해당 출처가 리소스에 접근하도록 허용합니다. 또는 자격 증명이 없는 요청의 경우 "*" 와일드 카드는 브라우저의 origin에 상관없이 모든 리소스에 접근하도록 허용합니다.

예를들어 https://mozilla.org 의 코드가 리소스에 접근 할 수 있도록 하려면 다음과 같이 지정할 수 있습니다.

Access-Control-Allow-Origin: https://mozilla.org

https://developer.mozilla.org/ko/docs/Web/HTTP/CORS

 

교차 출처 리소스 공유 (CORS) - HTTP | MDN

교차 출처 리소스 공유(Cross-Origin Resource Sharing, CORS)는 추가 HTTP 헤더를 사용하여, 한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 선택한 자원에 접근할 수 있는 권한을 부여하도록 브라

developer.mozilla.org

- always는 add_header가 2XX, 3XX 이외의 http status code에도 적용되도록 하는 것이다.

nginx 1.7.5이상에서 사용할 수 있다.

http://nginx.org/en/docs/http/ngx_http_headers_module.html#add_header

 

Module ngx_http_headers_module

Module ngx_http_headers_module The ngx_http_headers_module module allows adding the “Expires” and “Cache-Control” header fields, and arbitrary fields, to a response header. Example Configuration expires 24h; expires modified +24h; expires @24h; exp

nginx.org

add_header 'Access-Control-Allow-Origin' '*' always;
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

 

AWS EC2에 Nginx + WAS(Node.js)를 동시에 띄울 것이다. 때문에 upstream은 localhost로 설정해 놓았다.

http {
	
    upstream chat {
    // defalult round-robin방식
    // ip hash는 ip주소를 이용하여 동일한 서버로 접속하게 해준다. 하지만 이러한 경우 서버에 골고루 나눠주지를 못함
    // round-robin이나 least는 분산을 잘 할 수 있으나, socket handshake가 도중에 error가 자꾸 나서
    // 생각을 해봤는데 3 way handshake과정은 http통신을 이용해 이루어지는데 계속 접속되는 서버가 바껴서 error가 나는 것 같았음
    // 때문에 동일한 ip 접속은 동일한 end chat server로 배치시켰다.
	ip_hash;
	server localhost:8000;
	server localhost:8001;
    }


    server {
        listen       3000;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {

		// socket 연결일 경우 반드시 설정
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

	    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
	    proxy_set_header Host $host;
	
	    //CORS 세팅 always까지 써주어야 upstream까지 적용된다.
        
       	add_header 'Access-Control-Allow-Origin' '*' always;
		add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
		add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';
		add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';

		proxy_pass http://chat;
	}
}

 

자 이제 Server에서 Pm2를 이용하여 여러 포트로 서버를 띄어 보자

// ecosystem.config.js

var ignoreWatch = [
  'node_modules',
  'logs',
  'data',
  'dist',
  'conf'
]
// Options reference: https://pm2.keymetrics.io/docs/usage/application-declaration/
module.exports = {
  apps : [
  {
    name: 'server-1',
    script: 'dist/main.js',
    autorestart: true,
    watch: true,
    ignore_watch: ignoreWatch,
    max_memory_restart: '1500M',
    env: {
      'PORT': '8000'
    }
  },
  {
    name: 'server-2',
    script: 'dist/main.js',
    autorestart: true,
    watch: true,
    ignore_watch: ignoreWatch,
    max_memory_restart: '1500M',
    env: {
      'PORT': '8001'
    }
  }
  ]
};

이제 WebServer(Vue), Nginx, WAS(ChatServer), Redis 세팅이 끝났다.

User5 8001 port 접속
test폰 user 8000port 접속

 

엥 pc화면을 캡처를 못했다..

-.. ip_hash방식으로 하여 해당 ip는 반복적으로 같은 서버에 입장하게 된다. 때문에 다른 port로 접속하는 Ip를 찾는라 여러 기기를 이용하여 접속시도하였다.. 근데 pc 화면 캡처를 깜빡했네..

 

최종 아키텍쳐

'프로젝트' 카테고리의 다른 글

[Node] Chat Server 부하줄이기(분산처리)[1]  (2) 2022.02.07
Node js profiling  (0) 2021.12.07
heartalk stress test  (0) 2021.12.04
heartalk 개발  (0) 2021.11.19
NestJS 초기 명령어(CLI) & 기초  (0) 2021.11.06
Comments