2016-11-08 1 views
10

배경 : 나는 IIS에 저장된 웹 사이트를 사용하는 Microsoft 세계에서 왔습니다. 경험은 단편화로 인한 기묘한 문제를 제거하기 위해 하루에 한 번 응용 프로그램 풀을 재활용하도록 가르쳐 줬습니다. 기본적으로 응용 프로그램 풀을 재활용하는 것은 전체 IIS를 다시 시작하지 않고 응용 프로그램을 다시 시작하는 것을 의미합니다. 또한 마이크로 소프트가 어떻게 분열을 줄 였는지 설명하는 강연을 보았습니다. 넷 4.5.Node.js 및 조각화

이제 Node.js 응용 프로그램을 프로덕션 환경에 배포하고 있으며 항상 완벽하게 작동하는지 확인해야합니다. 원래 앱을 하루에 한 번씩 다시 시작하도록 생각했습니다. 그런 다음 Node.js의 조각화 문제에 대한 단서를 찾기 위해 조사를했습니다.

하는은 "어떤 메모리 조각화 V8은"정지 - 세계를 사용하지 을 빠른 객체 할당, 짧은 가비지 콜렉션 일시 정지 및 을 보장하기 위해 : 내가 찾은 유일한 것은 an article describing GC in V8에서 단락의 스크랩입니다 세대 간, 정확한 가비지 컬렉터. 내 응용 프로그램에 대한 다시 시작 메커니즘을 구축 포기하지만, 문제가 없으면 다른 한편으로는 내가 어떤 일을하고 싶지 않아위한

이 문장은 정말 충분하지 않습니다.

그래서 내 으론입니다

가 아니면 분열을 방지하기 위해 모든 이제 다음 내 응용 프로그램을 다시 시작하지 말아야 하는가?

답변

11

메모리 소비가 실제로 문제가된다는 것을 알기 전에 서버를 다시 시작하는 것은 조기 최적화입니다. 따라서, 나는 그것이 실제로 문제가된다는 것을 알기 전까지는 그렇게하지 말아야한다고 생각합니다. 메모리 소비와 비교하여 최적화 할 더 중요한 문제를 발견하게 될 것입니다. 당신은 서버를 다시 시작해야하는 경우

내가 다음을 수행하는 것이 좋습니다, 파악하려면

  1. 이의 모니터 성능을하자 https://newrelic.com/ 같은 일부 모니터링 도구를 설정합니다.
  2. 지속적으로 메모리를 모니터링하십시오. 소비되는 메모리의 양이 꾸준히 증가했는지 또는 수평으로 떨어지는지 확인하십시오.
  3. 조치를 취하기 전에 허용 가능한 임계 값을 결정하십시오. 예를 들어 앱이 시스템 메모리의 60 %를 소비하면 서버를 다시 시작하고 다시 시작 간격을 결정해야합니다.
  4. 서버를 다시 시작하는 동안 "가동 중지 시간"이 발생해도 괜찮은지 결정하십시오. 가동 중지 시간을 원하지 않으면 트래픽을 유도하기 위해 프록시 계층을 구축해야 할 수 있습니다.

일반적으로 모든 동적 가비지 수집 언어에 대해 서버를 다시 시작하는 것이 좋습니다. 이러한 유형의 대규모 응용 프로그램에서는 상당히 일반적입니다. 코드베이스의 어딘가에있는 작은 실수 나 의존하는 라이브러리 중 하나가 메모리를 누설하는 것은 거의 불가피합니다. 누설을 고칠 수 있더라도 결국에는 또 다른 누출이 발생합니다. 이것은 팀을 좌절시킬 수 있으며, 기본적으로 서버 재시작 정책과 응용 프로그램의 메모리 소비와 관련하여 허용되는 정의가됩니다.

+1

이 분명하면 모니터링 기능이있는 서버를 다시 시작하는 것이 좋습니다. 나는 그들에게 왜 이런 이슈가 있는지에 대한 어떠한 종류의 정보도없이 문제가있는 앱을 다시 시작하는 고위직에 대한 나쁜 경험을 가지고있어서 추측 게임을 유지합니다. –

+1

@CorvusCrypto 먼저 모니터링하는 것이 좋습니다. 그런 다음 서버를 다시 시작해야하는지 결정합니다. – Parris

+0

정교한 대답에 감사드립니다. 두 가지 질문이 있습니다. 1. 관리되는 코드 언어로 메모리 누수가 발생할 수있는 방법은 무엇입니까? Afaik는 더 이상 사용하지 않는 메모리 할당을 해제하지 않으면 메모리 누수가 발생합니다. 하지만 관리 코드 응용 프로그램에서는 더 이상 참조가없는 모든 객체가 GC에 의해 해제됩니다. (두 번째 질문은 다음 댓글에 있습니다). – Alon

3

나는 @Parris에 동의합니다. 아마 재시작 정책이 실제로 필요한지 여부를 알아 내야합니다. 나는 오후 2시 docs here을 사용하는 것이 좋습니다. keymetrics에 등록하고 싶지 않더라도, 꽤 좋은 작은 프로세스 관리자와 실제 설치가 빠릅니다.명령 줄에서 메모리 사용량 보고서를 가져올 수 있습니다. 이런 모습입니다.

pm2 output

또한

위 같은 클러스터 모드로 시작하면, 당신은 pm2 restart my_app를 호출 할 수 있으며, 첫 번째는 아마 위로 다시 마지막 오프라인을 촬영하기 전에 될 것입니다 (이것은 추가 혜택, 진짜 이유 8 개의 프로세스를 갖는 것은 모든 8 개의 코어를 활용하는 것입니다. 가동 중지 시간에 대해 굳게 고집한다면, ID에 따라 1 씩 다시 시작할 수 있습니다.

2

@Parris와 동의합니다. 조기 최적화와 같습니다. 또한 재시작은 근본적인 문제에 대한 해결책이 아니며, 증상을 치료하는 것입니다.

메모리 오류가 노드 응용 프로그램의 일반적인 문제인 경우, 처음에는이 조각화가 프로그램에서 발생하는 이유에 대한 생각이 가치 있다고 생각합니다. 프로그램이 오랜 기간 실행 된 후 메모리 오류가 발생하는 이유를 이해하고 문제의 근원을 해결하기 위해 프로그램의 아키텍처를 리팩터링하는 것은 증상을 해결하는 것보다 나은 해결책입니다.

나는 두 가지가 당신에게 유익하다고 믿습니다.

  1. immutable objects가 많은 도움이 될 것입니다, 그들은 변경할 객체를 사용하는 것보다 더 많은 예측, 그리고 프로젝트가 라이브되었습니다 시간의 길이에 의해 영향을받지 않습니다. 또한 불변 개체는 메모리의 읽기 전용 블록이기 때문에 서버가 개체를 저장하는 메모리 블록을 읽거나 쓸지 여부를 결정하는 리소스를 소비해야하는 변경 가능한 개체보다 빠릅니다. 나는 현재 IMMUTABLE이라는 라이브러리를 사용하며 잘 작동한다. Deep Freeze과 같은 다른 제품도 있지만 사용하지는 않았습니다.

  2. 응용 프로그램의 프로세스를 올바르게 관리하십시오. 메모리 누수가이 문제의 두 번째 큰 원인입니다. 다시 말하지만, 이것은 응용 프로그램이 어떻게 구조화되고 사용자 이벤트가 처리되는지, 클라이언트가 heap에서 적절하게 제거 된 프로세스가 클라이언트에서 사용되고 있지 않은지 확인한 다음 heap이 유지되는지 확인함으로써 해결됩니다 모든 메모리가 소모되어 응용 프로그램이 손상 될 때까지 계속 증가합니다 (아래 그림에서 V8의 메모리 구성표를 참조하십시오. heap의 위치를 ​​참조하십시오). Node는 C++ 프로그램이며 Google의 V8 및 Javascript에서 제어합니다.

V8 memory Scheme

당신은 Node.js를의 process.memoryUsage() 모니터링하는 메모리 사용을 사용할 수 있습니다. 힙을 관리하는 방법을 식별 할 때 V8은 두 가지 솔루션을 제공합니다. 하나는 Scavenge입니다.이 기능은 매우 빠르지 만 불완전합니다. 다른 하나는 Mark-Sweep입니다. Mark-Sweep은 속도가 느리고 참조되지 않은 메모리를 모두 비 웁니다.

, 당신의 힙을 관리하는 방법에 대한 자세한 정보를 원하시면 this 블로그 게시물을 참조 Node.js를

그래서 당신의 구현에 책임있는 접근이 열려 프로세스에 가까운 눈을 유지하는 것입니다 실행 V8에 메모리를 관리 heap에 대한 깊은 이해와 참조되지 않은 메모리 블록을 해제하는 방법에 대해 설명합니다. 이를 염두에두고 프로젝트를 만들면 프로젝트가 훨씬 더 확장 가능해진다.