思考

首先我们来思考一个问题:我们都知道几乎所有现代主流浏览器都全面支持了ECMAScript 5.1版标准,而JavaScript的标准是ECMAScript。那么我们就容易认为JavaScript是一种浏览器端的解释型编程脚本。那么脱离了浏览器,JavaScript还能够解释运行吗? 答案是肯定的,也就是说脱离了浏览器,在特定环境下JavaScript还是能运行的。JavaScript向来以Web网页的脚本语言而著称,但现在也可以用在许多非浏览器环境,例如node.js或者Apache CouchDB。本文就是基于NodeJS来进行探讨。

NodeJS是什么?

根据百度百科解释,Node.js是一套用来编写高性能网络服务器的JavaScript工具包。Node.js是一个可以快速构建网络服务及应用的平台,该平台的构建是基于Chrome's JavaScript runtime,也就是说,实际上它是对GoogleV8引擎(应用于Google Chrome浏览器)进行了封装。V8引 擎执行Javascript的速度非常快,性能非常好。

NodeJS并不是提供简单的封装,然后提供API调用,如果是这样的话那么它就不会有现在这么火了。Node对一些特殊用例进行了优化,提供了替代的API,使得V8在非浏览器环境下运行得更好。例如,在服务器环境中,处理二进制数据通常是必不可少的,但Javascript对此支持不足,因此,V8.Node增加了Buffer类,方便并且高效地 处理二进制数据。因此,Node不仅仅简单的使用了V8,还对其进行了优化,使其在各环境下更加给力。

Node.js的优点

1、基于V8虚拟机,可构建高性能服务器

V8引擎本身使用了一些最新的编译技术。这使得用Javascript这类脚本语言编写出来的代码与用C这类高级语言写出来的代码性能相差无几,却节省了开发成本。对性能的苛求是Node的一个关键因素。 Javascript是一个事件驱动语言,Node利用了这个优点,编写出可扩展性高的服务器。Node采用了一个称为“事件循环(event loop)”的架构,使得编写可扩展性高的服务器变得既容易又安全。提高服务器性能的技巧有多种多样。Node选择了一种既能提高性能,又能减低开发复杂度的架构。这是一个非常重要的特性。并发编程通常很复杂且布满地雷。Node绕过了这些,但仍提供很好的性能。

2、单线程

Node.js可以在不新增额外线程的情况下,依然可以对任务进行并行处理 —— Node.js是单线程的。它通过事件轮询(event loop)来实现并行操作,对此,我们应该要充分利用这一点 —— 尽可能的避免阻塞操作,取而代之,多使用非阻塞操作。

3、可利用Javascript进行后台开发

虽然让Javascript运行于服务器端不是Node的独特之处,但却是其一强大功能。不得不承认,浏览器环境限制了我们选择编程语言的自由。任何服务器与日益复杂的浏览器客户端应用程序间共享代码的愿望只能通过Javascript来实现。虽然还存在其他一些支持Javascript在服务器端 运行的平台,但因为上述特性,Node发展迅猛,成为事实上的平台。

4、非阻塞IO

Node采用一系列“非阻塞”库来支持事件循环的方式。本质上就是为文件系统、数据库之类的资源提供接口。向文件系统发送一个请求时,无需等待硬盘(寻址并检索文件),硬盘准备好的时候非阻塞接口会通知Node。该模型以可扩展的方式简化了对慢资源的访问, 直观,易懂。尤其是对于熟悉onmouseover、onclick等DOM事件的用户,更有一种似曾相识的感觉。

5、RESTFUL API

二、为何接触NodeJS,我们的问题以及解决方案

本人现在在IBM公司实习,参与公司云办公系统的项目研发,本人所在项目组主要负责在线电子表格的开发工作。项目前端开发是基于DOJO框架,后台主要基于JAVA。项目功能性开发已经基本完成,但是在实际测试阶段发现在编辑超过一定阈值的大数据的情况下系统开销比较大,运行效率无法满足要求。

在经过大量跟踪测试及分析后,基于系统的整体架构以及解决该性能问题,我们有两套解决方案:1、由于现在系统词法解析采用的是开源语法分析器ANTLR,而ANTLR在效率上还略有不足,因此我们决定基于ANTLR来进行二次开发,寻求一些改进;2、建立前端服务器,和后台服务器进行分离。前端与后台共同维护一致的数据模型,前端服务器主要解决运算方面的请求并将计算结果及时反馈用户,然后将改变发送到后台服务器,由后台服务器进行持久化存盘、消息分发等一些操作。

由于前端是基于DOJO框架进行的开发,为了最大限度的重用前阶段实现的功能代码来我们考虑基于NodeJS来搭建前端服务器,并充分利用NodeJS的一些特性来实现系统性能的提高。

三、为何选择NodeJS

我想不仅仅是Node.js,当我们要引入任何一种新技术前都必须要搞清楚几个问题:

    • 我们遇到了什么问题?
    • 这项新技术解决什么问题,是否契合我们遇到的问题?
    • 我们遇到问题的多种解决方案中,当前这项新技术的优势体现在哪儿?
    • 使用新技术,带来哪些新问题,严重么,我们能否解决掉?

Server端阻塞是当前系统遇到的最大问题。在整个数据查询的过程中,当前程序进程往往只是在等待结果的返回,这就造成了进程的阻塞。对于高并发、计算任务较大以及I/O密集行的网络应用中,一方面进程很长时间处于等待状态,另一方面为了应付新的请求不断的增加新的进程。这样的浪费会导致系统支持QPS远远小于后端数据服务能够支撑的QPS,成为了系统的瓶颈。Node一向是这样来标榜自己的:“在node中除了代码,所有一切都是并行执行的”。这句话的意思是说,Node.js可以在不新增额外线程的情况下,依然可以对任务进行并行处理 。Node.js是单线程的,它通过事件轮询(event loop)来实现并行操作,对此,我们应该要充分利用这一点 ,尽可能的避免阻塞操作,取而代之,多使用非阻塞操作。我们搭建前端服务器主要用于处理前端大量的公司计算并将计算结果及时呈现给用户,所以能够避免很多I/O阻塞操作,这样就能充分利用NodeJS的优点同时也能够满足我们的需求。另外,我们前端基于的DOJO框架是基于JS的,而NodeJS在处理JavaScript的优势在前面已有介绍,这里不再赘述。

JS适合解决阻塞问题

解决阻塞可以引入事件处理机制解决这个问题,在查询请求发起之前注册数据加载事件的响应函数,请求发出之后立即将进程交出,而当数据返回后再触发这个事件并在预定好的事件响应函数中继续处理数据。而JavaScript,相对于其他语言,至少有两个关键特性决定它特别适合完成这个任务。

(一) JavaScript是一种函数式编程语言,函数编程语言最重要的数学基础是λ演算(lambda calculus) ,即函数对象可以作为其他函数对象的输入(参数)和输出(返回值)。这个特性使得为事件指定回调函数变得很容易。特别是JavaScript还支持匿名函数,通过匿名函数的辅助,我们很容易实现回调。(二)JavaScript的另外一个重要语言特性:闭包(Closures)。该特性可以使异步回调的运行上下文保持,即"状态保持"。

四、使用NodeJS带来的问题以及解决方案

阻塞式编程浪费了大量进程资源只是在等待,导致大量内存和cpu的浪费。在这方面Node.js好很多,但也正是因为一些闭包等JavaScript内建机制也会导致资源的浪费。看下面的代码:

Js代码:

1 function main(){
2 var id = "1";
3 var str = "..."; //这里局部变量str存储一个2M的字符串
4 db.query("selcect name from persons where id=" + id,function(name){
5 output("person id:" + id + ", name:" + name);//n秒后数据返回后执行回调
6 });
7 }
8 main();

至少整个数据查询过程中,变量str所使用的2M内存并不会被释放,而str保持下去可能并没有意义。前面已经解释过闭包的原理,闭包并没有智能到只包起来今后可能被访问到的对象。

初识NodeJS,一个基于GoogleV8引擎的Javascript运行环境的更多相关文章

  1. PhantomJS是一个基于WebKit的服务器端JavaScript API

    PhantomJS是一个基于WebKit的服务器端JavaScript API,它基于 BSD开源协议发布.PhantomJS无需浏览器的支持即可实现对Web的支持,且原生支持各种Web标准,如DOM ...

  2. vsCode怎么为一个前端项目配置ts的运行环境

    vsCode为一个前端项目配置ts的运行环境,ts文件保存的时候自动编译成js文件: 假设此前端项目名称为Web:文件结构如图 1. 在根目录中新建一个“.vscode”文件夹,里面建一个“tasks ...

  3. 基于vs2015的rdlc报表运行环境部署

    先说明一下,rdlc报表是由visual studio来支持的,不是FM. 本次项目采用的是vs2015开发的,当中使用了ReportViewer报表. 两种方式可以支持开发rdlc报表环境: 1)在 ...

  4. Docker学习笔记之二,基于Dockerfile搭建JAVA Tomcat运行环境

    前言 在第一篇文字中,我们完全人工方式,一个命令一个命令输入,实现一个 java tomcat运行环境,虽然也初见成效,但很累人.如果依靠依靠脚本构建一个Tomcat容器实例,一个命令可以搞定,何乐而 ...

  5. 基于Dockerfile搭建JAVA Tomcat运行环境

    前言 在第一篇文字中,我们完全人工方式,一个命令一个命令输入,实现一个java tomcat运行环境,虽然也初见成效,但很累人.如果依靠依靠脚本构建一个Tomcat容器实例,一个命令可以搞定,何乐而不 ...

  6. 部署一个基于python语言的web发布环境

    ---恢复内容开始--- 1) 一门面向对象的语言 2)拥有丰富的库 3)可移植性 4)免费.开源 5)简单易易学 可做软件开发.人工智能.web开发等等 部署流程: Cnetos7.5+Nginx+ ...

  7. sublime text3配置javascript运行环境

    步骤一 安装node.js 官网下载链接:node.js 步骤二 Sublime 依次点击 菜单栏 Tools => Build System => New Build System 步骤 ...

  8. Vue.js 运行环境搭建详解(基于windows的手把手安装教学)及vue、node基础知识普及

    Vue.js 是一套构建用户界面的渐进式框架.他自身不是一个全能框架——只聚焦于视图层.因此它非常容易学习,非常容易与其它库或已有项目整合.在与相关工具和支持库一起使用时,Vue.js 也能完美地驱动 ...

  9. [转载]JavaScript 运行机制详解:再谈Event Loop

    https://app.yinxiang.com/shard/s8/sh/b72fe246-a89d-434b-85f0-a36420849b84/59bad790bdcf6b0a66b8b93d5e ...

随机推荐

  1. Unix内核中打开文件的表示

    Unix内核中已经打开文件,通过三种数据结构表示: 每个进程的进程表中的记录项,包含打开的文件的文件描述符表,与之关联的是: 文件描述符标识 指向一个文件表项的指针 内核为所有打开文件维持一张文件表, ...

  2. 在eclipse中使用正则表达式进行搜素

  3. l段子

    段子简介 L段子起源.L段子是开发者根据市场调查, 用户可在等候列车,飞机,或在公交车上无 聊之余使用本应用.打发无聊的时间,分为段 子,图片,活动和个人中心,用户可根据自己 喜好进入不同的区域.段子 ...

  4. 第二篇:白话tornado源码之待请求阶段

    上篇<白话tornado源码之一个脚本引发的血案>用上帝视角多整个框架做了一个概述,同时也看清了web框架的的本质,下面我们从tornado程序的起始来分析其源码. 概述 上图是torna ...

  5. Python之路----------生成器

    一.列表生成式 想想如何创建一个列表[0,1,2,3,4,5] l = [0,1,2,3,4,5] 如果上面的列表元素足够多的话,是不是会写很多代码?看看列表生成式怎么写 #列表生成式 l = [x ...

  6. Url获取图片流并打包~

    因为公司项目需求,做一个所有数据以excle的格式汇出,其中包括了图片. 而数据库保存的是图片的url,虽然不知道为什么....如果数据量大的话, 那么所有数据汇出,包括图片的话... 额.. 不知道 ...

  7. multiwii 2.4配置页面中文注释

                                                                                                         ...

  8. IOS遍历方式

    NSArray* arrays = @[@"1",@"2",@"3",@"4",@"5",@&quo ...

  9. windows shell api SHEmptyRecycleBin 清空回收站

    HRESULT SHEmptyRecycleBin( HWND hwnd, LPCTSTR pszRootPath, DWORD dwFlags ); hwnd 父窗口句柄 pszRootPath 将 ...

  10. Android--带你一点点封装项目 MVP+BaseActivity+Retrofit+Dagger+RxJava(二)

    1,昨天我们基本上把MVP给封装起来了,今天接着昨天的东西来结合RxJava把Retrofit把网络框架简单的封装一下,先看一下我们今天实现的效果: 哈哈 ,还是昨天的效果,好吧 ,我认错. 2,由于 ...