Використання MemoryStore у виробництві


116

Сьогодні я вперше запустив свою програму Node.js в режимі "виробництва" і отримав це попередження:

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, коли його реально не використовувати?

Відповіді:


29

MemoryStore призначений лише для режиму швидкого розвитку, тому що якщо програма перезапуститься (процес відмирає), ви втратите всі дані сеансу (які залишилися в пам'яті цього процесу).

Якщо ви не хочете використовувати базу даних, використовуйте натомість зашифроване зберігання файлів cookie.

http://www.senchalabs.org/connect/cookieSession.html


80

Добре, після розмови з розробниками Connect я отримав більше інформації. Тут є дві речі, які вважаються витоками пам'яті:

  1. проблема з розбором JSON, яка вже виправлена ​​в останніх версіях
  2. той факт, що немає очищення минулих сеансів, якщо користувачі ніколи не отримують до них доступу (тобто єдина очистка - це під час доступу)

Рішення здається досить простим, принаймні, це те, що я планую зробити: використовувати 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
Я виявив, що ви також можете використовувати Redis і Mongo в якості підкладки і дозволити db очистити його. У випадку Монго ви можете встановити термін придатності, забезпечуючи індексацію.
— huggie

57
Це дійсно дурна річ, яку вони зробили, помістивши це повідомлення. Це на кшталт "ми могли зробити це правильно, але натомість ми просто зробимо це неправильно, і ти підеш грати в здогадки по мережах.
— катамфетамін

2
яке значення var sessionStore?
— Димитрій Копріва

4
sessionStore? Це глобальна змінна node.js? Якщо ні, то як я можу отримати посилання на сеанс Магазин у node.js?
— вітерме

1
@MilanBabuskov - це ти помістиш у свій app.jsфайл? Чи є можливість відкликати зворотний дзвінок всередині експрес-сесії? Трохи докладніше про те, як це зробити, було б чудово.
— Джонатан Бехтел

46

Тож прийнята відповідь на це - [редагувати: було] в значній мірі хак, а інші просто рекомендують використовувати базу даних, яка, на мою думку, є надмірною.

У мене була така ж проблема і просто замінили експрес-сесію cookie-сеансом .

Для цього просто встановіть 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...
}));

Можливо, вам доведеться змінити деякі інші речі, для мене це був простий своп-боб-ваш-дядько-не-шкідливий.


2
як ти це зробив.
— Сід

2
Це насправді відповідь, яка корисна. Дякую.
— smonff

5
Різниця полягає в тому, що вони cookie-sessionзберігають дані про клієнта, тоді як express-sessionзберігають дані на сервері.
— Джордж

11

Цей модуль був розроблений для вирішення проблеми витоку пам'яті. https://www.npmjs.com/package/session-memory-store

Прийнята відповідь може бути прекрасною. Однак, оскільки це питання виявляється високо в списку результатів пошуку, я подумав, що включу це у випадку, якщо він допоможе комусь іншому.


Я не пробував цього, але це виглядає як чудове виправлення ситуації (якщо з ОП все нормально із втраченими сесіями при перезапуску програми)
— stujo

З вашого посилання: "Настійно не рекомендуємо використовувати його у виробництві!". Питання йдеться про "Використання MemoryStore у виробництві".
— Дамієн

Правильно, але лише тому, що "ви не можете поділитися сеансом з іншими процесами чи іншими службами". Значить, є й інші більш практичні рішення. Але це вирішує проблему з витоком пам’яті, тому, якщо це не стосується вас, тоді це добре використовувати і вирішувати проблеми в питанні.
— Довєв Гефец

7

Я думаю, що в Інтернеті є консенсус, що правильним способом було б дійсно використовувати для цього БД, але якщо ви впевнені, ви не хочете цього робити, тоді придушуйте попередження - попередження не є законом.

Однак, оскільки ми з вами погоджуємось, що витік пам’яті - справжня проблема, важко виправдати, сказавши, що Redis є надмірним, оскільки це вирішить вашу проблему.

Я також не розумію, чому MemoryStore включений у Node, коли його реально не використовувати

це чудовий момент - але до цього я б сказав, що вузол iself лише нещодавно вже став готовим до виробництва . Дехто не погодився б із думкою, що це взагалі.


2
Придушення попередження не призведе до витоку пам'яті.
— Мілан Бабушков

Ось чому вони радять вам використовувати його у виробництві. тому альтернативою є використання альтернативного способу зберігання, чи не так?
— Крістіан

1
Напевно, мені просто не подобаються альтернативи, які я знайшов поки що. Я шукаю просту альтернативу JavaScript в пам'яті, а не систему баз даних. Я дійсно не розумію, чому вони не виправляють це. Я маю на увазі, наскільки важким може бути простий магазин пам'яті ... Я просто сподіваюся, що хтось це вже зробив, тому мені не доведеться заново вигадувати колесо.
— Мілан Бабушков

2
Я відчуваю ваш біль, але вузол зараз досить кровоточить. Сортоф приходить з територією
— Крістіан

7
MemoryStore не входить у Node, він включений у програму Express / Connect
— Мустафа

6

Альтернативою є використання Redis або Mongo в якості магазину. З Монго ви використовуєте модуль експрес-сесії-монго .

Є порада видалити несвіжі сеанси за допомогою параметра індексації:

var MongoStore = require('express-session-mongo');
app.use(express.session({ store: new MongoStore() }));

db.sessions.ensureIndex( { "lastAccess": 1 }, { expireAfterSeconds: 3600 } )

Оскільки несвіжі сесії видаляються самою базою даних, сеанс Express не потребує самостійної обробки очищення.

EDIT : Схоже, вам потрібно мати власне поле "lastAccess". Коли ви отримуєте доступ до нього, ви оновите це поле самостійно. Перевірте дані про термін дії документації MongoDB http://docs.mongodb.org/manual/tutorial/expire-data/

EDIT2 :

Тепер стає db.sessions.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

Фон-нитка Mongo для перевірки цього поля працює кожні 60 секунд. Тож терміни на видалення документа не точні.


2

Для тих, хто має проблеми з Redis, спробуйте наступне - сподівайтеся, це допоможе.

Я використовую Redis для DEV і PROD і націлюю Express v4. У Windows я використовую легкий набір інструментів MSOpenTech Redis v3.0, інакше я просто використовую Heroku 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 або іншу базу даних саме для цього простого завдання.


0

Якщо ви використовуєте використання OSX

brew install memcached

якщо Linux

apt install memcached

вирішити повідомлення сеансу, програма becose de може підключитися до служби 127.2.0.1.11212 memcache.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.