苏宁的Nodejs实践不低于Java的

白癜风医院有哪些 http://www.xftobacco.com/m/
          作者

禹立彬      编辑

薛梁      前端Node.js的使用场景大多集中在前端工具上,当前的前端主要把它定位为辅助。苏宁易购使用Node.js作为前后端分离的主要手段,经历了从技术引进到全面开花,从边缘功能到核心业务,从纷乱到稳定的过程。同时Node.js作为新引入的技术,与公司原有架构融合衔接面临着怎样的挑战?以下是苏宁技术总监禹立彬老师在7月深圳ArchSummit全球架构师峰会上的演讲整理。(点击“阅读原文”查看12月7日北京ArchSummit架构师峰会日程)  

在苏宁引入Node.js之前,苏宁已经有了成熟的技术架构。

苏宁的技术架构,由苏宁云、基础支撑、后台、中台和前台组成。苏宁云主要为业务开发提供云服务。基础支撑,包括数据连接协议、防火墙、日志、中间件、短信等。在苏宁云和基础支撑之上,业务开发分为前中后台。而Web前端,主要集中在前台上。包含PC端、移动WAP端等。

Node.js的应用非常广泛,在不同的公司,可以用作微服务,也可以用来提供API,苏宁引入Node.js,最主要的,是用Node.js做中间层,当做一个Web渲染器,渲染页面,来实现前后端分离。

Web前台系统

在前台系统里,以前的开发模式,完全是Java技术栈。Java系统,分为JavaService服务器,和JavaWeb服务器,JavaWEB服务器读取JavaService服务器提供的接口,通过FTL模板来渲染页面。

引入了Node.js以后,苏宁研发团队的目标是使用Node.js替代JavaWeb服务器的渲染位置,使用Node模板,去替换Java模板,去除了模板文件谁写这样的模糊地带,让后端的Java工程师,只写JSON服务,实现前后端分离。

在应用前后端分离后,显式的获得了一些好处,Node.js系统的迭代速度优势明显强于JavaWeb,包括由于Node.js的轻量,带来的快速开发快速迭代,以及减少了前后端沟通上的“联调”时间成本,加快了项目的开发速度。同时,减少老项目里Java后台工程师写页面导致的一些BUG,提高了代码质量。

由于以上的这些优点,现在苏宁易购的Node.js项目越来越多,逐渐深入到核心业务。最早期,苏宁只是在用户体验收集这样的边缘页面使用Node.js,现在已经在海外购,小程序,大聚惠,我的易购,香港站,购物车等业务中都广泛的使用了Node.js,这样就不可避免的直面更多的技术挑战。

    Node.js如何融入已有技术架构  

当只是作为边缘业务时,Node.js项目尚可以通过一些临时方案,或者引入试点,来逃避,但是深入核心业务后,Node.js项目很快,就会被纳入总的技术架构里。

这是一张比较简单的Node.js应用部署图。一个Node.js应用被访问时,会使用公共的负载均衡,使用应用防火墙,当达到Node服务器时,要使用物理机和虚拟机,Node服务器要访问JavaService服务器也需要连接协议。

最简单的是IaaS,在这个层级上,Node可以完全可以复用苏宁云成熟的网络,存储,物理机,虚拟机等资源。

到了虚拟机这个层级,在这幅Node.js服务器图上,可以看到单台Node服务器,有一个Nginx,来做访问的accessLog和做反向代理到本机的Node.js应用端口,这台机器上同时安装了PM2,来启动多个Node应用,对应不同的端口,来提供对外服务。

在PaaS这个层级上,苏宁也尽量沿用了公司已有的技术资源。比如在操作系统方面,使用了RedHatLinux,尽量向已有技术架构靠拢。

在服务器的Node.js版本上,在去年年初的版本是Node6.9,去年年底已经将Node版本升级到Node8了,研发团队坚持使用LTS版本的Node.js。到Node有大版本更新时,同时更新PaaS平台的Node版本。

在Nginx上,选择的也是已有的通用Nginx版本,Node服务器对Nginx版本要求不严格,Nginx监听多域名的80端口后,反向代理到Node端口就好。

Redis的情况要麻烦一些,Node.js由于进程的原因,遇到Session这样需要多进程或者多服务器直接共享数据时,就必须借助Redis。很显然,Java体系内,并没有对应的Node版本的Redis客户端,于是苏宁自己编写了一个基于ioredis的Redis客户端,来满足需求。

在DB上,苏宁则遵循总的技术架构要求,Node服务器不直连DB,要获取数据时,永远是连接Java服务。

    监控报警  

解决了服务器环境后,Node也要接入日志服务和报警系统。通过配置Nginx日志格式和PM2的日志插件pm2-logrotate来将日志格式符合总技术架构的日志平台要求,并在日志平台上配置4XX和5XX报警,并且针对Node本身的一些特色,编写PM2插件,监控Node进程异常,并发送异常到苏宁内部的即时通信团建上。

    CI/CD发布系统  

服务器好了,代码编写好了,也需要发布。利用公司的统一发布平台,在平台上新建了Node.js标准发布,统一了Node代码包打包方案,统一了代码部署目录,统一从内部私库安装NPM包,统一了应用重启的方法。

除此之外,为了满足公司的总技术架构要求,苏宁研发团队还编写了基于Node的调用链监控组件,可以适配ESB/RSF通信协议的客户端组件,以及适合Varnish下的KOA,EXPRESS中间件。

    技术挑战  

解决了技术架构要求方面的问题,Node可以正规军上岗了,核心业务又会带来更高的技术要求。

以大聚惠页面为例,大聚惠是苏宁的一项营销业务,很多优惠活动,是通过大聚惠的名义放出的,因此业务非常重要。又因为运营需要,总是在凌晨0点,货品上新,要求此时页面不能有缓存,而且由于电商业务的特殊性,会遇到,,双十一这种半夜抢购的情况,因此全靠服务器硬扛流量洪峰,这就对应用性能,提出了很高的要求。

这个项目上线的时候,恰好是升级了Node8,研发团队把框架从express转换为KOA,写了一样的代码,压测时,4C4G单机才40TPS,而同样的Java系统,单机约为TPS,性能差距明显。

    并发性能优化之路  

首先考虑是缓存问题,经过排查,在KOA下,并不会默认开启,模板缓存,导致每次总是去硬盘读模板,当然快不了。果断优化,TPS上升为TPS,依然差距明显。Express框架中会默认开启模板缓存,而默认的KOA2并不会开启,首先开启模板缓存性能提升明显。

另外,通过CPU-PROFILER排查,发现路由消耗的时间挺多,匹配字符串路由,和匹配正则路由,时间消耗差距明显,于是将路由排序,优先选择字符串路由,将TPS推向TPS。

再查,为了减少并发,除渲染模板外,Node还在业务里,合并了静态资源地址,并且中间件加载的策略也可以优化,去除掉一些可以不用的中间件。比如只用EJS模板,那么就去除其他模板引擎的支持,通过这些优化,讲TPS提升到了TPS。

TPS没有提升后,再排查,发现include函数执行时间很长,发现ejs源码处理include时,总是去硬盘里查找是否有被include的模板文件,而这个页面是多人开发,include使用非常频繁,再进一步优化,终于达到了TPS。

    不低于Java的渲染性能  

最后,获得了不低于Java的渲染性能。很多文章博客对待Node渲染页面时会两级分化,一极认为Node不适合做这种CPU密集型操作,另一极就是不断宣扬Node性能强劲,但是在苏宁实际的应用中,从来没想过超过Java多少倍的性能,事实上也是。Node的基础性能略高于或者持平于老的JavaFTL渲染器。

    安全与稳定  

除了性能,安全与稳定也是重点需要的环节。针对Node.js来说,客观的说,安全文档方面是不如Java等语言的。

一方面是最后后来者,追赶前辈需要时间,另一方面也是Node.js的固有问题。Node.js是单线程的,代码报错会导致进程退出,在Node生态早期,会直接导致Node访问挂掉;

第二个,JS是弱类型语言,很多人认为弱类型的语言写的没有安全感,没有代码检查;

第三个,NPM很好,开源社区很强大,组件很多很方便,但是对于企业用户来说,都抵不过一个left-pad事件,公网的NPM包也会良莠不齐,如果出现了安全漏洞,影响就会非常大。

    问题如何解决  

NPM包策略。苏宁使用公司的私有NPM仓库来安装NPM包,避免外网扰动,导致无法安装问题。在核心业务中,限制使用不流行的NPM包,减少风险。在package.json里的包版本,使用确定的版本,不用符号,减少包升级导致的bug。对于自己开发的NPM包,严格进行单元测试及安全测试,进一步的减少风险。

使用PM2。针对Node进程挂掉的问题,苏宁使用了留下的PM2,来保证Node进程的存活。当Node进程挂掉时,PM2会重启他们。感谢PM2,通过它,也实现了发布的无缝重启,保证了平滑升级。

    Node.js系统的相对安全  

安全上,苏宁强制了所有的Node系统加入应用防火墙WAF,使用基于KOA的安全中间件XSS,尽量使用精确匹配的路由,减少注入。并在上线前,做完全的安全测试,实现Node系统的相对安全。

前端团队的挑战

另一方面,由于引入了Node,前端工程师对Node相关的知识了解较少,也会犯一些低级错误,技术挑战也是非常大的,知识要求被增加了很多。

为了解决这个问题,苏宁成立了专门的前端架构组,为各业务团队保驾护航。在发布,配置,安全监测等各个方面帮助业务开发团队。

全栈技能提升计划

并在工作中,加强Node技能培训。梳理出容易犯的低级错误,比如promise不写catch,某个条件分支里,不写请求返回,通过宣讲的方式,提高代码质量,并组织代码评审等活动,进一步的提升技术能力。

    Node.js的影响  

可以说,进入了核心业务,前端团队遇到的挑战是越来越大的,同时,Node的推进也带来了一些正面负面的影响,时间有限,不做太多的讲解,仅举几个方面。

第一个方面,项目更敏捷了,Node.js发布不涉及后台服务,即使发布出了小问题,也可以快速再次发布和回滚,因为Node.js系统其实是可以24小时发布,对业务支撑显然更迅速敏捷。运营商务。都显然的欢迎Node。

同时,Node的引入,也对前端团队带来了影响。Node的引入带来了前端工作量的增加,需要更多的前端工程师投入。

另一方面,也显著的提高了团队的技术活力,在团队内部刮起了全栈风,技术更活跃,解决问题的方案也更多了。

最后还有一些小型的负面影响,定位bug时,时间有所增加。需要查Node的问题,还是Java的问题;另一方面,访问性能因为HTTP的问题,略微增加了几毫秒。当然这对于前面的好处来讲都是可以接受的。

    嘉宾介绍  

禹立彬,苏宁技术总监,十年Web前端开发经历,中国最早一批前端开发者,历任西祠胡同前端负责人,途牛旅游网前端架构师等职务。现任苏宁消费者平台研发中心前端技术总监,负责苏宁易购网站前端领域的技术管理工作。在基于Node.js的前后端分离,ReactNative/Weex开发上有丰富的技术实践经历。

12月7日北京ArchSummit全球架构师峰会上,来自美团、百度、阿里、快手的讲师齐聚一堂,共同分享“打造Native体验HybridApp实践”、“定制统一可维护的前端架构”、“10年双十一前端关键技术”和“同构WebApp的另一种探索”的分享。

会议开幕倒数第10天,购票联系票务灰灰

文章已于修改


转载请注明:http://www.guyukameng.com/html/11401.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了