苏宁的Node.js实践:不低于Java的渲染性能、安全稳固迭代快
来源:前端全栈开发学习     阅读:557
易滴互联
发布于 2018-12-03 23:33
查看主页

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

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

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

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

Web 前端系统

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

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

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

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

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

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

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

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

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

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

在服务器的 Node.js 版本上,在去年年初的版本是 Node 6.9,去年年底已经将 Node 版本更新到 Node 8 了,研发团队坚持使用 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 点,货品上新,要求此时页面不能有缓存,而且因为电商业务的特殊性,会遇到 618,818,双十一这种半夜抢购的情况,因而全靠服务器硬扛流量洪峰,这就对应用性能,提出了很高的要求。

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

并发性能优化之路

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

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

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

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

不低于 Java 的渲染性能

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

安全与稳固

除了性能,安全与稳固也是重点需要的环节。针对 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 的问题,稍微添加了几毫秒。当然这对于前面的好处来讲都是可以接受的。



本次给大家推荐一个免费的学习群,里面概括移动应用网站开发,css,html,webpack,vue node angular以及面试资源等。
对web开发技术感兴趣的同学,欢迎加入Q群:943129070,不论你是小白还是大牛我都欢迎,还有大牛整理的一套高效率学习路线和教程与您免费分享,同时每天升级视频资料。
最后,祝大家早日学有所成,拿到满意offer,快速升职加薪,走上人生巅峰。

免责声明:本文为用户发表,不代表网站立场,仅供参考,不构成引导等用途。 系统环境 服务器应用
相关推荐
js操作属性;js换肤;js可控制换肤;js操作style属性
OpenImage
NSOperation的使用
他写出了 Vue,却做不对这十道 Vue 笔试题
微信小程序向本地保存
首页
搜索
订单
购物车
我的