ホームページ  >  に質問  >  本文

node.js中异步的“效率”体现在哪里?

小弟Node.js新手。

看了一些介绍,感觉大家都觉得,在Node.js中,异步“高效性”都体现在可以迅速响应用户的请求并做出反应。

但假如用户请求的内容需要有数据库查询这样的操作,I/O虽然未阻塞,但是必须得等数据表查完了,才能给用户发送完整的http response报文啊,在此之前用户的浏览器应该还是没有任何响应啊?

请问在这一点上,Node.js的迅速体现在哪里?

大家讲道理大家讲道理2763日前453

全員に返信(5)返信します

  • 伊谢尔伦

    伊谢尔伦2017-04-17 11:14:55

    @1000copy 的回答废话太多了。

    大部分 Web 应用的瓶颈都在 IO, 即读写磁盘,读写网络,读写数据库。使用怎样的策略等待这段时间,就成了改善性能的关键点。

    • PHP 的策略:多进程运行,直接原地等待 IO 完成。缺点:多个进程会消耗多份内存,进程间难以共享数据。
    • C 通常的策略:多线程运行,程序自己维护锁的状态。缺点:开发成本高,容易出错,不易调试。
    • Python(Tornado): 多个请求在单个进程中轮流执行,遇到 IO 时切换到另一个请求。缺点:对于单个请求而言,依然没有最高效地利用时间。

    何谓「最高效地利用时间」?比如现在有两个不相关的数据库查询,在 PHP 中通常会先执行一个,执行完成后再执行第二个(总时间是 a + b). 显然这不是最高效的,应该同时执行两个查询,时间是 max(a, b).

    Python 和其他支持多线程的语言的问题就在于,在语言层面,程序员很难告诉虚拟机,应当将两个操作同时执行,即使有办法,也相当麻烦,大多数人懒得去用(也不值得去用)。而因为 Node.js 没有历史包袱,强制所有的 IO 操作必须通过回调函数来通知,因此在 Node 里可以非常灵活地让两个查询同时执行,节省时间。

    返事
    0
  • 黄舟

    黄舟2017-04-17 11:14:55

    你提到的单客户上的时间上的效率,答案确实是不能提升。因为真正的时间压力不在node.js ,而是数据库服务器。但是,作为服务器软件,考量单客户速度,其实无意义。因为服务器,要考量的是并发用户数上来后,编程模型可以不变,仅仅增加设备和配置就可以支持。所谓的可伸缩性。

    社区内广泛存在的node.js 高效的说法,我认为是有误导之嫌疑的:)。充斥着node.js 社区的骄傲和对老派并发模型的不肖。

    很简单,你说高效是和谁比较呢?没有对比主体的高效,都是耍流氓。所以,我觉得nodejs 的默认对手,当然是传统的并发模型的web server,如apache。

    服务器的东西,必然是多线索运行的。和apache,iis不同的地方在于:

    1. node.js本身是存在多线程的。但是在用户代码却只能有一个线程。
    2. 传统的(以iis为例)。用户代码是运行在多个线程内的。

    当然传统的,不是简单地一对一,来一个request,iis 可能new一个新线程,也可能在线程池(进程池)内找到一个现成的。具体就要看web garden 的配置了。

    其实老的方式也不是罪恶之源了。用户代码存在于多个线程中,只要不访问共享资源,或者这个共享资源考虑到了多线程并发的情况,都是OK的。

    以我们一个产品的.net 代码为例,一直运行良好。直到又一次把web garden配置为>1 ,结果发生了找不到软件狗的问题。因为我们的软件狗就是一个没有考虑并发的单机软件狗。我们自己的代码更牛,是一个静态类(静态类变量是全局共享的,在多线程情况下,访问同一个静态类变量就会发生经典的多线程重入问题)。

    当然,关系数据库本身也是共享资源,可是人家考虑了多线程并发了(这是当然的)

    node.js的设计者,采用了新的并发模型,对于用户的效果显然的。不管访问什么共享资源,都不必考虑重入问题。因为应用程序开发者根本就没有多线程。如果有共享资源,那么有高级的程序员去封装库。如果有多线程问题,那么一定是库的问题。真的是把应用程序员为视为笨蛋的节奏啊。真的是库程序员解救世界啊。很残酷的是,据我的观察,他是对的:————)

    就意味着所有的库,最终和用户线程(唯一的)打交道的方法都必须重新考量,重新做,原来的所有现存代码,都需要重新翻新(至少是需要重新包装)。这就是他的伟大(牛逼)之处。真敢干。也是他不选择lua,python来实现的原因,因为js在服务器端没有历史包袱,直接新写代码即可,不太需要重新封装现有的库。如果因此就说Node.js 更加高效(笑话:),我不敢苟同。

    都是我的个人理解,欢迎搬砖。

    因此做一个牛逼哄哄的总结:

    node.js 的优势在于:以不需要应用程序员引入线程的情况下,以不低于现在已有方案的效率处理客户访问。

    返事
    0
  • 大家讲道理

    大家讲道理2017-04-17 11:14:55

    此处的高效不是指每一个请求的处理高效,而是高并发的情况下请求的平均处理很高效

    返事
    0
  • 怪我咯

    怪我咯2017-04-17 11:14:55

    传统的服务器IO阻塞是最大的瓶颈,假设一个请求来了,要茶数据库,返回,整个过程需要1秒。应用服务器启动100个线程作为线程池,那么在100个并发请求的情况下,客户端基本都可以在1秒得到结果,但是如果并发数继续增大,客户端就需要排队了。这是传统的IO阻塞模型。

    Node和Nginx属于IO非阻塞模型,无论来多少个请求都不阻塞,而是立刻dispatch给后台的处理线程去处理,主线程立刻可以处理下一个请求。Node在处理请求的时候根本不需要线程池的概念,在大并发的时候效率的优势就显现出来了。

    返事
    0
  • ringa_lee

    ringa_lee2017-04-17 11:14:55

    赞同elgs

    这些需要并发编程的知识才能明白

    返事
    0
  • キャンセル返事