단일 호스트 Node.js 프로덕션 앱에 적합한 세션 저장소는 무엇입니까?
저는 Node 's Express w / Connect 미들웨어를 사용하고 있습니다. Connect의 메모리 세션 저장소가 프로덕션에 적합하지 않습니다.
Warning: connection.session() MemoryStore is not designed for a production environment, as it will leak memory, and obviously only work within a single process.
대규모 배포의 경우 mongo 또는 redis가 적합합니다.
그러나 프로덕션의 단일 호스트 앱에 적합한 솔루션은 무엇입니까?
이것을 조사하는 데 하루를 보냈습니다. 내가 발견 한 옵션은 다음과 같습니다. 초당 요청 ab -n 100000 -c 1 http://127.0.0.1:9778/
은 내 로컬 컴퓨터 를 통해 수행됩니다 .
- 세션 없음-빠름 (438 요청 / 초)
- cookieSession : 외부 서비스 필요 없음, 약간의 속도 영향 (311 요청 / 초)-가장 빠르며 세션은 쿠키와 함께 만료됩니다 (에서 사용자 지정
maxAge
) - connect-redis : redis 서버 필요, 큰 속도 영향 (redis2go 및 redisgreen의 경우 4 req / sec)-mongo보다 빠르며 잠시 후 세션이 삭제됩니다 (에서 사용자 지정
ttl
) - connect- mongo - mongodb 서버 필요, 큰 속도 영향 (mongohq의 경우 2 req / sec)-redis보다 느림,
clear_interval
세션 정리를 위해 수동 설정 필요
다음은 cookieSession에 사용한 커피 스크립트입니다.
server.use express.cookieSession({
secret: appConfig.site.salt
cookie: maxAge: 1000*60*60
})
redis에 사용하는 coffeescript는 다음과 같습니다.
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
})
mongo에 대한 내 커피 스크립트는 다음과 같습니다.
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 데이터베이스는 로컬 데이터베이스보다 느립니다. 특히 호스팅 된 원격 대안과 비교할 때 제가 투자하고자하는 것보다 훨씬 더 많은 설치 및 유지 관리 시간을 고려할 때 로컬 등가물이 작동하도록 할 수 없었습니다. 데이터베이스 서비스는 애초에 존재합니다!
로컬 데이터베이스 benhmark에 대해서는 @Mustafa 의 답변을 참조하십시오 .
누군가 가이 답변 을 편집 하여 로컬 데이터베이스 벤치 마크를 혼합에 추가하게되어 기쁩니다.
허용되는 대답은 원격 호스트에만 연결하기 때문에 항상 localhost보다 느릴 것입니다. 집에있는 다음 컴퓨터라도 해당 컴퓨터에서 읽는 데 밀리 초가 걸리지 만 로컬 메모리는 나노초 만 걸립니다. 로컬에 설치된 서버를 사용하여 비교해야합니다.
내 로컬 PC의 결과는 다음과 같습니다. 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'
}));
Another good option is memcached. The session states are lost if memcached is restarted, but there is virtually never any reason to do that. You can leave the cache running all the time even when you restart your app server. Access to the session data is virtually instantaneous and memcached will run happily with whatever (appropriate) amount of memory you give it. And I've never seen memcached crash (on Linux).
https://github.com/elbart/node-memcache
Things to keep in mind about memcached generally:
- Never have whitespace in your cache keys
- Be aware that there is a maximum cache key length, including any namespace prefix you might use. If your cache key is too long, use a 1-way hash of it instead.
Neither of these should be an issue with session storage; just with generalized caching.
I've gone with a MongoDB session store using connect-mongo.
Install with npm install connect-mongo
and replace the existing MemoryStore with
app.use(express.session({ store: new MongoStore({ db: 'some-database' }) }));
It manages the database side of sessions automatically.
I would still use Redis even for local development. This is helpful because it stores the session even when you restart the Node application, keeping your browser session logged in. Redis by default saves the session in memory, same as connect's memory store is simple to configure (I just run it in screen along with my node apps) can support multiple applications if you just use a different database or session value in the configuration.
I'm just exploring node.js myself, but if you don't need to store a lot of information in the session object -- you might want to explore secure cookies.
Secure cookies store session information as part of the cookie that the browser stores and forwards with each request. They are encrypted to prevent a user from forging a valid cookie.
The advantage is that you don't have to maintain state at the server -- this solution scales well and is simple to implement.
The disadvantage is that you can only store up to about 4KB and that data gets sent to the server on every request (But you can have multiple fictitious domains pointing at your server so you don't impose that baggage on publicly visible static content, for example).
Searching the web it seems like there are at least two implementations of secure cookies for node.js. Not sure how production ready they are, though:
https://github.com/benadida/node-client-sessions/blob/master/lib/client-sessions.js
https://github.com/caolan/cookie-sessions
I appreciate that this is an old question, but I came across it while searching for a solution to a similar problem. I had already decided to use memcached for session storage on Linux (with connect-memcached), but I also required the ability to run on Windows. I spent a while trying to find an in-memory session storage for a single-process node app. Redis and Memcached don't appear to be well-supported on Windows, and I didn't want the additional complexity of their installation.
I found session-memory-store in another Stack Overflow thread, which looks good but significantly increased the size of my dependencies.
Finally, I found memorystore in the documentation for express-session. I had missed it originally due to the similarly of its name to the default MemoryStore
, but it's exactly what I was looking for:
express-session full featured MemoryStore module without leaks!
I'm now using connect-memcached when running in a cluster (on Linux only), and memorystore when running a single process (on Linux or Windows).
I thought it worth posting this as another answer, just in case anyone else makes the mistake of missing memorystore as I initially did.
Check out my benchmarks at https://github.com/llambda/express-session-benchmarks showing comparisons of different session implementations.
'Programing' 카테고리의 다른 글
Moq + 단위 테스트-System.Reflection.TargetParameterCountException : 매개 변수 개수 불일치 (0) | 2020.11.11 |
---|---|
다중 선택 상자의 모든 선택된 값을 얻는 방법은 무엇입니까? (0) | 2020.11.10 |
Twig에서 어레이의 특정 키가 있는지 확인 (0) | 2020.11.10 |
mongo 그룹 쿼리 필드 유지 방법 (0) | 2020.11.10 |
iOS7의 UIAlertView addSubview (0) | 2020.11.10 |