2016-01-19 7 views
11

ノード/エクスプレス・サーバーを実行する際に問題があります。 サーバは非常にうまく動作しますが、時間とともに多くのメモリを使用します。 約70MBのメモリ使用量で開始します。しかし、それはすべての要求に対して約2MBの追加が必要です。 そしてすぐに1.5GBのマークに当たってフリーズします。また、時間の経過とともにメモリを解放しません。 は、私は私のserver.jsのいずれかの一般的なエラーを持っていますか:Node.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')); 
    } 
}); 

答えて

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 
+0

。私は '/'ルートだけを要求している場合にもメモリリークが発生します。リダイレクトは必要ありません。 – ilse2005

+1

'server.get'ハンドラ全体を' res.send( 'handled' + req.url);に置き換えると、メモリにリークがありますか? –

+0

いいえ、これを行うと、プロセスは約140Mbで安定します。 – ilse2005

関連する問題