Express?? 너무나 당연히 썼던 서버 프레임워크 - (4) 성능편, 운영영역

2020. 11. 9. 16:44Project-Review

최근 Docker 및 TypeScript를 조금씩 공부하느라 Express 성능편을 쓴다는 것을 까먹고 있었다. 의무적인 것은 아니지만 이 또한 지식이나 실력면에서 도움이 되기에 떠오르자마자 다시 글을 썼다.

이번 편은 (3) 성능편, 개발영역 다음에 오는 내용으로, 개발이 아닌, 배포 후의 성능을 올리기 위해 어떤 것을 살펴봐야 할 것인가를 알려주는 내용이다. 분명 나와 같이 배포 및 개발을 시작한지 얼마 안 된 사람에게는 매우 유익한 글이 될 것 같다.

 

우선, 운영에서 성능을 개선하기 위한 목차로 다음과 같이 보여준다.

 

  • NODE_ENV를 "production"으로 설정하자
  • 앱의 재시작을 자동으로 하게끔 설정하자
  • Cluster로 앱을 구동하자
  • Request 결과를 캐싱하자
  • 로드 밸런싱(load balancing)을 사용하자
  • 리버스 프록시(reverse proxy)를 사용하자.

 

(1) NODE_ENV를 "production"으로 설정하자

 

Express를 시작하면 NODE_ENV를 설정할 수 가 있는데, 말 그대로 Express의 환경을 설정하는 것이다. 이 환경은 production으로 설정되어 있을 수도 있는데, 확인을 해 보니, development인 것들도 있었다. 그런데 이게 무슨 차이가 있을까? 라는 생각이 있었고, production으로 설정한다면 다음과 같은 이점이 있다.

 

  • 배포와 개발은 필요한 영역이 각각 다르기 때문에 제공해 주는 것이 다르다. 개발로 설정하면 대게, 개발을 편리하게 해주기 위해 다양한 것들이 더 담겨져 있어 무거울 수 있다. ( 아래의 링크를 들어가보면 된다. )
  • 뷰 템플릿을 캐싱할 수 있다.
  • CSS 확장자로부터 발생한 CSS 파일을 캐싱할 수 있다.
  • 에러 메세지 발생을 줄일 수 있다.

그리고 production으로 바꾸는 것만으로, 3배의 성능 향상을 기대할 수 있다고 한다. 궁금한 사람은 아래의 링크를 가서 읽어보면 된다. 이 안에서도 다양한 정보를 제공해주는 링크들이 존재하는데, 시간이 없는 사람은 그것을 읽지 않아도 대략적으로 왜 그렇게 되는지 알 수 있으므로 굳이 볼 필요는 없을 것 같다.

 

www.dynatrace.com/news/blog/the-drastic-effects-of-omitting-node-env-in-your-express-js-applications/

 

The effects of omitting NODE_ENV in your Express.js apps

 

www.dynatrace.com

 

 

(2) 앱의 재시작을 자동으로 하게끔 설정하자

 

우리가 배포를 했다면, 최악의 경우는 꺼져있는 경우가 아닐까? 꺼지는 경우는 크게 두 가지로 앱이 충돌하는 경우와 서버가 충돌하는 경우로 나눌 수 있다고 한다. 어떤 경우든 재시작을 하여 계속된 실행을 할 수 있게끔 만들어야 사용에 불편함이 없으므로 다음과 같은 제안을 해주고 있다.

  • 프로세스 관리자를 사용하여 앱 (및 노드)이 충돌 할 때 다시 시작합니다.
  • OS에서 제공하는 init 시스템을 사용하여 OS가 충돌 할 때 프로세스 관리자를 다시 시작합니다. 프로세스 관리자없이 init 시스템을 사용할 수도 있습니다.

물론, 이 상황이 오기 전에 적절한 예외처리( 개발 영역 편을 참고하자 )가 있다면 좋다고 여기서도 설명한다. 그렇지만, 언제나 우리의 상상은 빈약하고, 예외란 녀석은 대단하다. 그래서 어떤 경우로 충돌이 일어날지 모른다. 

 

먼저 앱 충돌 시 해결할 수 있는 프로세스 관리자로 아래의 3개가 가장 유명하고, 많이 사용된다고 한다.

 

  • StrongLoop PM
  • PM2
  • Forever

그런데, Express에서는 StrongLoop PM을 밀어주고 있다. 이유는 다음과 같다.

 

  • 로컬에서 앱을 빌드하고 패키징 한 다음 프로덕션 시스템에 안전하게 배포
  • 어떤 이유든 앱이 다운되면 자동으로 다시 시작 :  init 시스템을 사용하여 StrongLoop PM을 운영체제 서비스로 설치하면 시스템이 다시 시작될 때 자동으로 다시 시작하므로, 프로세스와 클러스터를 영원히 유지할 수 있다.
  • 클러스터를 원격으로 관리
  • CPU 프로필 및 힙 스냅 샷을 확인하여 성능을 최적화하고 메모리 누수를 진단
  • 애플리케이션에 대한 성능 메트릭을 볼 수 있다.
  • Nginx로드 밸런서에 대한 통합 제어를 통해 여러 호스트로 쉽게 확장 할 수 있다.

필자는 프로젝트 때, Ec2에 PM2를 사용해서 Express를 실행시키는 방법을 사용했었다. 세가지 모두 아래의 링크를 통해 들어가면 간략한 설명과 함께 홈페이지 링크도 있으므로 필요한 사람은 들어가보자. 앞으로 사용을 StrongLoop를 해보는 것도 고려해봐야겠다. (이렇게까지 강력하게 얘기하는데는 이유가 있지 않을까??? )

 

expressjs.com/en/advanced/pm.html

 

Process managers for Express apps

Process managers for Express apps Warning: This information refers to third-party sites, products, or modules that are not maintained by the Expressjs team. Listing here does not constitute an endorsement or recommendation from the Expressjs project team.

expressjs.com

 

(4) Cluster를 사용하자

앞에서 ENV를 production으로 설정하는 것 만으로도 3배의 성능 향상을 기대할 수 있다고 했다. 이보다 더 확실한 성능 향상 방법으로 Clusting을 하라고 Express는 말하고 있다. 한 줄로 설명하자면 다음과 같은 말일 것이다.

 

 A cluster runs multiple instances of the app, ideally one instance on each CPU core, thereby distributing the load and tasks among the instances.

복수의 인스턴스를 앱에서 실행하는 것으로, 각각의 CPU core에서 인스턴스 하나씩 실행한다. 그러므로 업무량과 역할을 인스턴스 사이에 나눠줄 수 있다.

 

필자는 비전공자이므로, 이런 방식이 아닐까? 하며 생각해봤다. 우리가 컴퓨터를 살 때,  0코어 0쓰레드 이런 식으로 CPU에 설명되어 있지 않은가? 그러니까 '4코어 CPU라면 내가 앱을 실행할 때 필요한 것들을 4개까지 나누어서 실행할 수 있으니까 빨리빨리 처리할 수 있다' 라고 생각했다.

 

그렇다고 무조건 좋은 것이 아니다. 왜냐하면 업무를 core 각각이 맡는데, 이때 메모리를 공유하지 않아 상태를 유지할 수 없다. 그렇기 때문에 In-memory 방식인 Redis로 세션 관련 데이터나 상태를 저장해 사용하는 것을 권장한다. 

 

또한, 클러스터링을 사용하는 이유로, 장애의 격리를 얘기한다. 예를 들어, 앱에서 실행하는 업무를 4개로 나누어 실행하는데, 다른 3개에서는 문제가 없고, 한 개만 문제가 생긴다고 생각해보자. 클러스터링을 하지 않았다면 전체에 문제가 발생하지만, 나누어 놓았기 때문에 한 곳에서만 따로 에러가 생기는 것이다. 그리고 이런 프로세스 어디에서는 충돌이 일어날 수 있기 때문에, 로깅과 cluster.fork()를 사용하는 것을 권장하고 있다.

 

이런 것은 Node.JS에서 Document에 Clustering을 보면 나와있지만,(개인적으로 보는데 전공에 대한 지식이 부족해서 그런지 물음표만 계속 떴다...) node-pm이나 cluster-service 와 같은 자동으로 클러스터링 해주는 기능을 추천하고 있다.

 

(4) 캐싱, 로드밸런서, 역방향 프록시

 

이 부분에 대해서는 Express에서도 자세한 내용을 다루지 않고 있다. 그렇지만 ,이 세가지 모두 NginX로 해결할 수 있다. 그렇기 때문에 아래의 페이지에서 왼쪽의 Admin탭에서 Content Cache나 load balancer, Web Server - Nginx Reverse Proxy를 보면 알 수 있다.

필자도 자세한 부분을 다 아는 건 아니기에, 이를 보면서 공부해볼 계획이다.

 

docs.nginx.com/nginx/admin-guide/

 

NGINX Docs | Admin Guide

NGINX Plus Admin Guide

docs.nginx.com

 

이렇게 Express에 대해 더 자세한 공부를 할 수 있는 거리가 이렇게나 많다는 걸 깨달았다. 물론 1달이나 이런 짧은 시간에 마스터한다는건 생각도 안하고 있다. 그렇지만, 위의 내용들을 조금씩 공부하고, 블로깅 하다보면 내가 배포한 웹 및 앱의 성능도 좋아지지 않을까??