Node代替Java可行性方案

目录

1 背景

2 业界综述

场景1:纯计算速度

测试结果

场景2:大量IO操作

测试结果

场景3:均衡的工作负载

测试结果

场景4:长时间运行的查询

测试结果

结论

3 成功案例

4 设计考虑

4.1 可维护性

4.2 问题和解决

5 方案描述

6 我的实践

6.1 应用简介

6.2 应用技术选型

6.3 应用架构

6.3.1 系统架构

6.3.2 应用运行状态

6.3.3 关键状态参数

7 笔者想说

8.1 cpu密集型任务

8.2 io密集型任务

9 参考


1 背景

之前有一个项目,面临性能上的瓶颈:这个项目是一个高频IO的跑数任务型项目,内存占用巨大,cpu也有一定程度的耗损,这个项目是基于JAVA编写的。在遇到性能问题之后,也采取了一定的拯救措施:mat分析内存泄漏、代码层面进行无用对象置空等操作,但是收效甚微,这个时候想起要能否使用node来重写java的这一块逻辑呢。

注:在此之前,笔者已经有比较丰富的node服务端的经验了。

2 业界综述

下面的论述仅借部分网友的实验非最终结论,仅供参考

下面借助部分网友提供的试验数据来说明:

测试模拟器源码:https://github.com/johnrjenson/javavsnode

为了证明Node确实可以超越Java,介绍了4种场景,在这些场景中通过使用模拟器来测试这两种技术的性能:

注释:

本测试中,为Java实现模拟阻塞IO。有些人可能会认为使用阻塞IO并不公平地比较Java的性能,但在本测试中使用阻塞IO的原因如下:①Java的JDBC规范仍然是一个阻塞规范,这意味,每当有人使用标准JDBC驱动程序连接到关系数据库时,都必须阻塞。② Apache Tomcat 8.5在2016年6月才完成了第一个非阻塞Servlet规范,这意味着绝大多数生产Java应用程序在执行IO时仍会阻塞。因此,由目前大多数组织以阻塞的方式使用Java,所以在本次模拟中,阻塞也是最具有代表性的Java。

场景1:纯计算速度

在第一个场景中,选择一个纯计算工作负载来证明Java的计算优势。分别在有和没有并发的情况下进行测试模拟,工作负载情况:

1a:①无并发;②计算500个质数;③执行0个阻塞IO调用。

1b:①有并发;②计算500个质数;③执行0个阻塞IO调用。

测试结果

1a:纯计算任务在没有使用并发时,Java速度是Node的2.1倍左右;

1b:一旦将并发加入到任务中,Java领先Node的速度降低到1.8倍。

场景2:大量IO操作

第二种模拟中,不做任何计算工作,只执行IO任务。分别在有和没有并发的情况下进行测试模拟,工作负载情况如下:

2a:①无并发;②计算0个质数;③执行4个阻塞IO调用;④处理一个5MB文件。

2b:①有并发;②计算0个质数;③执行4个阻塞IO调用;④处理一个5MB文件。

测试结果

2a:没有并发时,Node的速度是Java的3.4倍;

2b:有并发时,Node的速度增加到Java的8.5倍。添加并发后,Node与Java之间的差异更加明显。

场景3:均衡的工作负载

此场景与典型Web应用程序的请求工作负载最接近,模拟中同时执行IO和计算任务,均衡工作负载。同样,也是在有和没有并发的情况下分别模拟。

工作负载情况:

3a:①无并发;②计算500个质数;③执行4个阻塞IO调用;④处理一个5MB文件。

3b:①有并发;②计算500个质数;③执行4个阻塞IO调用;④处理一个5MB文件。

测试结果

3a:没有并发时,Node的速度是Java的1.8倍;

3b:有并发时,Node的速度增加到Java的4.9倍。

场景4:长时间运行的查询

工作负载情况:①计算500个质数;②发出一个很长的阻塞IO调用——10s响应时间;③处理一个5MB文件

测试结果

Java每秒6个请求;Node每秒64个请求,是Java的10倍

观察结果能够发现,执行长时间运行的查询,Java运行的性能大大受影响,但相同场景下,Node的性能几乎没有降低。也就是说,Node完胜Java

结论

在典型Web应用程序的真实场景中,Node确实是比Java运行速度更快、更具可伸缩性。对于Web应用程序开发来说,Node的性能是难以比拟的。由于Web应用程序大部分时间都在做IO,并且需要高并发,相比之下,Node显然是最终的赢家。

3 成功案例

领域

成功案例名称

我的案例

工具类应用

过去依赖java或者其他语言构建的前端工具类应用,纷纷被前端工程用node重写,比如vscode

前端工具类直接搬到node服务端使用

游戏开发领域

网易开源了Pomelo框架,是基于node的高性能、分布式游戏服务器框架

使用puppeteerr做自动化测试,使用puppteer做服务端截图等浏览器动作

云计算平台提供node支持

阿里云和百度在云服务器上提供node应用托管服务

小试:云函数使用

并行I/O利用

Ebay(海淘) 阿里巴巴(云原生)

 

 

高性能I/O用于实时应用

Voxer将node用于实时语言上

腾讯朋友网将node应用在长连接中

花瓣网、蘑菇街使用socket.io实现实时通知功能

实时跑数大屏

小试:在线打字PK游戏

新型物联网开发框架

Iot.js, ducktape, linkit等

其他

做实时通讯/爬虫/开发各种类型的动态网站(企业网站/商城/聊天室/直播/大量用户表单收集/微信公众平台等)

框架支持

第三方应用提供node的api支持,比如es,提供node语法和kibana语法平行使用

node+es实现搜索引擎

4 设计考虑

4.1 可维护性

开发效率,和团队协调,node都比较高。

开发效率:Nodejs语法完全是js语法,只要你懂js基础就可以学会Nodejs后端开发,Node打破了过去JavaScript只能在浏览器中运行的局面。前后端编程环境统一,可以大大降低开发成本。应用在项目开发中,开发周期短、开发成本低、学习成本低

维度

表现

备注

开发周期

短!

关注业务,极简代码风格

开发成本

低!

0s热更新,随处编码,随处调试,前端代码可移植,更简单的api使用

学习成本

低!

在有经验的node开发人员帮助下,前端人员2天转型,后端人员1天转型。

模块库

全、多、新

19年数据:开源NPM存储库(超过600000个模块),可手写模块、上传模块

4.2 问题和解决

Node.js优点很多,但是缺点也不少,但是都有对应的解决方案。

缺点

解决方案

异步API编码习惯不适应

async await配合可以解决

回调地域

async await配合可以解决

松散类型边界、编译时检查、运行时检查

模块化编程可以快速定位到问题

Node只支持单核CPU,不能充分利用CPU资源。

如果需要的话,可以分布多台低配主机(可以更省成本)

一旦代码某个环节崩溃,将会导致整个系统都崩溃

全局链条结构编码,异常捕捉

5 方案描述

java的技术方案已经非常成熟了,node的技术方案其实也比较成熟了。目前主要就是基于koa来打造服务端。

应用类型

表现

备注

WEB应用

Node关于web开发的框架,从express进阶到koa(可以理解成是express2.0版本)。

以koa为例子

目录结构

目录

备注

Biz

业务

Config

配置

Entity

实体

Node_modules

模块

Public

静态文件夹

Router

路由

Util

工具

涉及组件(常用):

组件名称

备注

Cheerio

网页分析

Jsonwebtoken

Jwt

Koa-send

文件下载

Socket.io

长连接

Superagent

服务通信

Uuid

Id生成器

Sequelize-auto

Orm框架

上线文件体积小,基本在1M以内

可以实现自动化上线。

后台运行

0S停机重载

Webstorm/hbuilderx/idea/sublime/记事本等都可以作为开发工具

桌面应用

-

有需要再分享

6 我的实践

在论证这个方案之前,笔者自己其实也做了一个长达3个月的实验。

6.1 应用简介

跑数服务 + 跑数看板,就是一个典型应用:

从上线(21.2.17)至今(21.5.20),已经稳定运行了3个月了。

这个应用特点:高频数据操作,数据量大,需要监控数据同步进步等。

6.2 应用技术选型

使用node来完成服务开发。

跑数程序特点:局部数据个性化难把握,需要结合实际机器情况以及上游服务能力,调整跑数进程和请求频率等。

对接外部程序经历:业务流程变动极大,收到的信息和实际的信息不对等等。

技术选型

app(客户端)

技术栈

版本

备注

Vue

V2.6

Element-ui

V2.13.1

Axios

V0.20

Js-md5

V0.7.3

Vue-count-to

V1.0.13

Vue-router

V3.2.0

Socket.io-client

V2.1.1

实时通信

Vue-socket.io

V3.0.7

实时通信

service(服务端)

Koa

V2.13.0

Koa-bodyparser

V4.3.0

Koa-cors

V0.0.16

Koa-router

V9.4.0

Koa-send

V5.0.1

Koa-sslify

V4.0.3

Koa-static

V5.0.0

Md5-node

V1.0.1

Mysql2

V2.1.0

Node-schedule

V1.3.2

Node-xlsx

V0.15.0

Sequelize

V6.3.5

Socket.io

V2.3.0

Superagent

V6.1.0

Urldecode

V1.0.1

Urlencode

V1.1.0

Uuid

V8.3.0

6.3 应用架构

6.3.1 系统架构

 

6.3.2 应用运行状态

应用部署使用pm2进程守护模块来部署(pm2 是一个带有负载均衡功能的Node应用的进程管理器)

C:\Users\Administrator>pm2 show 17

 Describing process with id 17 - name robot-service

┌───────────────────┬────────────────────────────────────────────

│ status            │ online                                                        │

│ name              │ service                                                 │

│ namespace         │ default                                                       │

│ version           │ 1.0.0                                                         │

│ restarts          │ 34                                                            │

│ uptime            │ 2M                                                            │

│ script path       │ E:\service-task\service.js   │

│ script args       │ N/A                                                           │

│ error log path    │ E:\service-task\logs\pm2_error.log │

│ out log path      │ E:\service-task\logs\pm2_out.log   │

│ pid path          │ C:\Users\Administrator\.pm2\pids\robot-service-17.pid         │

│ interpreter       │ node                                                          │

│ interpreter args  │ N/A                                                           │

│ script id         │ 17                                                            │

│ exec cwd          │ E:service-task                  │

│ exec mode         │ fork_mode                                                     │

│ node.js version   │ 10.15.3                                                       │

│ node env          │ N/A                                                           │

│ watch & reload    │ ✘                                                             │

│ unstable restarts │ 0                                                             │

│ created at        │ 2021-05-20T214:41:13.979Z                                      │

└───────────────────┴────────────────────────────────────────────

 Actions available

┌────────────────────────┐

│ km:heapdump            │

│ km:cpu:profiling:start │

│ km:cpu:profiling:stop  │

│ km:heap:sampling:start │

│ km:heap:sampling:stop  │

└────────────────────────┘

 Trigger via: pm2 trigger robot-service <action_name>

 Code metrics value

┌────────────────────────┬──────────────┐

│ Heap Size              │ 48.21 MiB    │

│ Heap Usage             │ 63.36 %      │

│ Used Heap Size         │ 30.55 MiB    │

│ Active requests        │ 0            │

│ Active handles         │ 9            │

│ Event Loop Latency     │ 0.06 ms      │

│ Event Loop Latency p95 │ 1.05 ms      │

│ HTTPS Mean Latency     │ 2 ms         │

│ HTTPS P95 Latency      │ 4 ms         │

│ HTTPS                  │ 0.06 req/min │

└────────────────────────┴──────────────┘

6.3.3 关键状态参数

根据上面信息,可以发现当前应用下面几个信息:

参数名称

参数解释

备注

内存占用值

80M

在开发调试阶段,监控过内存浮动过程,无明显变动

7 笔者想说

Java和Node这两个本来就没有可比性。

Java是一门语言,Node是一个运行环境。

如果非要说,哪个更好,这个命题本来就是伪命题。

注:伪命题是指不真实的命题。所谓不真实,有两种情况:其一是不符合客观事实;其二是不符合一般事理和科学道理。(看似正确却缺乏实际意义的观点)

不管Node还是Java,都有适用他们的场景。在合适的场景里头,选型正确的技术,可以简化问题、拉近目标。

Java作为一个已经有20多年历史的大佬语言,在过去和未来都会持续为解决诸如传统的web开发,cpu计算型应用发挥作用。

Node从2009年诞生至今,一直都饱受争议,但是随着各大产商的重资源投入,以及开源库、开源项目的不断涌现,无论是基于Node的项目、服务还是为Node项目提供的支撑都一直在火热中,从未衰退。从小厂到大厂,都不乏有基于Node项目。

其实Node.js作为后端能实现几乎所有应用,只是我们选择的时候考虑更多的是这个应用选择Node.js是不是最适合的。

个人觉得:技术无业界,能解决问题的技术都是好技术,我不偏向说用Node替换Java,也不会说因为Java有多年的底蕴,就拒绝用新技术解决问题。但是技术更新和迭代迅猛如今天,是否可以看看为什么会有这么多新的高级语言的出现,以及被追捧的技术,是否真的可以加速我们日常的问题的解决,如果是,为何不试试?万一就成了呢?至于网上的言论,褒贬不一,我觉得,还是亲力亲为,用过了,是否适合,才知道一二!

8 名词解释

8.1 cpu密集型任务

指进程绝大部份任务依靠cpu的计算能力完成,典型的如同科学计算,数值模拟等程序。

8.2 io密集型任务

指绝大部分任务就是在读入,输出数据,典型的例如web后端程序,主要就是在根据url请求找到对应的资源并输出。mysql的大量读写属于io密集。

9 参考

为什么有很多程序员认为Node.js的开发效率比Java高?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

独行侠_阿涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值