Nodejs的整个HTTP机制,问题儿童又来了,请教以便整理编程思维
Nodejs的整个HTTP机制,问题儿童又来了,请教以便整理编程思维
研究了Session的源码,之前对Node.js完全理解错误了,现在估摸着新的思路
Session源码里写得很清楚,Session自己的MemoryStore,不建议用于成品环境,只建议用于开发环境,至于为什么,下面详细道来.
我先只了解了MemoryStore的原理,如果用户在调用connect.session()的时候,option里没有store参数,session会把store指定为自己的MemoryStore,而这个MemoryStore其实就是在req这个对象下新建一个sessionStore的对象储存用户cookie数据,当用户不断增加时,sessionStore这个对象也会不断增大,所以Linkedln的建议是不要用内置的MemoryStore,这样浪费内存.
而Node.js是单线程的,在server.on(触发后?)req和res并不会销毁一直挂在内存里,我之前理解不了是因为忽略了单线程的特性,每一个用户进来都会新建一个req.session,如果用户的header有sid并能在sessionStore里找到,那么对应sid的内容就会合并到新的session里.如果两个用户同时并发进来,Node.js其实也是按循环事件的调用形式res.end给每个用户,而session中间件早已接管了res.end,使得每次结束连接之前都会把session的内容存进sessionStore.
这里需要注意的是,session不但接管了res.end,而且还在res.on注册了新的’header’事件,这个事件在调用<code>res._renderHeader()</code>的时候触发,用户无论res.write还是res.end都会调用<code>res._renderHeader()</code>,详细可参考Node.js源码.
so,下面的思路是错的! and,严重不建议使用内置的MemoryStore!
##错的:
因为水平低,源码看不懂,都是估摸出来的,所以希望各位指出错误
建立一个异步事件,就是createServer,一个用户连接进来后事件触发
触发后Node会为这个用户建立两个新的对象,分别是req和res
res.end后就是连接断开后,销毁为这个用户建立的两个对象
所以session都是req的属性,在连接断开后session也会跟着被销毁
所以当有N个用户并发进来的时候,就会建立N对req/res实例
望指正
Node.js 的整个 HTTP 机制
问题儿童又来了,请教以便整理编程思维
研究了 Session 的源码后,我发现我对 Node.js 的理解存在一些偏差。现在我试图整理出正确的思路。
Session 源码解析
首先,Session 源码里明确说明了,Session
自己的 MemoryStore
不建议在生产环境中使用,仅适用于开发环境。这是因为:
- 内存占用:如果用户在调用
connect.session()
时没有提供store
参数,session
会默认将store
指定为MemoryStore
。而MemoryStore
实际上是在req
对象下新建一个sessionStore
对象来存储用户 cookie 数据。随着用户数量增加,sessionStore
对象也会不断增大,这会导致内存浪费。
单线程特性与 Session 管理
Node.js 是单线程的,这意味着在 server.on('request')
触发后,req
和 res
并不会在连接断开后立即销毁,而是会一直挂在内存中。因此,每一个用户进来都会新建一个 req.session
。如果用户的 header 中包含 session id,并且该 session id 在 sessionStore
中能找到,对应的 session 内容会被合并到新的 session 中。
Session 中间件的工作机制
-
接管 res.end:
session
中间件接管了res.end
,确保每次结束连接前,都会将 session 的内容存入sessionStore
。 -
注册 header 事件:
session
还在res
上注册了一个新的'header'
事件,该事件在调用res._renderHeader()
时触发。无论用户调用res.write
还是res.end
,都会调用res._renderHeader()
。具体可以参考 Node.js 源码。
错误的理解
以下思路是错误的!并且强烈不建议使用内置的 MemoryStore
:
// 错误的代码示例
const http = require('http');
http.createServer((req, res) => {
// 建立一个异步事件,用户连接进来后事件触发
res.end(); // 连接断开后,销毁为这个用户建立的 req 和 res 对象
}).listen(3000);
正确的理解应该是:
- 创建服务器:使用
http.createServer
创建服务器。 - 处理请求:在请求处理函数中,每个用户连接进来都会新建一个
req
和res
对象。 - Session 管理:
session
中间件会在每次res.end
调用前将 session 内容存入sessionStore
。 - 内存管理:
req
和res
对象不会在连接断开后立即销毁,而是会一直挂在内存中。
总结
- 正确使用 Session:避免使用内置的
MemoryStore
,考虑使用数据库或其他持久化存储方案。 - 单线程特性:理解 Node.js 的单线程特性,合理管理内存资源。
希望以上内容能帮助你更好地理解和使用 Node.js 的 HTTP 机制。
对象像你这么理解也没问题. session倒是需要LZ去搞清楚一下其本质
如果是刚接触 Web 那不错了… Sesstion 应该是另外处理的, 不是链接断开就直接销毁的 大概是 maxAge: http://www.senchalabs.org/connect/middleware-session.html
如果去掉session的描述,其他的对否?
这样啊,连接断开后,res究竟有没销毁?session不是全局对象,就是说res一直没销毁?
这两天花时间把Session源码解构一下
你的理解中存在一些误区,让我帮你澄清一下Node.js中的HTTP机制以及Session的处理方式。
正确的理解:
-
单线程与事件驱动:
- Node.js 是基于事件驱动的单线程模型。这意味着所有请求都由同一个线程处理,但通过异步I/O操作不会阻塞其他请求的处理。
-
req 和 res 对象:
- 每个请求(request)和响应(response)都会创建
req
和res
对象。这些对象会在请求处理完成后释放,但它们并不是立即销毁的。相反,它们会被放到事件循环中等待下一个任务。
- 每个请求(request)和响应(response)都会创建
-
Session Store:
- 使用内置的
MemoryStore
存储Session数据确实不是一个好的生产环境选择,因为它会导致内存泄漏。更好的做法是使用如 Redis 这样的分布式存储系统。
- 使用内置的
示例代码
以下是一个简单的Express应用,展示了如何设置一个基于Redis的Session Store:
const express = require('express');
const session = require('express-session');
const RedisStore = require('connect-redis')(session);
const redis = require('redis');
const client = redis.createClient();
const app = express();
app.use(session({
store: new RedisStore({ client }),
secret: 'your_secret_key',
resave: false,
saveUninitialized: false
}));
app.get('/', (req, res) => {
if (req.session.views) {
req.session.views++;
res.setHeader('Content-Type', 'text/html');
res.write(`<p>views: ${req.session.views}</p>`);
} else {
req.session.views = 1;
res.write('<p>First visit</p>');
}
res.end();
});
app.listen(3000, () => {
console.log('App listening on port 3000');
});
在这个例子中:
- 我们使用了
express-session
和connect-redis
来配置Session Store。 - 每次用户访问根路径
/
,都会增加views
的计数。 - 通过
RedisStore
将Session数据保存到Redis服务器,而不是内存中。
总结
- 在Node.js中,虽然单线程处理所有的请求,但是通过事件驱动机制,多个请求可以并发执行。
- 使用内置的
MemoryStore
不适合生产环境,应考虑使用分布式存储系统如Redis。 - 每个请求和响应对象 (
req
和res
) 会在请求处理完毕后被释放,但不是立即销毁。
希望这能帮助你更好地理解Node.js的HTTP机制和Session管理。