[node.js] 프로덕션에서 MemoryStore 사용

오늘 저는 처음으로 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.

단일 프로세스 만 실행하면되는데 대신 무엇을 사용해야합니까? 빠른 액세스를 위해 내 세션이 RAM에 상주하기를 원합니다. 또한 단순히 Node 앱을 종료하여 모든 세션을 삭제할 수 있기를 원합니다.

이 간단한 작업을 위해 Redis, MongoDB 또는 다른 데이터베이스를 설치하는 것은 과잉으로 보입니다. 또한 실제로 사용해서는 안되는 MemoryStore가 Node에 포함 된 이유를 이해할 수 없습니다.



답변

MemoryStore는 (빠른) 개발 모드 전용입니다. 앱이 다시 시작되면 (프로세스가 종료 됨) 모든 세션 데이터 (해당 프로세스의 메모리에있는)가 손실되기 때문입니다.

데이터베이스를 사용하지 않으려면 대신 암호화 된 쿠키 저장소를 사용하십시오.

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


답변

좋습니다. Connect 개발자와 이야기를 나눈 후 더 많은 정보를 얻었습니다. 여기에서 메모리 누수로 간주되는 두 가지가 있습니다.

  1. 최근 버전에서 이미 수정 된 JSON 구문 분석 문제
  2. 사용자가 세션에 액세스하지 않는 경우 만료 된 세션이 정리되지 않는다는 사실 (즉, 유일한 정리는 온 액세스입니다)

해결책은 다소 간단 해 보입니다. 적어도 이것이 제가 할 계획입니다. setInterval을 사용하여 만료 된 세션을 주기적으로 정리합니다. MemoryStore는 목록을 얻기 위해 all ()을 제공하고, get ()을 사용하여 강제로 읽기를 수행하여 만료시킬 수 있습니다. 의사 코드 :

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

이제 setInterval ()을 통해 주기적으로 sessionCleanup을 호출하면 만료 된 세션에 대한 자동 가비지 콜렉션이 있습니다. 더 이상 메모리 누수가 없습니다.


답변

그래서 이것에 대한 대답은 [edit : was] 거의 해킹이며, 다른 사람들은 제가 생각하기에 과잉이라고 생각되는 데이터베이스를 사용하도록 권장하고 있습니다.

나는 같은 문제가 있었고 express-session을 cookie-session으로 바 꾸었습니다 .

이렇게하려면 간단히 설치하십시오 cookie-session.

npm install cookie-session

그런 다음에서 사용중인 app.js위치를 찾아 .express-sessioncookie-session

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

당신은 다른 것들을 바꿔야 할지도 모릅니다. 왜냐하면 저는 간단한 스왑 아웃-밥-당신-삼촌-해를 끼치 지 않는 일이었습니다.


답변

이 모듈은 메모리 누수 문제를 처리하도록 설계되었습니다.
https://www.npmjs.com/package/session-memory-store

받아 들여진 대답은 괜찮을 수 있습니다. 그러나이 질문은 검색 결과 목록에서 상위에 나타나기 때문에 다른 사람에게 도움이되는 경우에이를 포함 할 것이라고 생각했습니다.


답변

웹에 대한 합의는 실제로 DB를 사용하는 것이 올바른 방법이라고 생각하지만, 만약 당신이 그것을 원하지 않는다면 경고를 억제하십시오. 경고는 법이 아닙니다.

그러나 당신과 나는 메모리 누수가 실제 문제라는 데 동의하기 때문에 redis가 과잉이라고 말하는 것을 정당화하기는 어렵습니다.

또한 실제로 사용해서는 안되는 MemoryStore가 Node에 포함되는 이유를 이해하지 못합니다.

그것은 대단한 요점입니다.하지만 노드 iself는 최근에야 생산 준비가 된 것 입니다. 어떤 사람들은 그것이 전혀 없다는 개념에 동의하지 않을 것입니다.


답변

대안은 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 } )

이 필드를 확인하는 Mongo 백그라운드 스레드는 60 초마다 실행됩니다. 따라서 문서를 제거하는시기는 정확하지 않습니다.


답변

Redis에 문제가있는 경우 다음을 시도해보십시오. 도움이되기를 바랍니다.

DEV 및 PROD에 Redis를 사용하고 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 또는 다른 데이터베이스를 설치하는 것은 과잉으로 보입니다.