添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

如何解决高并发?

node使用异步IO和事件驱动(回调函数)来解决这个问题。

一般来说,高并发解决方案会提供多线程模型,为每个业务逻辑提供一个线程,通过系统线程切换来来弥补同步I/O调用的时间开销。像apache,是一个请求一个线程。

而node.js使用的是单线程模型,对所有I/O都采用异步的请求方式,避免频繁的上下文切换,在node.js执行的时候维护着一个事件队列;程序在执行时进入事件循环等待下一个事件到来,每个异步I/O请求完成后都会被推送到事件队列中的等待执行。

对于一个简单的数据库访问操作,传统方式是这样实现的

 res = db.query('SELECT * from some_table');
 res.output();

代码执行到第一行的时候线程会阻塞,等待query返回结果,然后继续处理。由于数据库查询、磁盘读写、网络通信等原因(所谓的I/O)阻塞时间会非常大(相对于CPU始终频率)。对于高并发的访问,一方面线程长期阻塞等待,另一方面为了应付新情求而不断添加新线程,会浪费大量系统资源,同时线程的增加也会也会占用大量的CPU时间来处理内存上下文切换。看看node.js怎么处理

  1. db.query( 'SELECT * from some_table' , function (res) {
  2. res.output();
  3. });

query的第二个参数是一个回调函数,进程执行到db.query的时候不会等待结果返回,而是直接继续执行下面的语句,直到进入事件循环。当数据库执行结果返回的时候会将事件发送到事件队列,等到线程进入事件循环后才会调用之前的回调函数。

node.js的异步机制是基于事件的,所有的I/O、网络通信、数据库查询都以非阻塞的方式执行,返回结果由事件循环来处理。node.js在同一时刻只会处理一个事件,完成后立即进入事件循环检查后面事件。这样CPU和内存在同一时间集中处理一件事,同时尽量让耗时的I/O等操作并行执行。

事件循环机制

所谓事件循环是指node.js会把所有的异步操作使用事件机制解决,有个线程在不断地循环检测事件队列。

node.js中所有的逻辑都是事件的回调函数,所以node.js始终在事件循环中,程序入口就是事件循环第一个事件的回调函数。事件的回调函数中可能会发出I/O请求或直接发射( emit)事件,执行完毕后返回事件循环。事件循环会检查事件队列中有没有未处理的事件,直到程序结束。node.js的事件循环对开发者不可见,由libev库实现,libev不断检查是否有活动的、可供检测的事件监听器,直到检查不到时才退出事件循环,程序结束。

libuv 是一个高性能事件驱动的程序库,封装了 Windows 和 Unix 平台一些底层特性,为开发者提供了统一的 API.
因此,node.js 是单线程,异步非阻塞。

但毕竟,如何弥补单线程缺陷?是不是有异步非阻塞,就可以高枕无忧了?

1)CPU密集型任务存在短板

如上所述,nodejs的机制是单线程,这个线程里面,有一个事件循环机制,处理所有的请求。如图所示。在事件处理过程中,它会智能地将一些涉及到IO、网络通信等耗时比较长的操作,交由worker threads去执行,执行完了再回调,这就是所谓的异步IO非阻塞吧。但是,那些非IO操作,只用CPU计算的操作,它就自己扛了,比如算什么斐波那契数列之类。它是单线程,这些自己扛的任务要一个接着一个地完成,前面那个没完成,后面的只能干等。因此,对CPU要求比较高的CPU密集型任务多的话,就有可能会造成号称高性能,适合高并发的node.js服务器反应缓慢。

2)无法利用CPU的多核

最开始,线程只是用于分配单个处理器处理时间的一种机制。但假如操作系统本身支持多个CPU/内核,那么每个线程都可以得到一个不同自己的CPU/内核,实现真正的“并行运算”。在这种情况下,多线程程序可以提高资源使用效率。Node.js是单线程程序,它只有一个event loop,也只占用一个CPU/内核。现在大部分服务器都是多CPU或多核的,当Node.js程序的event loop被CPU密集型的任务占用,导致有其它任务被阻塞时,却还有CPU/内核处于闲置的状态,造成资源的浪费。

利用原生模块或第三方模块,开辟进程或子进程,用于处理这些特殊的任务。

3)如果有异常抛出,因为是单线程,整个项目将不可用。但这归根到底是代码的问题,糟糕的代码,不管什么体系,都会有问题,即使不崩溃。解决办法是用pm2等工具来运行?

二、nodejs与javascript的关系

nodejs本身不是开发语言,它是一个工具或者平台,在服务器端解释、运行javascript;coffeescript属于nodejs体系,算是一种新的开发语言,但它的目的在于最后编译成javascript。

nodejs利用Google V8来解释运行javascript,但是系统真正执行的代码是用C++写的。javascript做的只是调用这些API而已。因此,并无执行效率的问题。

1、RESTful API

这是适合 Node 的理想情况,因为您可以构建它来处理数万条连接。它仍然不需要大量逻辑;它本质上只是从某个数据库中查找一些值并将它们组成一个响应。由于响应是少量文本,入站请求也是少量的文本,因此流量不高,一台机器甚至也可以处理最繁忙的公司的 API 需求。

2、实时程序

比如聊天服务

聊天应用程序是最能体现 Node.js 优点的例子:轻量级、高流量并且能良好的应对跨平台设备上运行密集型数据(虽然计算能力低)。同时,聊天也是一个非常值得学习的用例,因为它很简单,并且涵盖了目前为止一个典型的 Node.js 会用到的大部分解决方案。

3、单页APP

ajax很多。现在单页的机制似乎很流行,比如phonegap做出来的APP,一个页面包打天下的例子比比皆是。

总而言之,NodeJS适合运用在高并发、I/O密集、少量业务逻辑的场景

关于node.js的误会

Node.js的线程和进程

http://www.slideshare.net/mysqlops/nodejs-9313477

Node.js软肋之CPU密集型任务

JavaScript 运行机制详解:再谈Event Loop - 阮一峰的网络日志

滑动验证页面

node.js是单线程。好处就是1)简单2)高性能,避免了频繁的线程切换开销3)占用资源小,因为是单线程,在大负荷情况下,对内存占用仍然很低3)线程安全,没有加锁、解锁、死锁这些问题坏处就是如何解决高并发?node使用异步IO和事件驱动(回调函数)来解决这个问题。一般来说,高并发解决方案会提供多线程模型,为每个业务逻辑配备一个线程,通过系统线程切换来来弥补同步I/O调用的时间开销。而node.js 本来是想只做一个 Nodejs 运行 原理 -科普篇,但是收到了不少私信,要我多分享一些更进阶,更详细的内容,所以我会在接下来的两个月里继续更新 Nodejs 运行 原理 。 PS:此系列只做 Nodejs 的运行 原理 (架构,libuv,v8 etc),并不介绍 Nodejs 功能以及使用方法。 本文以两个view来看 Nodejs 的架构,一个是从模块依赖的角度,另一个是从函数调用的角度。 1.模块依赖
NodeJS NodeJS http服务器模块化规范模块分类 原理 导出模块引入模块: require()常用第三方的模块request模块cheerio模块WebSocket协议HTTP/HTTPS 协议TCP 协议WebSocket 协议使用Socket服务端客户端常用第三方模块工具 NodeJS http服务器 静态资源服务器 了解文件mime类型 const http = require('http'); const fs = req
nodejs 的诞生 创始人Ryan Dahl,他为了解决服务器的高并发性能问题,他认为通过事件驱动和异步I/O来解决这个问题是关键。 然后2008年谷歌推出了chrome浏览器,使用V8引擎就满足了他的想象。v8引擎的优势: 1、历史遗留问题少,都是异步I/O ​2、强大的编译和执行的效率 ​3、 javascript 的闭包特性非常方便 ​4、利用事件驱动 机制 随后Ryan Dahl就发现了v8引擎的巨大优势,然后Ryan Dahl就把v8移植到了服务端,就这样 nodejs 就从他的手中脱颖而出,就这样诞生了。
上一次我们讲了一下 JavaScript 的运行 机制 ,这次我们来谈谈 nodejs 的运行 机制 ,相信有了js的基础,关于 nodejs 的运行 机制 我们可以很清楚的 理解 了,如果有不了解js运行 机制 的,可以看我的上一篇文章 https://mp.csdn.net/postedit/90691003 一、 Nodejs 的架构 首先上张图 这张图是从github下扒下来的,首先我们可以看到, nodejs 的...
简单的说 Node.js 就是运行在服务端的 JavaScript ,是一个能让JavaSript运行在服务器端的开发平台 Node.js 不是一门语言,与PHP、JSP、Pythen、Perl、Ruby的“既是语言,也是平台”不同, Node.js 的使用 JavaScript 进行编程,运行在 JavaScript 引擎上(V8)。 与PHP、JSP 等相比, Node.js 跳过了Appac...
Node.js 是一个基于Chrome V8引擎的 JavaScript 运行环境。它可以在服务器端运行 JavaScript 代码,使得 JavaScript 不仅仅只能在浏览器中运行,还可以用来编写服务器端程序。下面是 Node.js 的安装及添加环境变量的步骤。 1. 下载安装包 在 Node.js 的官网(https:// nodejs .org/en/)上下载适合自己操作系统的安装包。 2. 安装 Node.js 双击下载的安装包,按照提示进行安装,一般来说是一路“下一步”即可完成安装。安装完成后,可以在命令行输入以下命令来验证是否安装成功: ```shell node -v 如果输出了 Node.js 的版本号,则说明安装成功。 3. 添加环境变量 在Windows系统中,需要将 Node.js 的安装路径添加到环境变量中,才能在命令行中直接使用node命令。可以按照以下步骤进行操作: 1) 右键点击“我的电脑”,选择“属性”。 2) 点击“高级系统设置”,在弹出的窗口中选择“环境变量”。 3) 在“系统变量”中找到“Path”,双击进入编辑界面。 4) 在“变量值”末尾加上 Node.js 的安装路径,比如: ;C:\Program Files\ nodejs \ 5) 点击“确定”保存修改,然后关闭所有窗口。 6) 在命令行中输入以下命令来验证是否添加成功: ```shell node -v 如果输出了 Node.js 的版本号,则说明添加环境变量成功。 在Linux和Mac OS X系统中,添加环境变量的方法类似,在命令行中使用以下命令来编辑环境变量文件: ```shell vi ~/.bash_profile 在文件末尾添加以下代码来添加 Node.js 的环境变量: ```shell export PATH=$PATH:/usr/local/bin 其中,/usr/local/bin是 Node.js 的安装路径。保存修改后,使用以下命令使其生效: ```shell source ~/.bash_profile 然后可以在命令行中输入以下命令来验证是否添加成功: ```shell node -v 如果输出了 Node.js 的版本号,则说明添加环境变量成功。
gradle版本引起编译报错问题:Cause: org.jetbrains.plugins.gradle.tooling.util.ModuleComponentIdentifierImpl.getM 110616