【问题标题】:Node.js server not releasing memoryNode.js 服务器不释放内存
【发布时间】:2016-04-24 08:50:11
【问题描述】:

我在运行节点/express 服务器时遇到问题。 服务器运行良好,但随着时间的推移会占用大量内存。 它从大约 70mb 的内存使用开始。但是对于每个请求,它需要多出大约 2mb。 很快它就达到了 1.5GB 大关并死机。随着时间的推移,它也不会释放任何内存。 我的 server.js 中是否有任何一般错误:

import 'babel/polyfill';
import _ from 'lodash';
import fs from 'fs';
import path from 'path';
import express from 'express';
import ReactDOM from 'react-dom/server';
import router from './router';
import Translator from './core/Translator.js';
import cookieParser from 'cookie-parser';
import StoreContainer from './utils/redux.js';
import { combineReducers } from 'redux';
import reducers from './reducers';
import {setAuthToken, removeAuthToken} from './utils/api';
import i18nLocation from './utils/i18nLocation.js';
import {api, setLangHeader, setProtocol} from './utils/api';
import {clearActiveApartment} from './actions/activeApartment.js';
import {clearCityInfo} from './actions/city.js';
import {setDevice} from './actions/appData.js';
import MobileDetect from 'mobile-detect';
import StaticConfiguration from './constants/StaticConfiguration.js';
import compression from 'compression';

const server = global.server = express();

server.set('port', (process.env.PORT || 5000));
server.use(cookieParser());
server.use(compression());
server.use(express.static(path.join(__dirname, 'public')));

// The top-level React component + HTML template for it
const templateFile = path.join(__dirname, 'templates/index.html');
const template = _.template(fs.readFileSync(templateFile, 'utf8'));

server.get(/^[^.]+$/, async (req, res, next) => {
  setProtocol(req.protocol);

  StoreContainer.emptyStore();
  let store = StoreContainer.store;

  let data = _.pick(req, ['baseUrl', 'ip', 'hostname', 'originalUrl',
    'path', 'protocol', 'headers']);
  api.saveRequest({
    data: data
  }).then(response => {

  }, _.noop);

  try {
    let statusCode = 200;
    let data = { title: '', description: '', css: '', body: '',
      country: '', city: '', lonlat: '', image: '/images/test.jpg', fbId: StaticConfiguration.fbKey,
      analytics: StaticConfiguration.analyticsKey};
    const css = [];
    let lang = Translator.resolveLangForRequest(req);

    lang = 'de';  // TODO: remove this line to allow other langs
    Translator.initialize({descriptor: lang});
    setLangHeader(lang);

    if (req.cookies && req.cookies['wg-token']) {
      setAuthToken(req.cookies['wg-token']);
    }

    const context = {
      onInsertCss: value => css.push(value),
      onSetTitle: value => data.title = value,
      onSetMeta: (key, value) => data[key] = value,
      onPageNotFound: () => statusCode = 404
    };

    await router.dispatch({ path: req.path, context }, (state, component) => {

      // redirect to another page
      if (state.redirect) {
        res.redirect(state.redirect);
      }

      data.body = ReactDOM.renderToString(component);
      data.css = css.join('');
      data.langFile = Translator.resolveLangFile(lang, req);
      data.initialState = JSON.stringify(store.getState());
      data.langCode = lang;
    });

    removeAuthToken();

    let html = template(data);
    res.status(statusCode).send(html);
  } catch (err) {
    next(err);
  }
});

//
// Launch the server
// -----------------------------------------------------------------------------

server.listen(server.get('port'), () => {
  if (process.send) {
    process.send('online');
  } else {
    console.log('The server is running at http://localhost:' + server.get('port'));
  }
});

【问题讨论】:

    标签: node.js express memory-leaks


    【解决方案1】:

    res.direct 可能存在问题。它可能应该被返回,以便调度函数不会继续运行data.body =data.css = 等。检查请求是否已被重定向也可能会有所帮助,因此调用 await router.dispatch() 之后的代码不会'如果您已经重定向,则不要运行。

    例如:

    let redirected = false
    await router.dispatch({ path: req.path, context }, (state, component) => {
    
      // redirect to another page
      if (state.redirect) {
        redirected = true;
        res.redirect(state.redirect);
        return; // stop data.body, data.css, etc from getting set
      }
    
      data.body = ReactDOM.renderToString(component);
      data.css = css.join('');
      data.langFile = Translator.resolveLangFile(lang, req);
      data.initialState = JSON.stringify(store.getState());
      data.langCode = lang;
    });
    
    if (redirected) return; // already redirected, don't send html
    

    【讨论】:

    • 不幸的是,这没有帮助。如果我只请求“/”路由,也会发生内存泄漏。并且不涉及重定向。
    • 为了确保问题出在您的处理程序内部,如果您将整个server.get 处理程序替换为res.send('handled ' + req.url);,您还会泄漏内存吗?
    • 不,如果我这样做,进程会稳定在大约 140Mb。
    猜你喜欢
    • 1970-01-01
    • 2014-12-27
    • 2018-10-22
    • 1970-01-01
    • 2017-06-29
    • 2016-05-24
    • 2011-06-30
    • 2016-09-14
    • 2015-08-19
    相关资源
    最近更新 更多