前言:

身边越来越多的同事谈论Nodejs,谈其异步IO、事件回调、前后台统一一门语言,创业的朋友的第一个创业项目也选择了Nodejs,期望能够使用一种语言节省成本快速完成需求开发。与其他项目组的同事聊项目选型Java时被他们嘲笑了一把,怎么这么不与时俱进怎么还在用Java。而且发现,越来越多的前端同事通过Nodejs轻松上手后端功能开发,作为后端开发工程师倍感压力。

借新项目的机会系统了解了下Nodejs的知识体系,本文对了解到的Nodejs技术作了总结,同时将其与Java的相关技术进行了总结对比,为其他考虑两种语言选型的架构师提供选型的决策依据。为了避免争议,本文避免对选型语言的推荐,也不对未来的发展趋势做出预测。

语言背景分析:

简单对两门语言进行“拼爹”对比,发现有技术深度的事情还是博士比较擅长,计算机专业的技术又未必是计算机专业的人贡献:

Nodejs

Java

Ryan Dahl,非科班出身,数学系读博士
2006开始学习网站开发,2年后成为高性能Web服务器专家,3年后创建Node

2009年的2月开始开发Node,年底发表关于Node.js的演讲

2010年由创业公司Joyent赞助开发

2013年更新缓慢、活跃度降低,纠结于稳定内核及新特性开发

2014年8月几个重要core contributor发起组织(io.js前身),此后高速发展,新功能激进、高速版本迭代、问题反馈快速回复解决,2015年5月Node.js项目和io.js项目都将加入Node.js基金会,io.js继续发展的同时进行合并,Nodejs的下一个版本将跨1.0直接到2.0

詹姆斯·高斯林,卡内基·梅隆大学计算机博士,编写了多处理器版本的Unix操作系统,是JAVA的创始人。

1995年5月23日,Java语言诞生

1996年1月,第一个JDK-JDK1.0诞生

1997年9月,JavaDeveloperConnection社区成员超过十万

1998年2月,JDK1.1被下载超过2,000,000次

2009-04-20甲骨文74亿美元收购Sun。取得Java的版权;

2014年3月19日,甲骨文公司发布Java 8.0的正式版。

2000年~今,编程语言排行榜一直在第一第二位

语言及SDK分析:

Nodejs选择javascript语法导致了其灵活、面向过程、单进程单线程执行的基本特性。然而得意其语言的灵活性,一些面向对象的特征也可以通过逻辑代码实现,但受阻于ECMAScript的发展速度,整体上Nodejs向企业级应用语法转型还暂时较慢。Nodejs主打的异步IO事件回调使其更适合服务器的编程,其单进程单线程的特质使得开发变得简单。得意与社区的活跃语言处于高速发展、SDK不断地发展稳定丰富。

相比之下,Java是面向对象的具备了面向对象的全部特征,经历了20年的发展沉淀越发的强大、稳健。与Nodejs相比Java是个在各个领域作精作深的技术巨人,然而也正因如此,学习Java的成本要比Nodejs高很大一个台阶,每一个小的技术方面都能找到很厚的一本书来。面对异步IO事件回调的新技术Java也在其新的SDK中提供支持与时俱进,相关Java的开源项目也及时跟进。

对比项

Nodejs

Java

函数式编程

非常自由,可以调用、作为参数、作为返回值

支持高阶函数、偏函数用法

Java8中支持了Lambda表达式实现函数编程与时俱进

类、接口、抽象类

原生不支持,本身是面向过程的,可利用函数实现类的定义能力。
ECMAScript 5引入Object.create(),类即对象,主流浏览器最新版本支持
ECMAScript 6引入class语法,2015年6月计划发布,还需脚本引擎开发支持
无接口、抽象类的概念,可以利用语言的灵活实现类似接口的特性能力,较为复杂

原生支持,面向对象语言基本能力,依赖接口编程降低耦合

封装、继承、多态

原生不支持
利用函数实现类似“类”的封装,利用prototype实现类似继承的能力,无多态能力
ECMAScript 6引入继承语法,2015年6月计划发布,还需脚本引擎开发支持
Nodejs中有继承的概念,但非语言级别的支持
没有多态的能力

原生支持,面向对象语言基本能力

动态

需要重启或者重新加载

依靠jvm的字节码和内存管理技术,可以实现动态编译、动态链接、动态加载、动态变更替换、热部署

异常

支持,由于异步IO事件回调导致异常捕获较为复杂。V8不会优化含有try/catch的函数又导致过多捕获异常产生性能问题。

全局捕获uncaughtException会丢失堆栈通常为时已晚。

Domain机制当前还不稳定。

支持,相对更成熟完善些,单线程异常不影响其他线程。

算法与数据结构

Node本身提供的较为简单,但开源社区相关代码高速发展中

比较稳定完善

集合Set\Map\List

api能力较弱,ECMAScript 6引入Set和Map,2015年6月计划发布,还需脚本引擎开发支持

完善丰富的集合容器,支持各种并发场景、业务特殊算法场景

事件回调与异步IO

语言级别支持,Nodejs杀手锏能力。

监听器模式实现事件回调,利用事件队列解决雪崩问题
利用事件机制充分利用异步IO突破单线程编程模型的性能瓶颈
通过异步机制使请求之间无阻塞,达到并行请求的目的,有效的调用下层资源
Linux采用线程池与阻塞I/O模拟出来的异步I/O(libeio)
Windows使用其独有的内核异步IO方案:IOCP

1.4版本开始提供NIO工具包实现同步非阻塞IO
1.7版本NIO2.0提供了异步IO的支持,支持异步IO回调接口

进程、线程

单线程单进程模式,开发成本低。
高效CPU利用需要部署多个Node.js进程,相对较为耗费资源,通信成本较高
单进程带来的稳定性可靠性问题通过负载均衡、自杀重启提升

支持多线程编程,支持并发控制,较为复杂,需要有并发开发经验
相对单进程可靠性更高、更加灵活

网络编程、WEB开发

可以十分方便地搭建网络服务器
提供多个模块快速搭建服务端和客户端,TCP/UDP/HTTP/WebSocket
本身就是个好的WEB开发框架,无须切换语言环境,但也容易造成前后端Js代码混淆

提供的还是底层API能力,由各个开源项目实现强大而专业的网络编程框架及WEB开发框架

组件模块、分包分层

package.json集合文件夹定义包,包内部可定义多个模块

通过package、类、ClassLoader、压缩包实现多维度多层次的划分和复用的能力
OSGI框架实现插件化、热部署

注解、反射、泛型

原生支持

扩展性

支持C/C++编写的逻辑扩展

支持C/C++/及其他可被JVM执行语言编写的逻辑扩展

三方开源框架选型:

语言选型后面即框架选型,好的框架可以去除很多不必要的重复工作使项目轻松获取强大的功能。当然三方开源框架的引入也带来的相应的学习成本,同样的,Nodejs框架由于发展时间相对较短学习成本相对较低,开发人员更容易了解到更多底层的实现源码,但相对的部分框架容易出现稳定性兼容性问题,加之NPM开发人员水平不一而又没有很好的审核机制,选择一些模块(尤其是C/C++模块)时需要慎重。Java三方开源框架大都已被大量企业大量使用、成熟稳定,提供强大能力的同时作了很好的封装分层,开发人员付出较高的学习成本后更多的是“傻瓜“式的使用。就WEB开发体系而言,两者都可以找到很多可服用引入的开源框架。

对比项

Nodejs

Java

数据库

针对不同数据库类型引入不同的驱动模块,Mongoose/reids/mysql

可以针对不同的数据库引入不同的驱动模块,也可以使用多个开源框架,降低数据库使用成本、不同数据源的迁移成本:
hibernate/ibatis等等

MVC框架开发WEB

Express/Koa:轻量灵活快速地搭建网站,支持多种模板,利用generatora解决了繁琐的回调嵌套

相关框架均较为成熟可靠,典型的有:
Structs:发展长达9年,稳定成熟,面对一些新的框架只能作为稍稳妥的选择
Srping MVC:为解决企业应用开发的复杂性而创建,轻量、控制反转、面向切面
阿里内WebX,其他的开源框架还有很多
Web容器也多种选择:tomcat\jetty\jboss等等,随着java支持nio也持续发展

前端模板

EJS:强大易用,语法更接近前端语言。Jade语法更接近后端语言,功能更强大

Velocity:基于java的模板引擎,阿里主流选择,内部进行了性能优化,支撑住了淘宝天猫的大流量
其他:FreeMarker、Jamon、JDynamiTe、Jbyte等

Rest开发

Restify:Rest应用框架,支持服务器端和客户端,专注Rest服务

JAX-RS:提供了一些标注将一个资源类、一个POJO Java类封装为Web资源。
Axis2:Apache项目,同时支持SOAP和REST风格的Web Service。 
Cetia4:基于Servlet API开发,可以运行于所有的Web容器中

Web Socket

Socket.IO:跨平台,多种连接方式自动切换,做即时通讯方面的开发很方便

Netty:异步的、事件驱动的网络应用程序框架和工具包

日志管理

Log4js:简单易用,winston:功能更强大,稍复杂

Log4j:输出定制、日志级别格式控制。Slf4j:简单统一的日志接口

HTTP调用

Request:建立各种HTTP请求,支持授权验证,其实功能还是非常多的,基本满足绝大部分需求。

HttpClient:Apache Jakarta Common 下的子项目,用来提供高效的、最新的、功能丰富的支持 HTTP 协议的客户端编程工具包

异步流程控制

Async:使异步流程同步化。Q是另外一种非常不错的选择,它是实现了promises接口。

asyn4j:异步方法调用框架,基于消费者与生产者模式。包括了异步方法执行,异步回调执行,异步工作缓存模块.支持Spring。

定时任务

Cron:小巧的定时任务管理模块。Later功能强大但稍微复杂

Quartz:可以用来创建简单或为运行上万个jobs这样复杂的程序,让作业变得易用管理

其他框架

社区活跃,更新非常快,但也容易存在不稳定、不兼容的风险。

Npm模块的开发人员水平不一,暂时只能依靠口碑、测试文档等条件选型

各种场景均有很多成熟稳定开源框架可供选择,公司内部通常也有自己的成熟项目

产品化分析:

就产品化而言,Nodejs虽然在各个方面都有建设,但相对Java还有很多需要继续完善发展的地方,如系统监控和性能分析领域还不如Java体系那么完善,受限于单进程单线程模式稳定性部署方面还不如Java那么灵活,灵活的脚本语言加上Nodejs发展时间相对较短使得系统的安全性还需要经受更多的考验。同时,前后端代码都可以使用到js并同时保存在一个开发分支时,单纯的依赖目录去区分前后端代码,容易造成前后端代码的混淆,相对不够清晰。但相信争议和问题都是暂时的,高速发展的Nodejs会逐步完善完美。

对比项

Nodejs

Java

编码规范

JSLint/JSHint:定义代码格式规范的规则,统一编码

CheckStyle/FindBug/Code formatter:比较完善,支持持续集成

包管理、构建

NPM:Nodejs的包管理器,模块库发展是十分神速和活跃
Makefile:linux下,依托强大的bash编程
Grunt:依托丰富的插件,NPM加Grunt媲美轻量级的Maven

MAVEN:一个项目管理和构建自动化工具,包含了一个项目对象模型、一组标准集合、一个项目生命周期、一个依赖管理系统、插件,方便、扩展性好、功能强大

部署

脚本方式启停进程进行部署
forever/pm2:进程容灾重启,Linux上支持的较好,

WEB项目利用Maven可以打包成一个war包,直接部署到容器的指定目录即可。
依赖部分容器的特性可以实现热部署,大部分还是去除流量后依靠脚本完成重启。

系统监控

但针对Nodejs的监控技术还是比较缺乏的,资料也比较缺乏

JVM提供虚拟机各项指标的监控接口,包括C++和Java的,基于此类接口实现了很多成熟的监控工具,互联网公司内将很多监控能力WEB化

性能分析

内存快照分析:node-heapdump/node-memwatch
Chrome:内存快照、CPU Profile

基于JVM的工具API实现有多种性能分析工具,可以分析CPU耗时分布、CPU调用链、CPU热点、内存分布、内存热点、线程阻塞等等。

稳定性

受限于单进程单线程的设计,稳定性需要引入多进程来解决,限制较大,相对比较耗费资源

传统的多线程、多进程、多机多机房机制,灵活选择部署,稳定性已经历过线上的长期考验

安全性

脚本语言的安全性较弱加上Nodejs的语法灵活性导致编码时较容易出现安全问题,已成立Node安全项目有针对性的分析解决Nodejs的安全问题。

相对脚本语言安全性较强,漏洞经过多年分析与解决

执行引擎分析:

在浏览器方面V8引擎大名鼎鼎赞不绝口,这也是Nodejs选型V8这个最快的Javascript执行引擎的原因。然而另一方面,V8引擎专门针对浏览器的设计也严重限制了Nodejs在服务器领域的大有作为,仿佛带着手链脚链在高速奔跑。因V8引擎的创始人和技术都是来自Java虚拟机,使用了部分Java虚拟机技术适配浏览器业务实现,所有相比之下Java虚拟机更加的成熟完善,也必然相对的复杂沉重。

对比项

Nodejs

Java

引擎概述

V8:最快的JavaScript虚拟机,参考JVM部分核心技术实现,针对浏览器需求场景而专门设计优化

JVM:成熟稳定完善的虚拟机技术及体系,各个内部模块算法等都经过深入研究形成专业领域,V8的创始人是原SUN的技术人员

内存限制

V8专为浏览器设计,最大内存占用:64位1.4GB,32位0.7GB,新生代分布对应为最大32M和16M(限制可打开,容易造成延迟,不推荐)
不能灵活的使用内存,必须严谨的为每一份资源作出安排。

可以结合系统的内存情况可以按需要设置,并且可以根据业务对内存的需求灵活设置调优。

垃圾回收

模仿JVM的分代回收。新生代晋升条件相对固定,复制回收。老生代标记清除回收(压缩解决碎片问题)

普遍分代回收,有多种垃圾回收算法可供选择,每个回收算法有多种参数可以配置调优,持续发展更新。

内存监控分析

process.memoryUsage查看内存概况,os模块的totalmem()和freemem()查询系统内存使用
--trace_gc打印垃圾回收日志
内存快照:V8-profiler/node-heapdump/node-memwatch

JVM提供C++和Java的接口可以查询详细的JVM内存及系统内存信息
可以通过启动参数打印回收日志,可以通过jstat命令实时查看
可以通过jmap或者多种工具dump内存,可以通过memoryAnalyzer等多种工具分析内存比对内存

跨平台、可移植

暂时只能支撑到Chrome浏览器支撑得了的平台

任何虚拟机支撑的平台,更为广泛稳定

扩展性

为浏览器设计,扩展性相对较差,体系还不够完善

技术体系比较深,提供多种接口方便三方扩展开发

其他一些对比:

其他一些简单对比如下:

领域

对比项

Nodejs

Java

开发工具

IDE

WebStorm

Eclipse

测试技术

单元测试

Mocha/Karma/Jasmine

Junit/TestNG/jMock

应用场景

场景

服务器编程,擅长高并发IO密集型程序项目

服务器编程、大数据、企业开发、android

开发者

来源

部分是向后台开发试水的前台人员,部分是被异步I/O吸引的后台人员

大部分还是后台开发人员

结束:

Nodejs的异步IO、事件回调虽是杀手锏能力,但其他程序开发语言也都有相应的跟进支持,但Node成功将前后端统一一门语言开发,这绝对是无人能及,吸引了大批的开发者加入。得益但又受限于V8引擎,其发展还带着包袱,但Nodejs还年轻还处在高速发展中,相信随着IO.js与Node.js合并、越来越多的开发者进行共建,Node会越来越稳定成熟。

相比之下Java是编程领域的巨人,20年的发展,越发的成熟稳定,形成完善的体系完善的生态,Android的流程再次将这门语言推到了巅峰,架构选型永远是个重点选项。

https://as.h5con.cn/articles/54118?spm=5176.100239.blogcont118673.32.8NFfUv

架构选型之Nodejs与Java的更多相关文章

  1. 记一个社交APP的开发过程——基础架构选型(转自一位大哥)

    记一个社交APP的开发过程——基础架构选型 目录[-] 基本产品形态 技术选型 最近两周在忙于开发一个社交App,因为之前做过一点儿社交方面的东西,就被拉去做API后端了,一个人头一次完整的去搭这么一 ...

  2. 管理支撑办公系统技术架构选型对照讨论(J2EE与SOA对照)

    续:管理支撑办公系统技术架构选型及相关技术应用范围.方法分析 M域办公系统改造.整合涉及到OA.业务流程.部室信息站点.部室专业管理等系统和信息共享等新需求,从信息化视角来看,内容多并且杂,这里核心业 ...

  3. paip.java 架构师之路以及java高级技术

    paip.java 架构师之路以及java高级技术 1.    Annotation 设计模式... 概念满天飞.ORM,IOC,AOP. Validator lambda4j memcache. 对 ...

  4. atitit.技术选型方法总结为什么java就是比.net有前途

    atitit.技术选型方法总结为什么java就是比.net有前途 #----按照不同的需要有不铜的法... 一般有开发效率,稳定性上的需要.. 作者 老哇的爪子 Attilax 艾龙,  EMAIL: ...

  5. Atitit.html解析器的选型 jsoup nsoup ,java c# .net 版本

    Atitit.html解析器的选型 jsoup nsoup ,java c# .net 版本 1. 框架选型的要求1 1.1. 文档多1 1.2. 跨平台1 2. html解析器特性:1 2.1. j ...

  6. 使用nodejs和Java访问远程服务器的服务

    既然这篇文章用的是nodejs和Java访问远程服务器的服务,那么咱们先用另一门编程语言,SAP的ABAP(我日常工作使用得最多的编程语言)来开发一个服务吧. 这是我用ABAP编程语言实现服务的类:Z ...

  7. 数据库周刊28│开发者最喜爱的数据库是什么?阿里云脱口秀聊程序员转型;MySQL update误操作;PG流复制踩坑;PG异机归档;MySQL架构选型;Oracle技能表;Oracle文件损坏处理……

    热门资讯 1.Stackoverflow 2020年度报告出炉!开发者最喜爱的数据库是什么?[摘要]2020年2月,近6.5万名开发者参与了 Stackoverflow 的 2020 年度调查,这份报 ...

  8. .net项目架构改造之搭建基于java环境配置一览【上】

    最近公司做了一个项目,需要嵌套在千牛的客户端上,项目代码必须上阿里的聚石塔,全程采用基于docker的自动化部署,我们的项目是基于.net架构.很遗憾 的是基于windows的docker上部署在访问 ...

  9. 【转】java架构师之路:JAVA程序员必看的15本书的电子版下载地址

    作为Java程序员来说,最痛苦的事情莫过于可以选择的范围太广,可以读的书太多,往往容易无所适从.我想就我自己读过的技术书籍中挑选出来一些,按照学习的先后顺序,推荐给大家,特别是那些想不断提高自己技术水 ...

随机推荐

  1. Android百分比布局支持库(android-percent-support)

    Android中提供了五种布局,其中用的最多的就是:LinearLayout, RelativeLayout 和 FrameLayout这三种布局,在对某一界面进行布局时最先想到也是通过这三种来布局的 ...

  2. linux内核算法---hex_to_bin分享

    这是我从内核抠出来的一段代码,用处就是传入一个字符,即可以用printf语句%d以十进制数的格式输出,同时也可以以%p地址的形式输出. 代码如下: #include <stdio.h> # ...

  3. Android 实现高仿iOS桌面效果之可拖动的GridView(上)

    转载请标明出处:http://blog.csdn.net/sk719887916/article/details/40074663,作者:skay      最近项目中遇到一个LIstview的拖动效 ...

  4. WinCE中断结构分析

    前一段时间研究了一下WinCE下的中断结构,整理了一下,希望与大家讨论. 最下面有PDF版本下载,便于保存 版权申明:本文版权归ARMCE所有,转载请保留所有原文内容及 ARMCE标识并注明出 自 A ...

  5. rails应用ajax之三:进一步完善ajax动画特效果

    本猫已经对界面放低标准很久了,但是复习了ajax之后突然发现:哇!原来世界可以这么美,这么生动鲜活的!所以本篇主要讨论下如何用ajax在rails中做一些简单的动画效果. 其实最新版的的rails中使 ...

  6. Kafka消费者-从Kafka读取数据

    (1)Customer和Customer Group (1)两种常用的消息模型 队列模型(queuing)和发布-订阅模型(publish-subscribe). 队列的处理方式是一组消费者从服务器读 ...

  7. (python3爬虫实战-第一篇)利用requests+正则抓取猫眼电影热映口碑榜

    今天是个值得纪念了日子,我终于在博客园上发表自己的第一篇博文了.作为一名刚刚开始学习python网络爬虫的爱好者,后期本人会定期发布自己学习过程中的经验与心得,希望各位技术大佬批评指正.以下是我自己做 ...

  8. 遍历输出图片加hover

    1. $(".icon a>div").hover(function () { var slls = $(this).attr("class"); sll ...

  9. private static final 修饰符

    java修饰符分类修饰符字段修饰符方法修饰符根据功能同主要分下几种 1.权限访问修饰符 public,protected,default,private,四种级别修饰符都用来修饰类.方法和字段 包外 ...

  10. jstack Dump

    jstack Dump 日志文件中的线程状态 dump 文件里,值得关注的线程状态有: 死锁,Deadlock(重点关注)  执行中,Runnable 等待资源,Waiting on conditio ...