Üretimde MemoryStore'u kullanma


116

Bugün Node.js uygulamamı ilk kez "üretim" modunda çalıştırdım ve şu uyarıyı aldım:

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

Yalnızca tek bir işlem çalıştırmam gerekiyor, bunun yerine ne kullanmalıyım? Hızlı erişim için seanslarımın RAM'de kalmasını istiyorum. Ayrıca, Node uygulamasını kapatarak tüm oturumları iptal edebilmek istiyorum.

Redis, MongoDB veya başka bir veritabanını sadece bu basit görev için kurmak aşırı bir şey gibi görünüyor. Ayrıca MemoryStore'un gerçekten kullanılmaması gerektiği halde Node'a dahil edildiğini de anlamıyorum.

Yanıtlar:


29

MemoryStore yalnızca (hızlı) geliştirme modu içindir, çünkü uygulamanız yeniden başlarsa (işlem ölürse) tüm oturum verilerini (bu işlemin belleğinde bulunan) kaybedersiniz.

Bir veritabanı kullanmak istemiyorsanız, bunun yerine şifreli tanımlama bilgisi depolaması kullanın.

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


80

Tamam, Connect geliştiricileriyle konuştuktan sonra daha fazla bilgi aldım. Burada bellek sızıntısı olarak kabul edilen iki şey vardır:

  1. son sürümlerde zaten düzeltilmiş olan JSON ayrıştırma ile ilgili sorun
  2. kullanıcıların hiçbir zaman erişmemesi durumunda süresi dolan oturumların temizlenmesinin söz konusu olmadığı gerçeği (yani, tek temizleme erişim üzerindedir)

Çözüm oldukça basit görünüyor, en azından yapmayı planladığım şey bu: süresi dolan oturumları periyodik olarak temizlemek için setInterval kullanın. MemoryStore, listeyi almak için all () 'ı sağlar ve okumayı zorlamak ve böylece onları sona erdirmek için get () kullanabiliriz. Sözde kod:

function sessionCleanup() {
    sessionStore.all(function(err, sessions) {
        for (var i = 0; i < sessions.length; i++) {
            sessionStore.get(sessions[i], function() {} );
        }
    });
}

Şimdi setInterval () aracılığıyla seansCleanup'ı periyodik olarak çağırın ve süresi dolan oturumlar için otomatik çöp toplamaya sahip olursunuz. Artık bellek sızıntısı yok.


3
Redis ve Mongo'yu bir destek mağazası olarak da kullanabileceğinizi ve db'nin temizlemesini sağlayabileceğinizi keşfettim. Mongo söz konusu olduğunda, endekslemeyi sağlarken son kullanma tarihini de ayarlayabilirsiniz.
huggie

57
Bu mesajı oraya koyarak yaptıkları gerçekten aptalca bir şey. Sanki "düzeltebilirdik ama bunun yerine biz sadece yanlış yapacağız ve sen internette bir tahmin oyunu oynuyorsun. Ha ha! Kaybedenler!"
catamphetamine

2
var sessionStore'un değeri nedir?
Dimitri Kopriwa

4
sessionStore? Bu bir node.js genel değişkeni mi? Değilse, node.js'deki oturum Mağazası'na nasıl bir başvuru alabilirim?
windchime

1
@MilanBabuskov - bunu app.jsdosyanıza koyar mısınız ? Ekspres oturum içinde geri arama yapma seçeneği var mı? Bunun nasıl uygulanacağına dair biraz daha detay harika olurdu.
Jonathan Bechtel

46

Bu yüzden kabul edilen cevap [edit: was] hemen hemen bir hack'ti ve diğerleri sadece abartılı olduğunu düşündüğüm bir veritabanının kullanılmasını öneriyorlar.

Ben de aynı sorunu yaşadım ve express-session'ı cookie-session ile değiştirdim .

Bunu yapmak için şunu kurun cookie-session:

npm install cookie-session

Ardından app.js, nerede express-sessionkullanıldığını bulun ve ile değiştirin cookie-session.

app.use(require('cookie-session')({
    // Cookie config, take a look at the docs...
}));

Başka şeyleri değiştirmeniz gerekebilir, çünkü benim için basit bir takas-amcan-zarar-yapılmamış.


2
bunu nasıl yaptın.
Sid

2
Bu aslında faydalı bir cevaptır. Teşekkürler.
smonff

5
Aradaki fark, cookie-sessionverileri istemcide saklarken, express-sessionverileri sunucuda depolar.
George

11

Bu modül, bellek sızıntısı sorununu çözmek için tasarlanmıştır. https://www.npmjs.com/package/session-memory-store

Kabul edilen cevap iyi olabilir. Ancak, bu soru arama sonuçları listesinde üst sıralarda göründüğünden, başkalarına yardımcı olması durumunda bunu ekleyeceğimi düşündüm.


Bunu denemedim, ancak durum için harika bir düzeltme gibi görünüyor (OP, uygulamanın yeniden başlatılmasında kaybedilen oturumlarla
uygunsa

Bağlantınızdan: "Üretimde kullanmanız kesinlikle tavsiye edilmez!". Soru, "Üretimde MemoryStore'u kullanma" hakkındadır.
Damien

Doğru, ancak sadece "oturumu başkalarıyla veya başka bir hizmetle paylaşamayacağınız için." Yani, daha pratik başka çözümler de var. Ancak bu, bellek sızıntısı sorununu çözer, bu nedenle bunlar sizin için endişeler değilse, o zaman sorudaki endişeyi kullanıp gidermek sorun değildir.
Dovev Hefetz

7

Bence web etrafındaki fikir birliği, bunun için doğru yolun gerçekten bir DB kullanmak olacağıdır, ancak eminseniz, bunu yapmak istemezsiniz, o zaman uyarıyı bastırın - uyarı kanun değildir.

Bununla birlikte, ikimiz de bellek sızıntısının gerçek bir sorun olduğu konusunda hemfikir olduğumuz için, sorununuzu çözeceğinden, redis'in aşırı olduğunu söylemeyi haklı çıkarmak zordur.

Ayrıca MemoryStore'un gerçekten kullanılmaması gerektiğinde neden Node'a dahil edildiğini de anlamıyorum

bu harika bir nokta - ancak buna düğümün kendisinin ancak son zamanlarda üretime hazır hale geldiğini söyleyebilirim . Bazı insanlar bunun olduğu fikrine hiç katılmayacaktır.


2
Uyarıyı bastırmak bellek sızıntısını ortadan kaldırmaz.
Milan Babuškov

lol bu yüzden üretimde kullanmamanızı tavsiye ediyorlar. yani alternatif, alternatif bir depolama yöntemi kullanmak, değil mi?
Kristian

1
Sanırım şimdiye kadar bulduğum alternatifleri beğenmedim. Basit bir bellek içi javascript alternatifi arıyorum, veritabanı sistemi değil. Gerçekten neden düzeltmediklerini anlamıyorum. Demek istediğim, basit bir Hafıza Mağazası ne kadar zor olabilir ... Sadece birinin bunu çoktan yapmasını umuyorum, bu yüzden tekerleği yeniden icat etmem gerekmiyor.
Milan Babuškov

2
Acını hissediyorum, ama düğüm şu anda oldukça kanayan bir uçta .. bu bölge ile birlikte geliyor
Kristian

7
MemoryStore, Node'a dahil değildir, Express / Connect'e dahildir
Mustafa

6

Alternatif, mağaza olarak Redis veya Mongo kullanmaktır. Mongo ile ekspres oturum mongo modülünü kullanırsınız.

Bir indeksleme seçeneğiyle eski oturumları kaldırmanız için bir tavsiye var:

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

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

Eski oturumlar veritabanının kendisi tarafından kaldırıldığından, Express oturumunun temizliği tek başına halletmesi gerekmez.

DÜZENLEME : Görünüşe göre kendi "lastAccess" alanınız olması gerekiyor. Ona eriştiğinizde bu alanı kendiniz güncellersiniz. MongoDB belgelerinin sona erme verilerini kontrol edin http://docs.mongodb.org/manual/tutorial/expire-data/

DÜZENLEME2 :

Şimdi olur db.sessions.createIndex( { "createdAt": 1 }, { expireAfterSeconds: 3600 } )

Bu alanı kontrol etmek için Mongo arka plan iş parçacığı her 60 saniyede bir çalışır. Yani belgeyi kaldırma zamanlaması kesin değil.


2

Redis ile sorun yaşayanlar için aşağıdakileri deneyin - bunun yardımcı olacağını umuyoruz.

DEV ve PROD için Redis kullanıyorum ve Express v4'ü hedefliyorum. Windows'ta hafif MSOpenTech Redis v3.0 araç setini kullanıyorum, aksi takdirde sadece Heroku Redis Eklentisini kullanıyorum. Düğüm aracılığıyla çalışmasını sağlamak çok zor olmadı - şimdiye kadar ...

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 
}));

İyi şanslar!

ps. Sadece orijinal sorguyu yeniden okudum ve bunu fark ettim - üzgünüm!

Redis, MongoDB veya başka bir veritabanını sadece bu basit görev için kurmak aşırı bir şey gibi görünüyor.


0

OSX kullanıyorsanız

brew install memcached

eğer linux

apt install memcached

Oturum mesajını çöz, uygulama 127.0.0.1:11211 memcache hizmetine bağlanabilir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.