Использование MemoryStore в производстве
Сегодня я впервые запустил приложение Node.js в режиме "production" и получил это предупреждение:
Warning: connection.session() MemoryStore is not
designed for a production environment, as it will leak
memory, and obviously only work within a single process.
Мне нужно всего лишь запустить один процесс, но что я должен использовать вместо этого? Я хочу, чтобы мои сеансы находились в ОЗУ для быстрого доступа. Я также хочу, чтобы убрать все сеансы, просто отключив приложение Node.
Кажется, слишком сложно установить Redis, MongoDB или другую базу данных только для этой простой задачи. Я также не понимаю, почему MemoryStore включен в Node, когда он действительно не используется?
Ответы
Ответ 1
MemoryStore предназначен только для (быстрого) режима разработки, потому что, если ваше приложение перезагрузится (процесс умирает), вы потеряете все данные сеанса (которые находились в памяти этого процесса).
Если вы не хотите использовать базу данных, вместо этого используйте зашифрованное хранилище cookie.
http://www.senchalabs.org/connect/cookieSession.html
Ответ 2
Хорошо, поговорив с разработчиками Connect, я получил дополнительную информацию. Здесь есть две вещи:
- с обработкой JSON, которая уже исправлена в последних версиях
- тот факт, что очистка сеансов с истекшим сроком не выполняется, если пользователи никогда не обращаются к ним (т.е. единственная очистка включена)
Решение кажется довольно простым, по крайней мере, это то, что я планирую сделать: используйте setInterval для периодической очистки прошедших сеансов. MemoryStore предоставляет все() для получения списка, и мы можем использовать get() для принудительного чтения и, таким образом, истекшего. Псевдо-код:
function sessionCleanup() {
sessionStore.all(function(err, sessions) {
for (var i = 0; i < sessions.length; i++) {
sessionStore.get(sessions[i], function() {} );
}
});
}
Теперь просто вызовите sessionCleanup периодически через setInterval(), и у вас есть автоматическая сборка мусора для истекших сеансов. Больше утечек памяти.
Ответ 3
Таким образом, принятый ответ на этот вопрос: [edit: was] довольно сильно взломал, а другие просто рекомендуют использовать базу данных, которая, по моему мнению, является излишней.
У меня была та же проблема, и я просто заменил экспресс-сессию cookie-session.
Для этого просто установите cookie-session
:
npm install cookie-session
Затем в вашем app.js
найдите, где express-session
используется и заменяется на cookie-session
.
app.use(require('cookie-session')({
// Cookie config, take a look at the docs...
}));
Возможно, вам придется изменить какие-то другие вещи, поскольку для меня это был простой выбор из-за-bobs-your-uncle-no-harm-done.
Ответ 4
Этот модуль был разработан для решения проблемы утечки памяти.
https://www.npmjs.com/package/session-memory-store
Принятый ответ может быть прекрасным. Однако, поскольку этот вопрос появляется в списке результатов поиска, я решил, что включу это в случае, если это поможет кому-то еще.
Ответ 5
Я думаю, что консенсус вокруг Интернета заключается в том, что правильным способом было бы действительно использовать БД для этого, но если вы уверены, что не хотите этого делать, то подавляйте предупреждение - предупреждение не закон.
Однако, поскольку вы и я оба согласны с тем, что утечка памяти - настоящая проблема, трудно обосновать, что redis является излишним, поскольку это решит вашу проблему.
Я также не понимаю, почему MemoryStore включен в Node, когда он не следует использовать
Это замечательный момент, но я бы сказал, что Node iself только недавно стал готовым к производству. Некоторые люди не согласятся с понятием, что это вообще.
Ответ 6
Альтернативой является использование Redis или Mongo в качестве магазина. С Mongo вы используете модуль express-session-mongo.
Существует рекомендации по удалению устаревших сеансов с опцией индексирования:
var MongoStore = require('express-session-mongo');
app.use(express.session({ store: new MongoStore() }));
db.sessions.ensureIndex( { "lastAccess": 1 }, { expireAfterSeconds: 3600 } )
Поскольку устаревшие сеансы удаляются самой базой данных, сеансу Express не нужно самостоятельно обрабатывать очистку.
РЕДАКТИРОВАТЬ. Похоже, вам нужно иметь собственное поле "lastAccess". Когда вы обращаетесь к нему, вы сами обновляете это поле. Проверьте документацию MongoDB expire-data
http://docs.mongodb.org/manual/tutorial/expire-data/
EDIT2:
Теперь становится db.sessions.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )
Монгольский фоновый поток для проверки этого поля запускается каждые 60 секунд. Поэтому время для удаления документа не является точным.
Ответ 7
Для тех, кто испытывает проблемы с Redis, попробуйте следующее: надеюсь, что это поможет.
Я использую Redis для DEV и PROD и нацеливаю Express v4.
В Windows я использую легкий набор инструментов MSOpenTech Redis v3.0, в противном случае я просто использую Addon Helloku Redis Addon. Чтобы заставить его работать через Node, не было слишком сложно - пока что...
var session = require('express-session');
. . .
var RedisStore = require('connect-redis')(session);
var redisClient = require('redis').createClient(process.env.REDIS_URL);
var redisOptions = {
client: redisClient,
no_ready_check: true,
ttl: 600,
logErrors: true
};
var redisSessionStore = new RedisStore(redisOptions);
app.use(session({
store: redisSessionStore,
secret: 'Some.Long.Series.of.Crazy.Words.and.Jumbled.letter.etc',
resave: true,
saveUninitialized: true
}));
Удачи!
пс. Я только перечитываю исходный запрос и замечаю это - извините!
Кажется, слишком сложно установить Redis, MongoDB или другую базу данных только для этой простой задачи.
Ответ 8
Если вы используете OSX, используйте
brew install memcached
если Linux
apt install memcached
решить сообщение сеанса, приложение becose de может подключиться к сервису memcache 127.0.0.1:11211.