logo

百度技术沙龙第42期 Node.js 框架的实现与开发实践

作者:HelloDeveloper2019.09.01 22:03浏览量:1470

简介:9 月 14 日,由百度公司主办,InfoQ 承办的第 42 期百度技术沙龙,在北京车库咖啡如期举行。本期沙龙的主题为“Node.js 框架的实现与开发实践”,

9 月 14 日,由百度公司主办,InfoQ 承办的第 42 期百度技术沙龙,在北京车库咖啡如期举行。本期沙龙的主题为“Node.js 框架的实现与开发实践”,现场邀了百度云 Clouda 开源框架技术负责人童遥,以及苏州唐人数码科技有限公司游戏平台的搭建维护和手游开发的负责人吴中骅,围绕最近一段时间备受关注的 Node.js 分享各自的经验体会以及开发实践。其中,童遥演讲的题目是“百度 Clouda 开源框架与云端一体的设计思路”,而 Clouda 正是百度在 2013 百度世界大会上公开发布的面向开发者的开源云服务;而吴中骅演讲的内容“Node.js 单线程缺陷的多种解决方案”则能给开发者更多的实战指导。本文将对两位讲师的演讲内容分享做一个摘要回顾,同时提供相关演讲稿的下载。

 

演讲一:百度 Clouda 开源框架与云端一体的设计思路(下载演讲稿)

 

在最近几年,大家都感受到整个 App 市场的繁荣和昌盛。现在的情况是,市场变成了只有前面的比较靠头部的一些应用,能够获得整个市场的红利。但是,开发者们都深有感触,现在在做 Web App 的时候,就像在淘宝开一个店一样,很难被最终用户所搜索到,因为开发者的应用在渠道里没有任何优势。 早在 2012 年 8 月份的时候,百度就提醒开发者正在面临这样的问题:比如终端分裂的问题,比如用户需求提升但是开发速度跟不上需求。 开发者面对这样的问题该怎么办?两条路,一是加强研发实力,第二条路是在现有的研发调价下尽量努力。其实,早在两年前,百度就开始考虑如何帮助 Web App 开发者解决这些问题。只不过,一直都没有向外界披露,直到 2013 年 8 月份的百度世界大会上,百度才正式对外公布它的名称“Clouda”——一个基于 Node.js 框架云端一体的 Web App 开发工具。

 

童遥表示,Clouda 是百度现在开源的一个技术框架,所有代码对于开发者都是开放的。另外,百度的 Clouda 开发框架是 MIT 协议,开发者可以拿去用、拿去改、拿去卖,不需要再跟百度打招呼。

 

目前,百度有一个应用叫做“百度翻译”,童遥介绍这个项目的开发情况:百度只用了 3 个工程师,通过 Clouda 框架仅用了 8 天的时间,开发了一个正式产品。这个产品里包含的功能有,语音输入的翻译、有拍照识别的翻译,还有本身文本的翻译等。童遥还特别提醒,大家可以用性能比较差的智能手机下载,体验百度翻译的效果。

 

同时,童遥指出,在移动互联网的时代,我们都希望整个 Web App 产品应该是全实时的。什么叫全实时呢?大家现在所用的互联网产品,其实都是准实时的,开发者现在使用的 App 协议本身就是个准实时的协议。

 

在现实生活中,其实有很多实时性的需求没有被真正的满足,而且被开发者用一些比较接近的技术手段处理了。举一个例子,你知道现在自己兜里有多少钱吗?你可能需要拿出来数一数。如果有一天打开手机,就能看到余额,这将会带来不同的体会。很多现在线下的数据,一旦被线上实时化,你会发现它对你的生活方式将有比较大的变革,很多你看不到的需求将被发掘。

 

Clouda 设计的核心理念是什么样的?简单来说,就是以前的开发模式是客户端有客户端的语言,服务端有服务端的语言,而现在 Clouda 要实现的是一份代码写完之后,客户端也可以运行、服务端也可以运行。 那么大家有没有想过,如果我们有一天可以用 Node.js 语言同时写两侧的程序,将能够带来什么?我们将进入一个可以用云端统一的思路来开发 App 的时代。

 

以上介绍并非是 Clouda 的全部亮点。

 

传统 Web App 运行起来很慢,因为传统 Web App 所有的资源都要从服务器上下载。通过百度 Clouda 开发的 Web App 的冷启动速度是传统 App 的 1 倍以上。

 

提升冷启动速度的同时,我们提出一种开发方式叫“面向数据的开发方式”——随动反馈工程。所有的数据更新导致的变化没有一行代码是自己写的,所有数据都是从终端手机发出来的,没有任何代码在接收服务器更新,它是自动完成更新的。为什么能自动更新?因为百度 Clouda 在渲染界面的时候,已经向框架描述了数据到视图的对应关系。当数据从外面进来的时候,可以用这个单向绑定关系推出视图应该发生的变化。所以在这样的思路下,开发者只要描述一次从数据怎么画 UI,后面所有的更新都是自动进行。

 

还有一件事,是困扰大多数 App 开发者的问题:没有渠道。

 

传统的检索渠道搜不到自己开发的 App,应用商店很多移动用户不知道搜什么。例如,直接去搜植物大战僵尸,未必能排到第一个,如果排不到前三页基本上就算是没有展现。这件事情从根本上没有一个检索机制在支持做 App 搜索。

 

大家今天生活中的检索都不是简单的关键词搜索了,而是较为复杂的无法用词语简单描述的需求,例如,20 年的房贷每个月还多少钱等。这样的需求,没有办法写在 App 描述信息里。

 

所以,在 Clouda 里提供了一个被搜索引擎抓取和检索的应用框架,通过 Clouda 开发的所有应用,每一个场景都是可以被搜索引擎抓取到,这个抓取不仅限于哪家公司的爬虫,而是所有公司的爬虫只要想抓都能抓得到。

 

因为 App 被检索到了,所以获得了用户。百度希望通过 Clouda,让整个生态变得不仅是头部应用,让开发者在面对互联网那样都拥有平等的机会:如果内容足够好,就可以通过用户的需求被真实的检索到,所以这是我们希望做到的一个状态。当爬虫来的时候,它可以从云上直接抓到这个场景的结果。以前大家会谈是不是搜索引擎应该做一个模拟器集群?就是为了运行市面上所有的应用,把里面的内容抓出来。

 

最后我们分享一下,我们有一些现在跟我们在往这个方向持续发展的合作伙伴,现在大概有携程网、嘀嘀打车、大姨妈等都在用 Clouda 做开发,还有一些公司在用 Clouda 做他们的商业产品。

 

如果大家在应用 Clouda 的过程中发现了问题,请在官网上面反馈给我们。官网地址,Clouda 整个项目都开源的。一个是留个言给我们由我们改,另外一个是自己直接修改。

 

演讲二:Node.js 单线程缺陷的多种解决方案(下载演讲稿)

 

吴中骅介绍自己是 2010 年初次接触的 Node.js,因为它简单的语法和出色性能,吴中骅就开始研究到现在。目前,吴中骅主要在社区的贡献是,一个 Web 框架,还有一个 Node.js 验证码模块,两个 Ifile 和 iroute 以及 tagg2 模块。

 

在开始介绍主题之前,吴中骅先简单介绍一下进程和线程。进程可以说是一个容器,一个进程要有一个线程在工作,这些线程是共享这个进程的内存地址的,进程之间也是可以共享内存。我们需要用一定的技术手段,但不是像线程这样共享内存这么简单。线程其实是处理器调度的一个基本单位,处理器在调度任务的时候,不是调度进程,而是调度线程。

 

吴中骅介绍到,Node.js 看上去很完美,但是 Node.js 像侏罗纪公园一样,一个个缺陷就像是恐龙,可能随时会被恐龙吃掉。从互联网上来看,大家都对 Node.js 的缺陷有什么样的认识。Node.js 的缺点: 1、可靠性低、单进程、单线程:只支持单核 CPU,不能充分利用多核 CPU 服务器。一旦这个进程崩掉,整个 Web 服务就崩掉了。 2、不适合应用实时任务:并非对每一个应用程序都适用,不适合任务关键型(硬)实时应用程序(如心跳监控应用程序)或需要占用大量 CPU 资源的应用程序。

 

因此,大部分矛头都指向了一个问题:Node.js 单线程缺陷问题。由于这个原因,导致 Node.js 项目出现两个问题:1、脆弱,易崩溃,可靠性低;2、无法应付 cpu 密集型场景,单点执行过长,会卡死主线程。如果一个函数,比如说死循环然后就卡死了,影响到整个主线程。

 

说了这么多 Node.js 单线程的缺陷,我们是不是觉得一下子对 Node.js 失去信心了?但是,下面这段代码可以让 Node.js 的 Http 服务器 QPS 下降到 1 以下:

 

复制代码

var express = require(‘express’);  var app = express();  var fibo = function fibo (n){      return n > 1 ? fibo(n-1)+fibo(n-2):1;  }  app.get(‘/’,function(req,res){      var n = fibo(~~req.query.n ||1);     res.send(n.toString());  });  app.listen(8124); 

如以上的程序,非常符合 Node.js 的风格。两个波浪线的作用是将数字或者浮点变成整数。不管用户传上来是什么东西,我们都会把它取整。那么,现在这样的一个支持多线程的 JS,会不会出现卡死的情况。我们也启动了这样一个 Node.js 的进程,然后在这边先来一个 45,再来一个第三个人来了,第四个人也来了。我们只有四个盒,按以前的情况,主线程就被卡死了,但是,现在第五个人还是很快速就响应了,说明我们的主线程并没有被卡死,而我们的计算放在了工作线程里面。

 

Node.js 单线程存在的缺陷,可以通过两个解决方案来解决:一个是使用多线程来解决,还有一个使用多进程来解决。多进程和多线程的解决方案都是一个让 Node.js 单线程不足的一个方案,进程和多线程有一个区别,创建的开销非常大,进程间共享内存地址很麻烦,部分情况下无法用多进程解决方案来真正解决一些业务需求的。

 

同时,吴中骅也提到,tagg2 模块并不是很完美,它是利用 V8 的 isolate 接口和 pthread 库实现的。Node.js 主线程的一些对象、一些方法、一些速度的引用不能够传给我们的工作线程的,只能通过字符传。

 

Node.js 主线程的对象无法共享给 tagg2 的线程, 限制就是如下几点:

 

无法使用 Node.js 的 api

无法传递对象或数组的引用

无法使用 Node.js 的其他开发模块

线程中的内存也无法被主线程访问

这样一来,我们似乎又回到了之前的状况:限制太多,就算支持多线程也是没有任何意义。 这时候我们的救世主又归来了,libuv,libuv 它是一个专门为 Node.js 准备的跨平台的抽象内库,主要是为了让代码能够不受平台的控制,目的是抽象 windows 的 IOCP 以及 linux 的 libev,而写一套 API 能够在各种平台上运行,它包括有文件系统、网络系统、线程、进程。

 

那么,libuv 能帮助我们做些什么:

 

Filesystem

Networking (TCP, UDP, Querying DNS, Network interfaces)

Threads (Introducing this)

Processes

Advanced event loops

Utilities

最后,吴中骅做出这样的总结:

 

Node.js 单线程脆弱不再是问题,就算是 cpu 密集型也可以胜任

易崩溃,可靠性差可以通过 cluster 弥补

CPU 密集型任务也可以通过 child_process 和 c++ 的 libuv 来创建多进程和多线程解决

Open Space(开放式讨论环节)

 

为了促进参会者与我们每期的嘉宾以及讲师近距离交流,深入探讨在演讲过程中的疑问,本次活动依然设置了 Open Space(开放式讨论)环节。

 

在 Open Space 的总结环节,几位话题小组长分别对讨论的内容进行了总结。

 

组长童遥:基于我们刚才的 Clouda 介绍,如果大家有什么想了解的细节,或者一些具体的技术讨论,我们一起讨论。现场与参会者一起互动了包括,Clouda 分布机制,包括一些建议和 fich 的一些想法,还包括 Clouda 内部的一些机制。同时,童遥也提议大家在应用 Clouda 过程中有哪些建议,随时可以向百度提出来。

 

组长吴中骅:我们讨论一下用 Node.js 能不能做一个像样点的网络游戏。针对吴中骅老师提出的一个设问句,Node.js 是否做一款像样点的网络游戏,大家讨论的结果是非常适合,非常适合做一个实时的应用,同时讨论认为 Node.js 是以后实时性网络应用发展的主要力量。

 

OpenSpace 环节之后,现场观众也分享了他们的参会感受:

 

@zy_cloud:我在百度技术沙龙,现在讲解 node.js, 讲云端统一,看来 javascript 是趋势呀,希望公司决策层能意识到,而不是花大精力去做其他语言对 js 的转换。

 

@GoAce :@吴中骅 开发的 ifile 模块 大大提高了 node 对静态文件的服务速度 减少了 js 和 c++ 模块之前转换的次数 从而提高了速度。

 

@东郭泥:@吴中骅 分享的“node.js 单线程缺陷的解决方案”,从中了解到了很多自己之前没有怎么太关注的 Node.js 多进程、线程的实现方案,感觉非常有用! PS:吴大牛还是个 PS 高手。

 

@fox_ling2012:Clouda 理念真不错,原来秘密做了两年。

相关文章推荐

发表评论