Использование 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.