Подтвердить что ты не робот

Что такое хороший магазин сеансов для однозадачного приложения Node.js?

Я использую Node Express w/Connect middleware. Магазин сеансов памяти не подходит для производства:

Warning: connection.session() MemoryStore is not designed for a production environment, as it will leak memory, and obviously only work within a single process.

Для больших развертываний монго или redis имеет смысл.

Но какое хорошее решение для приложения с одним хостом в производстве?

4b9b3361

Ответ 1

Провел день, изучая это. Вот варианты, которые я обнаружил. Запросы/секунда выполняются через ab -n 100000 -c 1 http://127.0.0.1:9778/ на моей локальной машине.

  • нет сеансов - быстрый (438 req/sec)
  • cookieSession: не требует внешней службы, незначительное влияние скорости (311 req/sec) - быстрее, сеансы истекают с файлом cookie (настраивается maxAge)
  • connect-redis: требуется сервер redis, большое влияние скорости (4 req/sec с redis2go и redisgreen) - быстрее, чем mongo, сеансы будут удалены через некоторое время (настроено на ttl)
  • connect-mongo - требуется сервер mongodb, большое влияние скорости (2 req/sec с mongohq) - медленнее, чем redis, требуется ручная clear_interval для установки сеансов очистки

Вот файл coffeescript, который я использовал для cookieSession:

server.use express.cookieSession({
    secret: appConfig.site.salt
    cookie: maxAge: 1000*60*60
})

Вот код, который я использую для redis:

RedisSessionStore ?= require('connect-redis')(express)
redisSessionStore ?= new RedisSessionStore(
    host: appConfig.databaseRedis.host
    port: appConfig.databaseRedis.port
    db: appConfig.databaseRedis.username
    pass: appConfig.databaseRedis.password
    no_ready_check: true
    ttl: 60*60  # hour
)
server.use express.session({
    secret: appConfig.site.salt
    cookie: maxAge: 1000*60*60
    store: redisSessionStore
})

Вот мой кофейник для монго:

server.use express.session({
    secret: appConfig.site.salt
    cookie:
        maxAge: 100*60*60
    store: new MongoSessionStore({
        db: appConfig.database.name
        host: appConfig.database.host
        port: appConfig.database.port
        username: appConfig.database.username
        password: appConfig.database.password
        auto_reconnect: appConfig.database.serverOptions.auto_reconnect
        clear_interval: 60*60  # hour
    })
})

Теперь, конечно, удаленные базы данных redis и mongo будут медленнее, чем их локальные эквиваленты. Я просто не мог заставить работать локальные эквиваленты, особенно учитывая, что время установки и обслуживания для меня было намного больше, чем то, что я хотел инвестировать по сравнению с удаленными альтернативными решениями, что я считаю правдивым для других, поэтому почему эти удаленные удаленные службы баз данных существуют в первую очередь!

Для локальных баз данных benhmarks см. ответ @Mustafa.

Счастливый для кого-то отредактируйте этот ответ, чтобы добавить в таблицу свои локальные базовые тесты базы данных.

Ответ 2

Поскольку принятый ответ связан только с удаленными хостами, очевидно, что он будет всегда медленнее, чем localhost. Даже если это следующий компьютер в вашем доме, для чтения с этого компьютера потребуется миллисекунды, но локальная память занимает всего лишь наносекунды. Вы должны сравнить их с помощью локально установленных серверов.

Вот мои результаты от моего локального компьютера: вы видите, redis почти так же быстро, как и в памяти, при высокой нагрузке. Вы можете клонировать мое репо, чтобы эти тестовые коды были доступны: https://github.com/mustafaakin/express-session-store-benchmark

Concurrency: 1
none       4484.86 [#/sec] 
memory     2144.15 [#/sec] 
redis      1891.96 [#/sec] 
mongo      710.85 [#/sec] 
Concurrency: 10
none       5737.21 [#/sec] 
memory     3336.45 [#/sec] 
redis      3164.84 [#/sec] 
mongo      1783.65 [#/sec] 
Concurrency: 100
none       5500.41 [#/sec] 
memory     3274.33 [#/sec] 
redis      3269.49 [#/sec] 
mongo      2416.72 [#/sec] 
Concurrency: 500
none       5008.14 [#/sec] 
memory     3137.93 [#/sec] 
redis      3122.37 [#/sec] 
mongo      2258.21 [#/sec] 

Используемые страницы сеанса - очень простые страницы;

app.get("/", function(req,res){
    if ( req.session && req.session.no){
        req.session.no = req.session.no + 1;
    } else {
        req.session.no = 1;
    }
    res.send("No: " + req.session.no);
});

Redis сохранить конфигурацию:

app.use(express.session({
    store: new RedisStore({
        host: 'localhost',
        port: 6379,
        db: 2,
        }),
    secret: 'hello'
}));

Конфигурация магазина Mongo:

app.use(express.cookieParser());
app.use(express.session({
    store: new MongoStore({
        url: 'mongodb://localhost/test-session'
    }),
    secret: 'hello'
}));

Ответ 3

Еще один хороший вариант - memcached. Состояние сеанса теряется, если memcached перезапускается, но практически нет причин для этого. Вы можете оставить кеш все время, даже когда вы перезагружаете сервер приложений. Доступ к данным сеанса практически мгновенен, и memcached будет работать счастливо с любым (соответствующим) объемом памяти, которую вы ему даете. И я никогда не видел memcached crash (в Linux).

https://github.com/elbart/node-memcache

Что нужно помнить о memcached вообще:

  • Никогда не используйте пробелы в ключах кеша
  • Имейте в виду, что существует максимальная длина ключа кеша, включая любой префикс пространства имен, который вы могли бы использовать. Если ваш кеш-ключ слишком длинный, используйте вместо него хэш-адрес из 1-way.

Ни одна из этих проблем не должна быть проблемой для хранения сеанса; просто с генерализованным кэшированием.

Ответ 4

Я пошел с хранилищем сеансов MongoDB, используя connect-mongo.

Установите с помощью npm install connect-mongo и замените существующий MemoryStore на

app.use(express.session({ store: new MongoStore({ db: 'some-database' }) }));

Автоматически управляет сессией сеансов базы данных.

Ответ 5

Я бы по-прежнему использовал Redis даже для локального развития. Это полезно, потому что он хранит сеанс, даже когда вы перезапускаете приложение Node, сохраняя свой сеанс браузера. Redis по умолчанию сохраняет сеанс в памяти, так же как и в хранилище памяти для подключения прост в настройке (я просто запускаю его на экране наряду с моими приложениями Node) может поддерживать несколько приложений, если вы просто используете в настройках другую базу данных или значение сеанса.

Ответ 6

Я просто изучаю node.js самостоятельно, но если вам не нужно хранить много информации в объекте сеанса, вы можете изучить безопасные файлы cookie.

Защищенные файлы cookie хранят информацию о сеансе как часть файла cookie, который браузер хранит и пересылает с каждым запросом. Они зашифровываются, чтобы пользователь не мог подделать действительный файл cookie.

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

Недостатком является то, что вы можете хранить до 4 КБ и отправлять данные на сервер по каждому запросу (но у вас может быть несколько фиктивных доменов, указывающих на ваш сервер, чтобы вы не налагали этот багаж на общедоступные статические контент, например).

Поиск в Интернете кажется, что есть как минимум две реализации безопасных файлов cookie для node.js. Не уверен, что производство готово, но:

https://github.com/benadida/node-client-sessions/blob/master/lib/client-sessions.js

https://github.com/caolan/cookie-sessions