我们使用一个看似简单的Node.js和Express服务器来提供我们的Angular.js项目,您可以在下面看到。其背后的想法是,如果服务器上存在客户端请求的文件,比如main.css,那么它将由express静态中间件返回。否则,我们假设它是一个Angular路由,比如/account,然后返回index.html文件,以便Angular接管。
附图显示了Heroku上的内存峰值,然后Heroku杀死服务器并重新启动。然后又再次出现峰值...
以下是服务器代码:
附图显示了Heroku上的内存峰值,然后Heroku杀死服务器并重新启动。然后又再次出现峰值...
以下是服务器代码:
var newrelic = require('newrelic')
, fs = require('fs')
, express = require('express')
, app = express()
, ENV = process.env.NODE_ENV || 'development'
, ENV_PROD = ENV == 'production'
, port = process.env.PORT || 8080;
console.log('ENV: ' + ENV);
// force ssl
app.use(function(req, res, next){
if (ENV_PROD) {
var protocol = req.get('x-forwarded-proto');
if (protocol != 'https') {
res.redirect(301, 'https://' + req.get('host') + req.url);
} else {
res.header('Strict-Transport-Security', 'max-age=31536000');
next();
}
} else {
next();
}
});
// set default headers
app.use(function(req, res, next){
var cache = ENV_PROD ? 3600 : 0;
res.set('Cache-Control', 'public, max-age='+cache);
res.set('Vary', 'Accept-Encoding');
next();
});
// static cache headers
app.use('/bower_components*', function(req, res, next){
res.set('Cache-Control', 'public, max-age=2419200');
next();
});
// set static directory
app.use(express.static(process.cwd() + '/build'));
// deeplink
app.use('/dl/*', function(req, res, next){
var path = req.baseUrl.replace('/dl/', '');
var url = 'https://www.deeplink.me/tablelist.com/' + path;
return res.redirect(url);
});
// file not found, route to index.html
app.use(function(req, res, next){
res.sendFile(process.cwd() + '/build/index.html');
});
// error handling
app.use(function(err, req, res, next){
res.status(404).send(err.message);
});
app.listen(port, function() {
console.log('Listening on port: ' + port);
});
module.exports = app;
有人看出可能导致这个问题的原因吗?使用最新版本的Node 0.10.31和Express 4.8.6。
更新:2014年8月29日
我对server.js文件进行了一些更改,删除了Express的sendFile和静态中间件。您可以看到下面的更新图表,它看起来确实更好,但使用的内存比我个人想要的多。更新后的服务器也在下面。
var newrelic = require('newrelic')
, fs = require('fs')
, express = require('express')
, app = express()
, ENV = process.env.NODE_ENV || 'development'
, ENV_PROD = ENV == 'production'
, SSL = ENV_PROD || process.env.SSL
, port = process.env.PORT || 8080
, config = require('../config')[ENV];
console.log('ENV: ' + ENV);
// force ssl
app.use(function(req, res, next){
if (SSL) {
var protocol = req.get('x-forwarded-proto');
if (protocol != 'https') {
res.redirect(301, 'https://' + req.get('host') + req.url);
} else {
res.header('Strict-Transport-Security', 'max-age=31536000');
next();
}
} else {
next();
}
});
// set default headers
app.use(function(req, res, next){
var cache = ENV == 'production' ? 3600 : 0;
res.set('Cache-Control', 'public, max-age='+cache);
res.set('Vary', 'Accept-Encoding');
next();
});
// static cache headers
app.use('/bower_components*', function(req, res, next){
res.set('Cache-Control', 'public, max-age=2419200');
next();
});
// add isFile to req
app.use(function(req, res, next){
var fileName = req.path.split('/').pop();
var isFile = fileName.split('.').length > 1;
req.isFile = isFile;
next();
});
// static
app.use(function(req, res, next){
if (req.isFile) {
var fileName = req.path.split('/').pop();
var path = process.cwd() + '/build' + req.path;
fs.readFile(path, function(err, data){
if (!data) return next();
res.contentType(fileName);
res.send(data);
});
} else {
next();
}
});
// file not found, route to index.html
app.use(function(req, res, next){
if (req.isFile) {
next(new Error('Not found'));
} else {
var path = process.cwd() + '/build/index.html';
fs.readFile(path, function(err, data){
if (err) return next(err);
res.contentType('index.html');
res.send(data);
});
}
});
// error handling
app.use(function(err, req, res, next){
res.status(404).send(err.message);
});
// start server
app.listen(port, function() {
console.log('Listening on port: ' + port);
});
module.exports = app;