非阻塞http服务器中的阻塞代码
blocking code in non-blocking http server
比如我有一个http服务器,是node.js,所以是非阻塞的。
对于每个请求都会做一次数据库操作。
我无法理解的是阻塞数据库操作和非阻塞数据库操作有什么区别?
既然网络服务器是非阻塞的,那么请求中的阻塞数据库操作没有区别吗?
我猜你混淆了非阻塞和线程。在单个线程上使用您的nodejs 运行,如果您收到多个请求,每个请求都需要访问数据库,在非阻塞状态下,nodejs只会请求数据库获取数据,不会等待数据库的响应并移动继续处理下一个请求,以阻塞方式,只有线程,当它一次回答一个 http 请求时,会导致请求超时。
编辑:你可以查看this question的答案,我想他的解释更好。
这里有一个类比,可能有助于您理解。假设您从事销售工作,今天要打 50 phone 个电话。
在阻塞模型中,您拨打电话,如果对方还没有准备好与您交谈,您就必须在线等,一直等到他们准备好与您交谈。当他们终于准备好与您交谈时,您就可以开始谈话,挂断电话,然后才能拨打下一个电话并重复该过程。因此,您 phone 忙碌而您无法拨打电话的时间是您等待客户准备好与您通话的所有时间加上您通话的所有时间。
在非阻塞模型中,您拨打电话,如果此人没有立即可用,您可以快速留言,他们会在准备好通话时给您回电。您挂断了留言并立即致电您的下一个客户。您的 phone 总忙时间只是快速留言的时间,然后是他们回电时您通话的时间。他们在一分钟或三小时后给您回电话实际上并不重要——这不会影响您打电话的整体效率。显然,您可以使用非阻塞模型发出并完成更多呼叫,因为您不会浪费很多时间,而您可以通过等待客户准备好通话来做其他事情。
node.js 通过使用非阻塞 I/O 模型而不是使用线程来提高效率。如果实施得当,这种非阻塞模型比让许多单独的线程都在等待它们的阻塞请求更有效。
因此,在 node.js 中,如果您有一个阻塞的数据库请求,那么在该数据库请求一直处于阻塞状态的整个时间内,node.js Web 服务器无法执行任何其他操作。它只有一个线程,因此如果该线程忙于处理需要一段时间才能完成的阻塞请求,则服务器基本上会在很长一段时间内变得无用。这将是 node.js 服务器进程的错误实现,并且以这种方式使用 node.js 毫无意义。
对于非阻塞数据库请求,node.js 服务器开始处理 http 请求。它运行一些代码,然后到达非阻塞数据库请求。该请求已启动并为完成注册了一个回调,但由于它是非阻塞的,因此数据库会立即调用 returns。 node.js 服务器 returns 回到它的事件循环,可以立即开始处理其他 http 请求或其他事件供服务器处理(例如其他 http 请求的完成)。然后,稍后,数据库调用 finishes 并将一个条目放入事件队列以触发其回调。当 nodejs 服务器到达事件队列中的那个事件时,回调被调用并且那个原始请求现在有来自数据库服务器的答案并且可以完成那个原始请求。与此同时,它一直在等待该数据库请求完成,它一直在忙于处理其他事情——所有这些都是一个线程。
比如我有一个http服务器,是node.js,所以是非阻塞的。
对于每个请求都会做一次数据库操作。
我无法理解的是阻塞数据库操作和非阻塞数据库操作有什么区别?
既然网络服务器是非阻塞的,那么请求中的阻塞数据库操作没有区别吗?
我猜你混淆了非阻塞和线程。在单个线程上使用您的nodejs 运行,如果您收到多个请求,每个请求都需要访问数据库,在非阻塞状态下,nodejs只会请求数据库获取数据,不会等待数据库的响应并移动继续处理下一个请求,以阻塞方式,只有线程,当它一次回答一个 http 请求时,会导致请求超时。
编辑:你可以查看this question的答案,我想他的解释更好。
这里有一个类比,可能有助于您理解。假设您从事销售工作,今天要打 50 phone 个电话。
在阻塞模型中,您拨打电话,如果对方还没有准备好与您交谈,您就必须在线等,一直等到他们准备好与您交谈。当他们终于准备好与您交谈时,您就可以开始谈话,挂断电话,然后才能拨打下一个电话并重复该过程。因此,您 phone 忙碌而您无法拨打电话的时间是您等待客户准备好与您通话的所有时间加上您通话的所有时间。
在非阻塞模型中,您拨打电话,如果此人没有立即可用,您可以快速留言,他们会在准备好通话时给您回电。您挂断了留言并立即致电您的下一个客户。您的 phone 总忙时间只是快速留言的时间,然后是他们回电时您通话的时间。他们在一分钟或三小时后给您回电话实际上并不重要——这不会影响您打电话的整体效率。显然,您可以使用非阻塞模型发出并完成更多呼叫,因为您不会浪费很多时间,而您可以通过等待客户准备好通话来做其他事情。
node.js 通过使用非阻塞 I/O 模型而不是使用线程来提高效率。如果实施得当,这种非阻塞模型比让许多单独的线程都在等待它们的阻塞请求更有效。
因此,在 node.js 中,如果您有一个阻塞的数据库请求,那么在该数据库请求一直处于阻塞状态的整个时间内,node.js Web 服务器无法执行任何其他操作。它只有一个线程,因此如果该线程忙于处理需要一段时间才能完成的阻塞请求,则服务器基本上会在很长一段时间内变得无用。这将是 node.js 服务器进程的错误实现,并且以这种方式使用 node.js 毫无意义。
对于非阻塞数据库请求,node.js 服务器开始处理 http 请求。它运行一些代码,然后到达非阻塞数据库请求。该请求已启动并为完成注册了一个回调,但由于它是非阻塞的,因此数据库会立即调用 returns。 node.js 服务器 returns 回到它的事件循环,可以立即开始处理其他 http 请求或其他事件供服务器处理(例如其他 http 请求的完成)。然后,稍后,数据库调用 finishes 并将一个条目放入事件队列以触发其回调。当 nodejs 服务器到达事件队列中的那个事件时,回调被调用并且那个原始请求现在有来自数据库服务器的答案并且可以完成那个原始请求。与此同时,它一直在等待该数据库请求完成,它一直在忙于处理其他事情——所有这些都是一个线程。