Node.js:Node.js是构建在Chrome上的js运行时的一个平台,Node.js使用事件驱动的、非阻塞式的I/O模型。node.js是单进程单线程。
关于node.js使用事件驱动以及非阻塞式,可以理解为下面的例子:
当你去肯德基点餐,当轮到你的时候,你点好餐,如果收银员此时等到你的食物给你之前都只为你服务,那么这个进程就是阻塞式的。而如果收银员让你点好餐后,让你拿好号码牌在旁边等着,继续服务点餐的其他客户,那么这个进程就是非阻塞的。
Node.js做了什么工作呢?
经典的服务器执行模式有同步式、进程式和线程式
同步式就是每次只处理一个请求,迭代地为处理完web请求,就例如肯德基只有一个收银员,每次为每个客户点好餐并上好餐后再服务后面的客户。这种模式效率很低
进程式就是为每个web请求开一个进程,这样同时可以处理很多请求,但这样当请求比较多的时候对于资源有限的系统就会比较吃力了。如每次来一个客户,就增加一个收银员,收银员每次为每个客户点好餐并上好餐后再服务后面的客户,这样会给资源有限的肯德基造成很大负担。
线程式模型为每一个ieWeb请求开启一个线程处理。线程式又包括单线程模型、多线程模型,也就是一个进程中几个个线程,每一个线程分担一个任务听起来很不错,但这会冒出两个问题:其一,线程的数量是有限制的,当你的任务量大于可调度的线程时,就会发生等待处理资源的情况;其二,线程上的任务是共用资源,当线程面对堵塞IO的事务很长时间时,通过线程锁来阻止资源的使用。对于数据密集性的应用来说,这两个问题可能会导致低效的Web服务。
事件驱动
Node采用事件驱动的运行方式,它无需为每一个请求创建额外的线程,每一个I/O被添加到事件队列中,线性循环的执行队列中的事件,当执行队列任务遇到阻塞时(如读取文件、查询数据时),线程不会停下来等结果,而是留下一个回调函数处理结果,转而执行下一个任务,这个传递到队列中的回调函数等到阻塞任务完成之后才会被线程调用
那么对于阻塞任务的执行是怎么样的呢,此时可能会有疑问,阻塞事件是早晚得执行的啊,如果此时读一个文件花费了十分钟,这个线程还是无阻塞的吗?对于阻塞事件,node在幕后使用线程池来确保工作的执行,当碰到阻塞事件时,node在池中取出一个进程去执行事件,而不占用主循环线程。当堵塞任务完成之后通过处理添加到队列中的回调函数来处理接下来的工作。这时又得拿出肯德基的例子了,当顾客付完款之后,食物的等待过程可以看成是阻塞的,此时收银员不会自己去处理食物,而是通过将单子给处理食物的工作人员,让他去处理顾客的食物,这样就不会耽误后面顾客的继续点单。可以这么说,node起到的是一个调度的作用,它不会自己去执行任何阻塞的操作,通过不停地循环调度去处理请求。

1470

被折叠的 条评论
为什么被折叠?



