学了前端那么久,各种框架的运行都离不开Node,于是便对Node产生了浓厚的兴趣,之前还是对后端有所了解的,对于Php还是多少了解过,自从接触到node异步式I/O便发现跟其他后台语言不太一样,便对Node 的兴趣更加强烈,好吧,废话不多说,先来一段Node与php的对比吧。

一.http服务器
从上图可知,我们node跟php运行是不太一样的,对于php,我需要自己配置如apache,ngix之类服务器,再配合本身php语言的解析再执行从客户端请求到后端解析再反馈的过程,而Node本身含有server,无需配置,轻松完成请求。
const http=require('http');
http.createServer((req,res)=>{
//响应头状态和响应头内容格式
res.writeHead(200,{'Context-Type':'text-html'});
//Respose内容
res.write('<h1>Node.js</h1>');
res.end('<p>hello world</p>');
}).listen(3000);
console.log('http server is listening at port 3000');
http中如此强大,其中包含居多api,以至于我们能调用createServer,其他api都有哪些呢
本人console.log以下内容:(METHODS,STATUS_CODES,Agent,server,server response,
createServer,get,request,maxHeaderSize等api其中用createServer就创建了一个http服务器)
http { _connectionListener: [Function: connectionListener],
METHODS:
[ 'ACL',
'BIND',
'CHECKOUT',
'CONNECT',
'COPY',
'DELETE',
'GET',
'HEAD',
'LINK',
'LOCK',
'M-SEARCH',
'MERGE',
'MKACTIVITY',
'MKCALENDAR',
'MKCOL',
'MOVE',
'NOTIFY',
'OPTIONS',
'PATCH',
'POST',
'PROPFIND',
'PROPPATCH',
'PURGE',
'PUT',
'REBIND',
'REPORT',
'SEARCH',
'SOURCE',
'SUBSCRIBE',
'TRACE',
'UNBIND',
'UNLINK',
'UNLOCK',
'UNSUBSCRIBE' ],
STATUS_CODES:
{ '100': 'Continue',
'101': 'Switching Protocols',
'102': 'Processing',
'103': 'Early Hints',
'200': 'OK',
'201': 'Created',
'202': 'Accepted',
'203': 'Non-Authoritative Information',
'204': 'No Content',
'205': 'Reset Content',
'206': 'Partial Content',
'207': 'Multi-Status',
'208': 'Already Reported',
'226': 'IM Used',
'300': 'Multiple Choices',
'301': 'Moved Permanently',
'302': 'Found',
'303': 'See Other',
'304': 'Not Modified',
'305': 'Use Proxy',
'307': 'Temporary Redirect',
'308': 'Permanent Redirect',
'400': 'Bad Request',
'401': 'Unauthorized',
'402': 'Payment Required',
'403': 'Forbidden',
'404': 'Not Found',
'405': 'Method Not Allowed',
'406': 'Not Acceptable',
'407': 'Proxy Authentication Required',
'408': 'Request Timeout',
'409': 'Conflict',
'410': 'Gone',
'411': 'Length Required',
'412': 'Precondition Failed',
'413': 'Payload Too Large',
'414': 'URI Too Long',
'415': 'Unsupported Media Type',
'416': 'Range Not Satisfiable',
'417': 'Expectation Failed',
'418': 'I\'m a Teapot',
'421': 'Misdirected Request',
'422': 'Unprocessable Entity',
'423': 'Locked',
'424': 'Failed Dependency',
'425': 'Unordered Collection',
'426': 'Upgrade Required',
'428': 'Precondition Required',
'429': 'Too Many Requests',
'431': 'Request Header Fields Too Large',
'451': 'Unavailable For Legal Reasons',
'500': 'Internal Server Error',
'501': 'Not Implemented',
'502': 'Bad Gateway',
'503': 'Service Unavailable',
'504': 'Gateway Timeout',
'505': 'HTTP Version Not Supported',
'506': 'Variant Also Negotiates',
'507': 'Insufficient Storage',
'508': 'Loop Detected',
'509': 'Bandwidth Limit Exceeded',
'510': 'Not Extended',
'511': 'Network Authentication Required' },
Agent:
{ [Function: Agent]
super_:
{ [Function: EventEmitter]
EventEmitter: [Circular],
usingDomains: false,
defaultMaxListeners: [Getter/Setter],
init: [Function],
listenerCount: [Function] },
defaultMaxSockets: Infinity },
ClientRequest:
{ [Function: ClientRequest] super_: { [Function: OutgoingMessage] super_: [Fu
nction] } },
globalAgent:
Agent {
_events: [Object: null prototype] { free: [Function] },
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 80,
protocol: 'http:',
options: { path: null },
requests: {},
sockets: {},
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256 },
IncomingMessage:
{ [Function: IncomingMessage]
super_:
{ [Function: Readable]
ReadableState: [Function: ReadableState],
super_: [Function],
_fromList: [Function: fromList] } },
OutgoingMessage:
{ [Function: OutgoingMessage]
super_:
{ [Function: Stream]
super_: [Function],
Readable: [Function],
Writable: [Function],
Duplex: [Function],
Transform: [Function],
PassThrough: [Function],
pipeline: [Function: pipeline],
finished: [Function: eos],
Stream: [Circular],
_isUint8Array: [Function: isUint8Array],
_uint8ArrayToBuffer: [Function: _uint8ArrayToBuffer] } },
Server:
{ [Function: Server] super_: { [Function: Server] super_: [Function] } },
ServerResponse:
{ [Function: ServerResponse] super_: { [Function: OutgoingMessage] super_: [F
unction] } },
createServer: [Function: createServer],
get: [Function: get],
request: [Function: request],
maxHeaderSize: [Getter] } 二.异步式 I/O 与事件驱动
Node.js 最大的特点就是采用异步式 I/O 与事件驱动的架构设计。对于高并发的解决方
案,传统的架构是多线程模型,也就是为每个业务逻辑提供一个系统线程,通过系统线程切换来弥补同步式 I/O 调用时的时间开销。Node.js 使用的是单线程模型,对于所有 I/O 都采用异步式的请求方式,避免了频繁的上下文切换
例如,对于简单而常见的数据库查询操作,按照传统方式实现的代码如下:
res = db.query('SELECT*from some_table');res.output();以上代码在执行到第一行的时候,线程会阻塞,等待数据库返回查询结果,然后再继续处理 一
方面线程长期阻塞等待,另一方面为了应付新请求而不断增加线程,因此会浪费大量系统资源,同时线程的增多也会占用大量的 CPU 时间来处理内存上下文切换,而且还容易遭受低速连接攻击。
看看Node.js是如何解决这个问题的:
db.query('SELECT*from some_table', function(res){ res.output();});这段代码中 db.
query 的第二个参数是一个函数,我们称为回调函数。进程在执行到db.query 的时候,不会等待结果返回,而是直接继续执行后面的语句,直到进入事件循环。
当数据库查询结果返回时,会将事件发送到事件队列,等到线程进入事件循环以后,才会调
用之前的回调函数继续执行后面的逻辑。
Node.js 的异步机制是基于事件的,返回的结果由事件循环来处理。Node.js 进程在同一时刻只会处理一个事件,完成后立即进入事件循环检查并处理后面的事件
