创业团队撸 Node
前言
大家好,我是 Scott,2016 年 9 月 25 日在杭州大搜车总部举行的杭州 Node Party 上分享了一个话题 - 《创业公司撸 Node》 ,分享之后我以文字的形式又记录了一遍,分享给没有与会的朋友,也方便大家通过搜索引擎者一些技术社区平台来看到这篇文章。
写在前面,感谢芋头哥和大搜车,给了我这个机会跟大家在大搜车面基,说实话,从我出道以来,这还真的是我第一次正式在公开场合装逼,尤其是当着这么多大牛大咖的面儿装逼。
某天当你进入创业团队
今天跟大家分享的话题是,现阶段下创业团队中对于 Nodejs 工程师的认可程度,以及如果有一天你进入了创业团队,在做技术选型的时候,基于什么标准来判断,要不要使用 Nodejs 开发,以及如何跟进技术的演变。
我特意加了前端逆袭这个小标题,是为了在咱们现场做个小调查,请从前和现在做过前端开发的的同学举一下手好么,看看多少人搞了前端现在也在搞 Node。现场举手的超过一半人数,前端这个职业真的是屌爆了。
我的职业转型
ok,首先做一个自我介绍,我跟大家一样,从前也是一名前端工程师,从 2010 开始,在阿里妈妈做了四年前端,后期做了不少广告投放相关的前端页面,跟后端的创意投放管理系统对接,制作和优化广告效果模板等等,大家如果去上 Youku, 微博,各种电影小说新闻媒体网站,应该会有印象曾看过这样满屏滚来滚去的淘宝豆腐块广告。
哈哈,很不好意思,2014 年以前,你在全网看到的差不多有 70% 的豆腐块广告都是我做的,你在淘宝搜了鲜花啊,内裤啊,硬盘啊,种子啊,再去访问其他网站,都能看到豆腐块里的类似商品,当时我的工作就是开发这些模板的样式,优化这些模板的特效,测试在各种终端设备上的兼容性,数据方面需要跟各种算法引擎团队约定各种异步数据格式,业务上需要考虑复杂的参数加密解密二跳透传,Cookie 的读取定向等等来落地不同推广场景下的异步交互方案,最终基于各种广告系统接入和投放到目标网站。
所以在最初我仍然是一个很纯的前端工程师,后来怎么就开始折腾 Nodejs 了呢,我们可以看下上图最右上角的这个轮播图,它由上下两部分组成,上面是轮播的商品列表图,下面是推广的商品关键词,它俩是两个独立的数据接口,而且很可能是隶属于两个完全不同的数据引擎团队,从前端开发的角度呢,我需要发两次请求来分别获取和控制这两个数据接口的展现,而从后台开发的角度看,两个接口最好相对独立,互不影响,因此我们前端工程师,尽管很希望将两个接口合并成为一个接口,却很难推动后端工程师团队为我们这样某一个模板,专门开发一个接口出来,由这个接口统一获取两个接口数据合并后再交给前端展现,于是我们就很难从至少是请求个数这个层面,来优化这个广告的展现速度和展现完整度,有时候是图片先出来,有时候是关键词先出来,如果等待同时出来,万一某一个接口挂了怎么办,这时候再等待超时以后去获取打底的接口或者类似接口,用户早就离开了。
但是这样一个模板在全网的每天为阿里带来的收益,是非常巨量的,而它的生命周期也许只有 2 周,2 个月就撤下去换别的模板了,所以从维护的角度上,后端工程师的确也很难及时跟进前端和产品层面频繁的改动,而从收益方面,就需要跟后端工程师努力的沟通解释,非常费劲,协作成本居高不下。
但是现在有了 Nodejs 后,我们设想一下,如果把 Node 作为接口这一层,由它来决定调用哪几个接口,合并哪几个接口,哪些接口使用哪些打底数据,是不是这样的场景就迎刃而解了呢,关于这个我就不再探讨了,可能会涉及到公司保密协议,因为我后来从阿里离职出来创业了。
创业以后,开始了我的职业转型,这近 3 年时间,我一直在创业公司用 Nodejs 开发产品,我也就从一个标准的前端开发工程师逐步切换为一个会使用 Nodejs 的开发工程师,中间费了不少力气,想了解我的技术成长路线的,可以看上一篇文章 - 4 年前端狗,2 年 CTO,进入一个新的 领域,作为新人是要踩很多坑的,有的是有必要踩,有的没必要踩,我就把自己的一些心得整理做成视频,放到了慕课网上。
地址见这里:http://www.imooc.com/u/108492/courses?sort=publish
如果是刚入行的新人可以去看看,里面知识点也许有点陈旧,讲解也未必很严谨,可以选择性的理解流程和项目思路。
那么现在,我是 CampusRoom 这个网站的技术负责人,大家可能都没听过 CampusRoom, 没关系,估计部分同学听说过 Moveha,创业这几年中,无论是 CampusRoom,Moveha,还是微信服务号,包括其他的一些内部的外部的,做了没上线,上线了又下线的大小项目,统统都是用 Nodejs 来搭建的,整个创业团队也充分体验到了使用 Nodejs 建站或者启动一个项目时候敏捷所带来的高效率,其中有一个小案例,近几年,一些欧美国家不是太安全,我们为了让学生和家长能对当地的居住环境有一个安全方面的了解,就用 Nodejs 很快速的搭建了一个爬虫小系统,爬取一些州和城市的警署犯罪数据,然后合理的分类和评级打分后,给出一个数据可视化的效果,这个功能的产品价值可能是很大的,然而实现成本是非常非常小的,效果见下图:
市场对于 Nodejs 工程师的需求
以上都是从我自身,从我们公司来来感受 Nodejs 的开发效率和对公司的价值,但是整个业界对于 Nodejs 的态度又是怎样的呢,他们的接受度又是如何呢,我们再举个例子,大家可能看到过 CNode 论坛上的这个招聘贴,我截图了有赞的和大搜车的,最后一个就是我发的,也就是 Moveha 公司的招聘,哦,说一句,Moveha 是 CampusRoom 的前身,CampusRoom 是从 Moveha 孵化出来的,我要说的重点是,我发的这个 Node 工程师招聘贴,是论坛里最先被加精的招聘帖子,也是阅读量最高的帖子,现在有 4 万多个阅读量,400 多个评论,这个帖子给我带来了 100 多份简历,现在我们公司的所有工程师都是从这个帖子招过来的。
在这个帖子前后 - 2014 年秋季,在论坛或者社区中,很多公司对于 Nodejs 工程师的认知包括他们的价值定位其实是不够清晰的,从招人的风气中就能看出来,在我发这个帖子以前的时候,很多公司跑到 CNode 上发帖,都是姿态比较高,一副你爱来不来的样子,对自己公司团队文化介绍的三言两语模棱两可,薪资区间从来不敢放,自从我发这个帖子之后,逐渐的论坛的招聘贴开始接地气了开始有诚意了,薪资够不到 20K 的公司甚至都不好意思上来发帖了,从这件事情上就能反映出工程师社区的结果导向,玩虚的根本不行,结果好市场认同自然容易被人接受,CNode 上面大量的招聘也从侧面证明了,这三四年以来,Nodejs 工程师越来越被认可,越来越被重视,一个职位到底含金量高不高,其实不是你说了算,也不是我说了算,而是这个市场说了算。
我们再来看下 indeed 上面统计的职位需求变化的趋势,第一个图是 Nodejs 的需求量变化,第二个是 Fullstack 的需求量变化:
这两个职位,即便是在今天,现在依然处在井喷暴涨的阶段,整个市场已经对 Nodejs 工程师有了足够的认可,所以大家的职业黄金期真的是已经到了,再过两三年,Nodejs 工程师就会真的遍布大街小巷各种公司,现在是跟上这个大潮的最佳时期。
那为什么这么多公司对 Nodejs 工程师这么认可呢,特别是中小型团队,特别是创业团队,为什么明明可以选择 PHP,可以选择同样敏捷的 Ruby,可以选择更加成熟,程序员相对更容易招聘的 Java,Python,却非要费劲巴力的去招聘紧缺的 Nodejs 工程师呢,尤其是具备前端工程师能力的 Nodejs 工程师呢?
答案非常简单,就是因为利用 Nodejs 开发一个新项目,会非常的高效敏捷,无论从最终的用户体验,还是上线后的产品迭代节奏,使用 Nodejs 都有巨大的成本优势。
而成本对于创业公司来讲,是非常敏感的事情,现在市面上成千上万家嗷嗷待哺的创业公司,其实跟屌丝无异,不是没钱,就是没人,没钱,没人也就罢了,很多 CEO 还想要有好的用户体验,还想要有更短的研发周期,更快的迭代节奏。
说白了,也只有通过这种快速迭代和小步快跑,才能跟同类产品的大公司竞争中拿到时间差优势,最快的拿到用户反馈和市场反应,最终才能在竞争中和夹缝中杀出一条血路,现实的确是如此残酷。快速的推出产品,熬过最艰难的阶段,找准了产品的盈利点,抓住了目标用户群,有了可以拿到桌面上的各种数据,自然更有优势融资,那时候再去改进优化技术栈甚至更换开发语言也完全有足够的缓冲余地。
所以我们 Nodejs 工程师的核心价值,尤其对于创业公司,就是能够快速产出,迭代的速度更快,前端后端可以通吃,为创业公司节省巨大的人力成本,这就是为什么在市场上,Nodejs 这么受欢迎的原因,创业公司选择我们,不仅因为它能最快速的满足初创团队的场景,也是因为 Javascript 也是唯一的能跨越前后端,用一种语言搞定产品实现的选择了,关于 Nodejs 的适用场景,它的优势劣势,它的开发和维护成本,相信大家做了这么久都有自己的见解,不再过多赘述,我们且往下看。
究竟什么样的创业项目,比较适合 Nodejs 呢,或者说, Nodejs 作为创业团队立项时候所考虑的技术选型,有它适用的边界么,如果有,边界在哪里,有哪些衡量的标准。如果在创业公司,我们需要确定用 Nodejs 开启一个项目,那么以怎样的标准,或者说怎样的准则来衡量, Nodejs 怎么用,框架怎么选,版本如何跟进呢?
太多的问号在脑海中回荡,我个人认为,可以简化为如下三个问题,就能解决从决策到执行的流程:
一、要不要用 Nodejs
首先第一个,什么样的创业项目,适合用 Nodejs,哪些又不适合用,我们从这三个因素来衡量:
1. 期望的迭代节奏
任何一个产品,立项之初,都有它特殊的商业背景和商业目标,在这个背景和目标下,会给予对它的一些期望,希望它以怎样形式,多长时间开发上线,上线后,以多长的周期进行版本的更新迭代,这些都很好理解,如果是一个展示型的,扔上去不需要怎样去增加功能,也不需要多么频繁的改版升级,那么就没必要一定要使用 Nodejs,用 PHP,Ruby 统统没问题。
2. 团队工程师能力
我们知道,就像这世界的大部分事物一样,工程师的能力也是大概符合正态分布,除去特别弱的,比如 3 年前的我,除去特别强的,大部分工程师其实都处在中间的这个地带,就像现在的我,对于 Nodejs 及周边生态的掌握可能比较好,但不是特别特别好,而 Nodejs 又是一个新的职业方向,火热的市场上根本没有足够时间来沉淀,于是大部分的创业团队是并没有足够资深的 Nodejs 工程师,这意味着我们在快速开发的时候,往往也面临着更高的业务风险,一旦 Nodejs 用的姿势不对或者技术选型失误,会给业务带来灾难性的打击。
这一点其实被很多公司所忽视,整个团队在当下与未来半年的一个规模,团队成员的技术背景,自我学习的能力,对于新技术升级的接受程度,如果是不能很好的驾驭 Nodejs 而且自学能力又偏弱的话,就需要慎重考虑一下。
3. 跟产品的匹配程度
其实创业类的产品,往往很少有上来就规模化,高难度的,所以许多类型都适合,我们与其想那些可以用 Nodejs 开发,不如反过来看,那些类型的不太适合用 Nodejs 开发,排除掉这些场景,剩下的都可以评估一下用 Nodejs 是不是可以。
我这里罗列了几种,其实大家照着这个方向走,未必只有这 4 点:
极高并发数
密集 CPU 运算
高安全高可靠性
内存精密控制及释放
并发数本来是 Nodejs 的强项,高吞吐量,但是如果上来就是要应对爆发式井喷的场景,需要堆机器的时候,显然这些非 Nodejs 领域内软实力会过度消耗工程师的时间成本,这一点一旦工程师的学习能力跟不上来,就会反过来制约业务的发展,如果非要给一个数字的话,可以以 10 万作为一个衡量点,并发大于 10 万的,都要慎重评估一下。
而对于大循环的数据结构,需要长时间的运算的,对 CPU 强依赖,导致时间片释放迟缓的场景就尽量不要用 Nodejs 来做,可以交给 Scala,可以交给 Go,甚至可以交给 Java 和 C++ 来做。
举一个例子,比如有旅游路线的实时计算,对用户的出行路线进行推荐,需要基于多维度不同权重的因子进行算法推演,考虑进去用户的性别,喜好,预算,期望的出行方式,天气,当地景点的分布,目的地有没有类似 G20 的大会等等各种因素,背后则可能依靠一些大数据做支撑,这时候用户不可能等待太久,而是希望马上拿到路线报告,这些场景下我们处于中段能力值附近的工程师就不要逞强,避免使用 Nodejs。
安全可靠也同理,一些支付或者银行对接从场景,服务的稳定性非常之高,不能有任何可能异常导致的进程挂起,引起数据不一致,这种如果其他语言已经具备很好的线上解决方案的话,那么 Nodejs 就可以只做它擅长的方面,把这些交给其他更专业的技术来实现,Nodejs 只调用接口就行。
一个项目做大了之后,代码中会有更多的隐患或者风险,一个疏忽就可能导致内存泄露,而如果业务层面是对内存非常敏感的,由于内存使用不精细导致对外的服务质量不平稳,这些都是业务不能接受的,那么这样的场景也要慎重权衡一下。
其实,考虑到创业团队特定的起步方式,不平衡的工程师能力,产品迭代的节奏,只要是一些略苛刻的场景,都应该要多思考一下,用 Nodejs 除了效率,能带来的价值能否高过带来的挑战和风险,如果答案是否定的,我们就要慎重使用 Nodejs。
我们始终需要去找到一个在工程师能力,Nodejs 满足和匹配业务的程度,以及公司的产品节奏之间找到这个平衡点,而且这个平衡点会随着业务的膨胀,团队的成长而不断的变化,在变化之中我们需要不断的评估,去反思。
那么我们回到产品本身,一旦我们排除掉这些场景以后,我们就可以大胆使用 Nodejs 了,或者说,不是我们,而是更多已经大力度投入到 Nodejs 阵营中的先驱者和执行者们,比如下图:
太多全球的大公司,已经在使用 Nodejs 了,就连 微软这样印象中比较封闭刻板的软件帝国,都已经对 Nodejs 有着很大的投入,对开源有很大的包容度,推出了很多 Nodejs 好用的工具和服务,甚至要 Fork 一个 Nodejs 推出新的引擎。
甚至更另类一点的,发射太空任务的 NASA 都要用 Nodejs 来开发一些应用或者是运行一些系统,甚至是 2016 年 Github 上评选的,最受欢迎的项目中,有将近一半都是 Nodejs 相关的项目,或者有用到 Nodejs 做一些构建工作。
总结起来就是一句话,Nodejs 上天入地,刚前刚后,流行只是我们看到的现象,背后是它较低的使用门槛,较小的协作成本,以及更好的开发体验,和不错的性能表现。
二、扔掉历史包袱
虽然有这么多我们乐于看到的方面,作为一个工程师,我们依然需要谨慎对待,当我们确定使用 Nodejs 以后,如何选择版本或者语法层面的一些编程习惯,毕竟 JS 编程始终太灵活,有许多问题大家纠结好多年,而 JS 的快速进化也带来更多的编程方向,站在这个十字路口,往前一步未必是大海,往后一步也未必是悬崖,但是前进总比后退要更能接近未来。
举一个简单的例子,让很多工程师头痛了很多年的例子,就是 Callback, 这是个老生常谈的问题了,不同的团队不同的项目历史背景不同的技术风格,显然对于 Callback 的态度和选择是不同的,比如芋头哥在大搜车,对于 Callback 的态度是相对宽容的,因为几十万行的历史代码,说实话交给我维护,我也不敢乱来。
那么我个人的看法呢,Callback 显然是不爽的,是反人类的,我的观点是,初创团队,如果没有历史包袱或者历史包袱不大的话,坚决丢掉,可以直接上 Promise,因为包袱只要背在身上,只会越来越重,越来越不敢扔掉。
如果再激进一些,可以将 Promise 和 Generator Function 混用;
如果再激进一些,就结合 Babel 来使用 async/await;
我们来看一个例子,通过这个搜索框,输入学校或者城市,可以搜学校周边或者城市周边的房子。
搜索实现的路径,我这里做了最大的简化,只有两种,在以后继续升级的产品形态中,会更加复杂,比如有精确查询和模糊查询,有除了城市和学校以外的经纬度直接查询,有标题查询,也有邮编号码查询等等,他们的搜索显然都是异步的。
那么这个简化的例子,第一条路,输入学校,搜索学校,拿到学校以后搜索周边房源。第二条路,搜索城市,搜索到城市以后,搜城市里面的大学,再搜城市里面的房源。
由于我们不知道用户输入的是学校的类型,还是城市的类型,我们需要两个都查,以学校的结果为主。
如果用 Callback 的方式开发,很容易就写出这样的代码,通过嵌套就强行锁定了搜索的优先级,以及并发和非并发的次序,当然每一个异步查询都要处理一个后置的错误对象判断,这些错误不能进行合并,要分别处理 5 次,有的会中断流程,有的也许不会,加上如果使用 eslint,这里的 err 都需要单独命名,不可以重名,单从维护的角度看,如果以后要调整这里的搜索优先级,就会很头痛,相信这些事情大家都有遇到过,我们再来看第二段代码,这一段我们使用了 Promise 和 Generator Function 结合以后的一个升级版本。
很显然,这个升级直接就解决了 Callback 的几个痛点,首先是逻辑可以分拆开来,升级维护更方便,如果先以城市为第一优先级搜索,直接把底下代码整块扔上来就行了,另外,错误的捕获可以合并起来,当然也可以做更精细的控制,同时呢,比如搜索城市大学和城市房源它俩是可以并行的,我们就用 Promise 和 Generator 就能很自然的做到这件事,当然用 callback 也可以集合 eventproxy 或者 async 做流程控制,但是也会进一步引入代码的复杂度。
其实只要解决掉 Callback 的问题,我们就已经往前迈了很大很大一步了,因为我们引入了 Promise ,引入了 Generator Function,甚至可以突进到 await 和 async,这意味着底层的 Nodejs 的版本也会有更大的升级,带来更多编程思路的变化。
三、Nodejs 跟进升级
那么说到 Nodejs 的版本,我的观点是,我们需要保持对 Nodejs 大版本的跟进,因为站在 2016 年的这个节点上,其实 Nodejs 已经经过了 7 年之痒,后面的日子比前面的几年要幸福太多了,这个我可以从自身的一些经验来说下吧:
我从 2013 年开始兼职创业做我们公司的项目,那时候的 Nodejs 版本是 0.8,我一直使用到 2014 年 7 月份,才从 0.8 升级到了 0.10,然后又使用到了 2015 年春节,没有忍住,从 0.10 升级到了 0.12,一直使用到 2016 年 1 月份,再次升级到了 4.x,现在仍然保持在 4.x 的版本状态,我经历了这几次大的版本周期,感觉是这样的。
从 0.10 到 0.12 是一个比较大的飞升,从 0.12 到 4.x 是一个巨大的飞升
从 4.x 到 6.x 也将是一个巨大的飞升,当然了, Nodejs 有它特殊的历史进程,比如 0.10 的版本中,有一个重大的安全漏洞,不升级都不行,在 4.x 推出以前,Nodejs 社区还分出来 io.js 阵营,结结实实的对抗了很长时间,再往后面合并后就正常化了,只要官方推了 LTS 版本,在首个 LTS 版本之后,可以观望一个月左右,就可以考虑升级了。
当然,在 LTS 版本升级之前的至少 1 个月,我们本地的开发环境,就应该已经切换到了这个大版本了,在我们本地来开发来测试。
升级到 6.x
接下来,我们都会面临 6.x 版本甚至是即将发布的 7.x 版本,官方也罗列了一些重大的变化,我谈下我觉得需要关注的点。
1. V8 升级到 5.0.x
每一次版本的升级,都不可例外的,会优化提升整体的性能,包括安全方面的增强,文档的完善,测试用例的覆盖,但是都没有重大的引擎升级来的给力,作为一个 Javascript 运行环境,Nodejs 是依赖于 Chrome V8 引擎进行代码解释,所以 Chrome V8 的能力基本上限定了 Nodejs 的能力,那么这次,相比较于 4.x,6.x 的底层引擎 v8 升级到 5.0.x,这意味着,由于底层 v8 自身的很多缺陷和 Bug 都已经通过大升级而一下子就修复了,所以整个 6.x 的表现会跟 4.x 有很大不同。
2. 覆盖 93% 的 ES6 特性
6.x 覆盖 93% ES6 特性,则代表我们可以大胆的使用 es6 的几乎全部特性了,比如 解构,剩余参数,类啊,super 关键字啊,我们知道,往往我们在使用一个库或者框架的时候,甚至是语言,常常用到的总是那 5 成,6 成,顶天了 7 成的 API,就能完全满足我们的业务需要,那么 ES6 的覆盖率如此之高,我们的确可以敞开胸怀,去拥抱 ES6.
3. 模块加载比 4.x 快 4 倍
模块加载比 4.x 快 4 倍
,如果你是一个项目负责人,或者技术组长,那么这个对于你来讲肯定是有意义的,我们线上应用启动,或者重启的时间会变得更短,让我们的线上服务对用户来说,切换更加的平滑,由重启引起的波动也感知更小。
然而我们除了从语法层面去避免历史疑难杂症以外,我们更需要关注 Nodejs 版本本身带来的巨大差异和变化,来看一下 Nodejs 这张表,从现在到 2018 年,我们自身的技能是不断增长的,同时我们对于 ES6 的使用和了解会越来越深入,那么我们就应该选择一个未来的版本来切入技能栈,说句老实话,接下来两年我们会持续的在 6.x 的版本上跑我们的项目,那么接下来几个月就是升级线上版本的缓冲期。
搭积木一样搭建 Nodejs 应用
当我们把上面的问题都考虑清楚,剩下的事情就变得简单很多,到了 2016 年,我们并不像是在 2014 年之前那样,处在大跃进的年代,太多的变化导致太多的不稳定性,现在社区的生态环境已经相当完善。
从静态资源、Web 框架,模板输出,数据库中间件到第三方通信,消息推送各种 SDK 和 CDN 内容分发,都有太多优秀的库可以使用,我们做一些适当的定制和改造便可以拎到项目中大胆使用。
然而当我们把魔爪伸向后端,使用 Nodejs 搭建企业级应用的时候,我们抓过来的不仅是更多的价值体现,我们也抓过来更多的职责和信任,后端底层乃至团队规范都需要我们花费更多的时间去了解对接的方式,接入的阶段,不需要精通,但需要备份为基础的常识,这些软实力,是我们成为一个优秀 Nodejs 工程师的必备要素。
最后,我来对创业公司中使用 Nodejs,做一个小总结,我们在妥善处理了 运维、集群管理、性能调优等等这些传统语言已经做的非常棒非常成熟的领域,在大部分的创业公司,都可以由前端团队推动,来使用 Nodejs 去接管数据访问层与渲染层的事情,等到公司规模上来以后,就可以依靠更资深的工程师以及原来团队的沉淀,来做 比如日志、监控系统、分布式服务接入这些事情,Nodejs 的落地需要前端工程师,需要 Nodejs 工程师,更需要强大的运维之锤,了解除了 JS 以外的更多技能,比如数据库,比如系统的设计,比如接口服务,比如团队规范协作流程等等等等,在大公司可以扎根一个方向挖下去,在小公司则需要放眼天下,筹备未来。
无论是怎样的技术背景,如果有一天你进入创业公司,在立项之初,你都可以先大胆的来做一个假设或者推演,假设说把赌注押到 Nodejs 上,会不会拿到一个更快更好的结果,如果是,请毫不犹豫的选择 Nodejs。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。