热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

node.js究竟是什么

前言如果你有一定的前端基础,比如HTML、CSS、JavaScript、JQ、Vue;那么,Node.js

前言

如果你有一定的前端基础,比如 HTML、CSS、Javascript、JQ、Vue;那么,Node.js 能让你以最低的成本快速过渡成为一个全栈工程师(我称这个全栈为伪全栈,我认为的全栈也要精通数据库,不喜勿喷),从而触及后端和移动端的开发。当然,Node.js 也不是万能的、也不是说学了它就可以完全取代后端的其他开发语言,它有自己的使命和擅长的应用领域。

除此之外现在非常火热的 Vue.js,React.js ,等很多数据层动态交互优先选用了Node.js,一些比较流行的打包工具也是如此;综上,为你为什么要学习它又增加了一大理由。

Node.js 和传统的后端语言(比如 PHP、JAVA 等)相比,各有优缺点,各自擅长领域和侧重点不同,因此,各有千秋、各有需求市场。Node.js 让我们进行后端开发多了一种便捷的手段。所以大家也不要总说哪些语言是最好的,各有各的使命,嘿嘿。

# Node.js 的特点


# 非阻塞异步 io

例如,当在访问数据库取得数据的时候,需要一段时间。在传统的单线程处理机制中,在执行了访问数据库代码之后,整个线程都将暂停下来,等待数据库返回结果,才能执行后面的代码。也就是说,I/O阻塞了代码的执行,极大地降低了程序的执行效率。

由于 Node.js 中采用了非阻塞型I/O机制,因此在执行了访问数据库的代码之后,将立即转而执行其后面的代码,把数据库返回结果的处理代码放在回调函数中,从而提高了程序的执行效率。

当某个I/O执行完毕时,将以事件的形式通知执行I/O操作的线程,线程执行这个事件的回调函数。为了处理异步I/O,线程必须有事件循环,不断的检查有没有未处理的事件,依次予以处理。

阻塞模式下,一个线程只能处理一项任务,要想提高吞吐量必须通过多线程。而非阻塞模式下,一个线程永远在执行计算操作,这个线程的 CPU 核心利用率永远是 100%。所以,这是一种特别有哲理的解决方案:与其人多,但是好多人闲着;还不如一个人玩命,往死里干活儿。

# 单线程

在 Java、PHP 或者 .net 等服务器端语言中,会为每一个客户端连接创建一个新的线程。而每个线程需要耗费大约 2MB 内存。也就是说,理论上,一个 8GB 内存的服务器可以同时连接的最大用户数为 4000 个左右。要让 Web 应用程序支持更多的用户,就需要增加服务器的数量,而 Web 应用程序的硬件成本当然就上升了。

Node.js 不为每个客户连接创建一个新的线程,而仅仅使用一个线程。当有用户连接了,就触发一个内部事件,通过非阻塞I/O、事件驱动机制,让 Node.js 程序宏观上也是并行的。使用 Node.js ,一个 8GB 内存的服务器,可以同时处理超过 4 万用户的连接。

另外,单线程带来的好处,操作系统完全不再有线程创建、销毁的时间开销。但是单线程也有很多弊端,会在 Node.js 的弊端详细讲解,请继续看。

# 事件驱动

Node.js 中,客户端请求建立连接,提交数据等行为,会触发相应的事件。在 Node.js 中,在一个时刻,只能执行一个事件回调函数,但是在执行一个事件回调函数的中途,又有其他事件产生,可以转而处理其他事件(比如,又有新用户连接了),然后返回继续执行原事件的回调函数,这种处理机制,称为“事件环”机制。

Node.js 底层是 C++V8也是 C++写的)。底层代码中,近半数都用于事件队列、回调函数队列的构建。用事件驱动来完成服务器的任务调度,这是鬼才才能想到的。针尖上的舞蹈,用一个线程,担负起了处理非常多的任务的使命。

注意这里的事件循环,也可以说是 Node.js 的一个精髓所在,下面引用一段 Node.js 官网的内容

┌───────────────────────────┐
┌─>│ timers │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ pending callbacks │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
│ │ idle, prepare │
│ └─────────────┬─────────────┘ ┌───────────────┐
│ ┌─────────────┴─────────────┐ │ incoming: │
│ │ poll │<─────┤ connections, │
│ └─────────────┬─────────────┘ │ data, etc. │
│ ┌─────────────┴─────────────┐ └───────────────┘
│ │ check │
│ └─────────────┬─────────────┘
│ ┌─────────────┴─────────────┐
└──┤ close callbacks │
└───────────────────────────┘


引用 Node 官网中的一段内容:

注意:每个框将被称为事件循环的“阶段”。

每个阶段都有一个要执行的回调FIFO队列。虽然每个阶段都以其自己的方式特殊,但通常情况下,当事件循环进入给定阶段时,它将执行特定于该阶段的任何操作,然后在该阶段的队列中执行回调,直到队列耗尽或最大回调数量为止已执行。当队列耗尽或达到回调限制时,事件循环将移至下一阶段,依此类推。

关于事件循环是一个核心点,经常会被面试官考具体执行输出的问题,大家可以看我的这篇文章


# 跨平台

起初,Node 只能在 Linux 平台上运行。后来随着 Node的发展,微软注意到了它的存在,并投入了一个团队帮助 Node 实现 Windows 平台的兼容,在v0.6.0版本发布时,Node 已经能够直接在 Window 平台运行了。 Node 是基于libuv实现跨平台的。

# Node.js 的弊端


# 单线程带来的弊端

Node.js 中有一个特点就是单线程,它带来了很多好处,但是它也有弊端,单线程弱点如下。


  1. 无法利用多核 CPU

  2. 错误会引起整个应用退出无法继续调用异步I/O

  3. 大量计算占用 CPU 导致无法继续调用异步I/O

以上确实是 Node 的弊端,但是都会有一些对应的解决方案:

弊端 1:解决方案


  • (1)一些管理工具比如pm2,forever 等都可以实现创建多进程解决多核 CUP 的利用率问题。

  • (2)在 v0.8 版本之前,实现多进程可以使用child_process

  • (3)在 v0.8 版本之后,可以使用cluster模块,通过主从模式,创建多个工作进程解决多核 CPU 的利用率问题。

弊端 2:解决方案


  • (1)Nnigx 反向代理,负载均衡,开多个进程,绑定多个端口;

  • (2) 一些管理工具比如pm2,forever 等都可以实现进程监控,错误自动重启等

  • (3)开多个进程监听同一个端口,使用 Node 提供的cluster模块;

  • (4)未出现cluster之前,也可以使用child_process,创建多子线程监听一个端口。

  • (5)这里说明下,有上面的这些解决方案,但是写 node 后端代码的时候,异常抛出try catch显得格外有必要。

弊端 3:解决方案


  • (1)可以把大量的密集计算像上面一样拆分成多个子线程计算

  • 但是如果不允许拆分,想计算 100 万的大数据,在一个单线程中,Node 确实显得无能为力,这本身就是 V8 内存限制的弊端。


说明:child_process 与 cluster 模块我会单独拿一篇文章来讲。

值得开心的是上面这些弊端随着 Node 的版本更新,和新的 api 模块出现,好像解决了这些弊端。


# 调试

用过node的人可能第一时间就会想到debug太难了,没有stack trace,因此调试比较困难。

# Node 社区中的 npm 包

Node.js社区有很多包品质良莠不齐、如果你想偷懒而又刚好npm了一个有问题的包你就很麻烦,因为代码是开源的,只能自己调试了。

# Node.js 的应用场景

介绍了 Node.js 的特点和弊端,再说一下 Node.js 的应用场景。

Node.js 适合用来开发什么样的应用程序呢?

善于I/O,不善于计算。因为Node.js最擅长的就是任务调度,如果你的业务有很多的 CPU 计算,实际上也相当于这个计算阻塞了这个单线程,就不太适合 Node 开发,但是也不是没有解决方案,只是说不太适合。

当应用程序需要处理大量并发的I/O,而在向客户端发出响应之前,应用程序内部并不需要进行非常复杂的处理的时候,Node.js非常适合。Node.js也非常适合与websocket配合,开发长连接的实时交互应用程序。

具体场景可以表现为如下:


  • 第一大类:用户表单收集系统、后台管理系统、实时交互系统、考试系统、联网软件、高并发量的 web 应用程序;

  • 第二大类:基于 web、canvas 等多人联网游戏;

  • 第三大类:基于 web 的多人实时聊天客户端、聊天室、图文直播;

  • 第四大类:单页面浏览器应用程序;

  • 第五大类:操作数据库、为前端和移动端提供基于json的 API;

  • 第六大类,....


# 哪些大公司在用



  • 雅虎:雅虎开放了Cooktail框架,将YUI3这个前端框架的能力借助 Node 延伸到了服务器端。

  • 腾讯:将 Node 应用到长连接,以提供实时功能。

  • 花瓣网,蘑菇街:通过socket.io实现实时通知。

  • 阿里:主要利用的是并行I/O这个性能,实现高效的分布式,它们自己也出了很多 Node 框架

  • LinkedIn:移动网站也是使用的 Node

  • 网易:游戏领域对并发和实时要求很高,网易开源了 Node 的实时框架pomelo

  • 等等...

参考文章:本文部分内容来自朴灵老师的《深入浅出 Node.js》


推荐阅读
  • 本文详细记录了腾讯ABS云平台的一次前端开发岗位面试经历,包括面试过程中遇到的JavaScript相关问题、Vue.js等框架的深入探讨以及算法挑战等内容。 ... [详细]
  • 实践指南:使用Express、Create React App与MongoDB搭建React开发环境
    本文详细介绍了如何利用Express、Create React App和MongoDB构建一个高效的React应用开发环境,旨在为开发者提供一套完整的解决方案,包括环境搭建、数据模拟及前后端交互。 ... [详细]
  • ABP框架是ASP.NET Boilerplate的简称,它不仅是一个开源且文档丰富的应用程序框架,还提供了一套基于领域驱动设计(DDD)的最佳实践架构模型。本文将详细介绍ABP框架的特点、项目结构及其在Web API优先架构中的应用。 ... [详细]
  • 本文提供了一个详尽的前端开发资源列表,涵盖了从基础入门到高级应用的各个方面,包括HTML5、CSS3、JavaScript框架及库、移动开发、API接口、工具与插件等。 ... [详细]
  • 本文回顾了作者在求职阿里和腾讯实习生过程中,从最初的迷茫到最后成功获得Offer的心路历程。文中不仅分享了个人的面试经历,还提供了宝贵的面试准备建议和技巧。 ... [详细]
  • 春季职场跃迁指南:如何高效利用金三银四跳槽季
    随着每年的‘金三银四’跳槽高峰期的到来,许多职场人士都开始考虑是否应该寻找新的职业机会。本文将探讨如何制定有效的职业规划、撰写吸引人的简历以及掌握面试技巧,助您在这关键时期成功实现职场跃迁。 ... [详细]
  • [附源码]计算机毕业设计JAVAjsp医药管理信息系统
    [附源码]计算机毕业设计JAVAjsp医药管理信息系统项目运行环境配置:Jdk1.8Tomcat7.0MysqlHBuilderX(Webstor ... [详细]
  • 本文讲述了一位80后的普通男性程序员,尽管没有高学历,但通过不断的努力和学习,在IT行业中逐渐找到了自己的位置。从最初的仓库管理员到现在的多技能开发者,他的职业生涯充满了挑战与机遇。 ... [详细]
  • Java毕业设计项目:“传情旧物”网站(含源码与数据库)
    本项目介绍了如何配置和运行“传情旧物”网站,包括所需的技术栈、环境配置以及具体的操作步骤。 ... [详细]
  • SQLite数据库CRUD操作实例分析与应用
    本文通过分析和实例演示了SQLite数据库中的CRUD(创建、读取、更新和删除)操作,详细介绍了如何在Java环境中使用Person实体类进行数据库操作。文章首先阐述了SQLite数据库的基本概念及其在移动应用开发中的重要性,然后通过具体的代码示例,逐步展示了如何实现对Person实体类的增删改查功能。此外,还讨论了常见错误及其解决方法,为开发者提供了实用的参考和指导。 ... [详细]
  • 解决WebStorm使用Vuewebpack卡顿问题
      我们在使用Vue时,经常会遇到项目卡顿的情况,这主要是因为Vue的webpack打包时会生成一个node_modules模块,该模块内含至少上万个文件,因而往往会造成WebSt ... [详细]
  • 在掌握Promise调用链的过程中,理解其在异步执行中的核心作用至关重要。链式调用不仅简化了代码结构,提高了可读性,还增强了程序的健壮性和维护性。类似于jQuery中常用的链式调用,如 `$(#app).show().css('color', 'red')`,Promise的链式调用通过 `.then()` 方法实现了异步操作的无缝衔接,使得复杂的异步流程更加直观和高效。掌握这些技巧将有助于开发者更好地处理异步编程中的常见问题,提升开发效率。 ... [详细]
  • 深入RTOS实践,面对原子操作提问竟感困惑
    在实时操作系统(RTOS)的实践中,尽管已经积累了丰富的经验,但在面对原子操作的具体问题时,仍感到困惑。本文将深入探讨RTOS中的原子操作机制,分析其在多任务环境下的重要性和实现方式,并结合实际案例解析常见的问题及解决方案,帮助读者更好地理解和应用这一关键技术。 ... [详细]
  • 本文深入探讨了Java枚举类型的使用与实践,详细解析了枚举的基本用法及其在实际开发中的应用。首先介绍了枚举作为常量的替代方案,自JDK 1.5起,通过枚举可以更加简洁、安全地定义常量,避免了传统方式中可能出现的错误。此外,文章还探讨了枚举在实现单例模式、状态机等场景中的优势,并提供了多个实际案例,帮助开发者更好地理解和运用这一强大的语言特性。 ... [详细]
  • 深入解析 Go 语言中的位操作技术 ... [详细]
author-avatar
下个路口见的
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有