随着无线端的快速普及,前后端分离技术走上前台,而Node由于它的一些特性被工程师快速接受尤其是前端工程师,所以产生了很多Node是否会引起新的技术变革的讨论。我本人是淘系的一个Web开发人员,基本上经历了淘系关于Node和Java技术选型讨论的过程,所以今天我给大家推演一下在像淘系这个环境下Node能否会成为主流的Web开发技术,当然后面也给出了我认为比较适合的场景。
Node火了!在百度中搜索Node可以得到w个结果,图书出版方面1年月到15年6月年时间有近0种相关的Node书出版,实践方面国外公司PayPal、LinkedIn、groupon也都在使用,国内大公司阿里、腾讯、百度也都有实践项目在尝试。这让我想起了当初Nosql新出来是一样的场景,大家都一窝蜂的涌上去拥抱新技术,获取新技术带来的红利。
Node很火的另一个推手是当前的无线技术流行,很多应用从传统的PC开发要转到无线等多端,这种情况下渲染层和逻辑层的分离变得重要起来,而Node刚好可以很好的渲染前端页面,所以我们的开发同学不遗余力的在推广Node技术。
Node能够火起来最重要的原因还是它的确给我们的开发带来了很多好处:
基于事件驱动
无阻塞I/O
Node还有其它一些优点如单线程、RESTfulAPI等,总体来说Node是为轻量级的分布式的实时数据服务这类应用提供运行容器而设计的,这类应用很容易想到微博、Facebook这类典型场景,需要非常实时化、个性化、高并发的数据服务。
为什么火了?今年由于无线终端的兴起,后端要提供基于JSONAPI的数据接口非常普遍。目前来看公司还存在两种形态:一个是无线作为新系统独立存在于传统PC系统;另外一种是将无线系统合并到老的PC系统,在一个系统里同时支持多端服务。长期来看无线和PC系统的合并是必然,业务上以无线为主,PC仅仅作为一个终端而已,不可能存在无线和PC两套业务逻辑。
那基于无线和PC业务合并,由一个系统提供多终端、多语言适配的角度来看,Node能否在其中扮演传统服务端MVC中的V角色?
要回答这个问题,我们再设想一下,在多端情形下,需要怎样的交互:PC、手机端、Pad、TV、Car、Watch等其它移动终端。
是Native还是H5?当前移动端主要还是以Native实现为主,从用户体验角度来考虑Native的实现要比H5更流畅,同时Native还可以基于本地做很多在浏览器里不能做的优化,如大数据的存储、可以定制的通信协议、更方便的保持长连接以及更容易实现的实时消息推送。
当然H5也有其无法比拟的优势,客户端更轻量级,服务端发布更迅速,不需要用户升级版本等。长期来看移动端能否会向早期PC那样也从富客户端转向浏览器呢?
我的判断是未必,有几个因素,首先Native实现性能优势相比H5会好很多,当前移动端都在追求极致体验的时代,无疑APP会比H5有很多的优势;其次,移动端屏幕较小,基于网页的交互和APP相比还有很多限制。最重要的是不同的商家是主推带有品牌标识的APP还是向统一的浏览器靠拢,从目前的趋势看,APP会是手机端上争夺的重点。所以推测直接基于手机端的浏览器的应用不会成为主流前端。
如何实现快速迭代?基于APP的Native如何解决客户端更新和服务端的快速迭代,这个问题是当前正在着力解决的,目前为止有两种思路:一种是客户端用同一种技术开发,然后通过工具编译技术把它编译成不同平台上能够执行的代码,如当前的Reactor.js;另一种思路是将客户端中经常需要更新的模块做成动态推送的,用模板+数据的方式,在不同的客户端平台上实现一个小的解析引擎来实现快速个性化的定制,目前手淘主要采用后面一种实现方式,当然前一种也正在尝试。
那么再说回来,基于前面的这些推断,多终端和服务端交互主要是数据+模板的方式为主,那么服务端提供格式化的数据将成为必然选项。所以涉及到的问题就是服务端既要提供格式化的数据(HttpJSON数据),又要支持传统的PC的方式:基于JSON数据渲染出HTML页面,所以很容易想到将渲染层独立出来用Node完成。
真的靠谱么?既然Node可以带来这么多好处,那么我们不妨就继续向下推演,看是否真的很靠谱?下面看下Node在我们的实际的开发环境中如何使用,在引入Node之前我们有必要先介绍下当前Web服务端架构:
[图1]传统的web架构
在当前这种架构下Node怎么融入进去呢?最保守的一种方案是将当前的JavaWeb中的VIEW层从MVC中独立出来,交给Node来完成,JavaWeb只提供基于JSON数据接口给Node调用,架构图变成了如下的形式:
[图]Node作为渲染层加入到传统架构中
很明显的差别是在我们当前的访问路径上多增加了一个Web代理层,而这一层和当前的Web服务器层怎么看都有点别扭,两者同时存在始终觉得有一个是多余的,那么Node能否替代掉Nginx成为Web代理服务器呢?理论上是完全没问题的,就像我们用PHP来代替JavaWeb开发一样,不过你放到具体的公司运维体系中,你会发现目前在Nginx上的防攻击、限流、数据埋点、热点cache等模块都要在Node上重新开发一遍,最重要的是用Node取代Nginx并不能带来额外的好处,如果你说Node可以渲染页面,那么Nginx的开发会和你讨论Nginxlua模块和Node哪个更合适,所以用Node取代Nginx作为代理服务器也不太现实。
那么Node能否取代前端台的Web系统,成为主流的MVC框架呢?
未必!Node和JavaWeb一样可以提供MVC管理功能,一个系统中同时存在两套MVC框架显然不合理,那么如果用Node来替换JavaWeb的话,服务端的架构变成如下的:
[图]Node替代JavaWeb
从技术实现上这种架构没什么大问题,就是用Node上的MVC框架如express来替代JavaWeb中Webx,也就是用JavaScript替换Java,以及整个运行容器和中间件都要替换,那么是否真的带来那么大的好处呢?
我们从语言特性、开发效率和成本因素三个方面来看,Node作为后来者能否比我们现在的Java更优秀。
如何联合索引查询?JavaScript作为Node上运行的语言和Java相比,优缺点很明显。JavaScript语法简单,很容易编写基于事件的驱动的实现。但是JavaScript基于面向对象的描述能力偏弱,不像Java是真正的面向对象语言,同时JavaScript的对数据类型定义也比较单一,要么是数值类型要么是字符类型。很明显Java更擅长构建复杂逻辑的大型应用程序,在这一点上JavaScript明显落于下风。
在语言运行效率上,JavaScript本来是解释执行,而Java是编译执行,但是由于Node做了优化,所以运行效率差别不大。
开发效率开发效率可以从语言的复杂度、程序员培养、开发工具包的丰富性以及编码效率几个方面比较。
语言的复杂度。Java和JavaScript从开发角度都不需要关心内存的管理,都是基于虚拟机来管理内存,从并发角度来看:JavaScript是基于事件触发的,而Java是基于线程的,JavaScript更占优势。另外JavaScript是无阻塞I/O的,在I/O效率上JavaScript也更占优势,虽然Java8也将更好的支持异步I/O。
程序员培养。目前Java语言仍然是仅次于c语言的第二大编程语言,而JavaScript排查第10位,Java程序员队伍要比JavaScript大很多,很显然Java程序员招聘要比JavaScript更容易一点。
开发工具包。一个语言的开发效率很多时候要这个语言的支持工具包和组件的丰富性,Java经过这么多年的发展,工具类库已经非常丰富,几乎你想要的工具类库都能在网上找到。JavaScript虽然也发展很长时间,但是基于JavaScript的工具类库主要集中在前端,能够直接用于Node上的仍然很少,当然Node的社区非常活跃,可以预见Node的工具类库增长也会非常迅速。但是短时间内要达到Java的规模尚需时日。
编码效率。Java语言的运行基于JVM,但是Java的部署效率稍差,而JavaScript使测试更加简单,容器重启更快,但是debug机制仍然不完善,所以很难做debug测试。
成本因素前面主要是从技术角度考虑,但是如果往Node迁移的话,成本也是一个考虑因素。
首先是学习成本。公司大部分是Java程序员要往Node迁移很明显这个学习成本会非常巨大,即使这个迁移是逐渐的,长期来看仍然是要将一部分Java程序员替换成JavaScript程序员,不管这个程序员是公司内培养的还是从外部招聘的,我们可以算一下帐,公司招聘一个程序员的成本有多大:一个普通的工程师的年薪假定有10w以上,猎头费一般是年薪的0%以上,也就是w,再加上一个月的实习成本1w,加在一起约w,对于一个有1w以上开发的大公司成本可想而知,即使是招聘应届生,由于应届生的培养周期更长,所以学习成本会更高。
其次是环境成本。公司的基础服务产品,如中间件都是基于Java开发的,如果要替换成JavaScript必然要再开发一套,还有配套的运维工具等,这个成本也可想而知。
最后是维护成本。Java和JavaScript都是基于容器运行,JVM和v8引擎相比,程序员显然对JVM更熟悉。另外从排查问题的难易程度来看针对JVM的工具显然更完善。
从上面几个方面来看,当前在阿里要让JavaScript完全取代Java作为后端开发语言,基于Node用JavaScript实现整个服务层逻辑显然成本会比较高。
换个角度我们再换一种角度推演一下,假如我们现在的Web系统都用Node实现,那必然有很多Java工程师会做Node的开发,因为我们现有的前端工程师人数肯定是支撑不了现有的业务发展的。我们假定一部分Java工程师愿意学习JavaScript成为全栈工程师,但是是否同一个人愿意用两种不同的语言完成同一个任务呢,正常来说,如果我能用同一个方式完成全部工作,我为什么要把一个任务分成两种不同的方式来完成,这显然也不太合理。所以部分前端同学通过要求后端同学也学习JavaScript,来达到让后端同学来使用Node这显然有点打错算盘,不过后端同学学习JavaScript可以实现页面的JS交互逻辑倒是可以替代前端的工作。
怎么办?基于前面的分析,Node不管是在现有基础上单独增加一层还是要整个替换JavaWeb层都不太合理,那是否意味着这种前后端分离的思路有没有合理之处?有没有更好的实现呢?
传统的MVCWeb软件架构将渲染层独立出来交由前端同学控制有其合理性,在当前的多终端开发模式下,将业务逻辑层和前端渲染层分离有利于提升后端的开发效率,后端只需要