V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Androilly
V2EX  ›  Android

五个最佳案例带你解读 Node.js 的前后之道

  •  2
     
  •   Androilly · 2016-03-28 13:49:01 +08:00 · 11021 次点击
    这是一个创建于 3163 天前的主题,其中的信息可能已经有所发展或是发生改变。
    Node.js 是什么?

    Node.js 采用 C++语言编写而成,浏览器内核 V8 做为执行引擎; Node 不是 JS 应用、而是一个 Javascript 的运行环境。 Node 保留了前端浏览器 js 的接口,没有改写语言本身的任何特性,依旧基于作用域和原型链。

    Node.js 是一个为实时 Web ( Real-time Web )应用开发而诞生的平台,它从诞生之初就充分考虑了在实时响应、超大规模数据要求下架构的可扩展性。这使得它摒弃了传统平台依靠多线程来实现高并发的设计思路,而采用了单线程、异步式 I/O 、事件驱动式的程序设计模型。这些特性不仅带来了巨大的性能提升,还减少了多线程程序设计的复杂性,进而提高了开发效率。

    Node.js 的特点

    1 、一个 Javascript 运行环境
    2 、依赖于 Chrome V8 引擎进行代码解释
    3 、事件驱动
    4 、非阻塞 I/O
    5 、轻量、可伸缩,适于实时数据交互应用
    6 、单进程,单线程

    Node.js 能做什么?

    1 、具有复杂逻辑的网站
    2 、基于社交网络的大规模 Web 应用;
    3 、 Web Socket 服务器(页游, web IM );
    4 、 TCP/UDP 套接字应用程序;
    5 、命令行工具;
    6 、交互式终端程序;
    7 、带有图形用户界面的本地应用程序;
    8 、单元测试工具;
    9 、客户端 JavaScript 编译器

    Node.js 架构



    事件循环



    NodeJs 执行模型: 单线程 Event Loop

    当应用请求发生时,首先进入 V8 引擎,然后进入到事件队列,可以理解为他们在不断地在循环,看是否有任务,产生任务就去执行。上图是单线程模型。

    NPM

    后端在开发其他语言时,都有一些模块的概念或者第三方提供了很实用的小模块。同样, Node.js 当时出来的时候也有这样一个仓库。这个仓库就是专门用来管理中国开发者的一个贡献的模块,而且发展非常的快。同样,前端有一些脚手件,在服务器这边运行的有 debug , express , express-session , thrift ,依托这个插件做 thrift 相关的事情, images 其他的一些你想的到的插件,都是可以从它找到。

    架构体系




    上图是个推部分 WEB 平台的架构体系,个推有一套云组进资源,通过 Nginx 作为一个分发, Node 可以有多个节点,通过 session 进入。每一个 Node 都有模式,相信大家在部署的时候肯定不可能部署一个节点,部署一个节点,否则这个节点挂了就是挂了。

    Thrift 使用

    1 、定义接口




    2 、编译,生成对应的包,并上传到相应的库中
    3 、在 Node 中使用,如下:



    注意:这里有个坑

    thrift 中有个基本类型叫做 double ( 64 位浮点数)。当定义成这个类型时,数据从 java 过来到 Node 会变成全是 0 。

    解决方案

    定义成 string 类型,之后特事特办,如必要则在 Node 处再转成浮点数,或者直接由页面端处理。
    IP 负载( IP Load Balance )

    负载均衡

    分摊到多个操作单元上进行执行,例如 Web 服务器、 FTP 服务器、企业关键应用服务器和其它关键任务服务器等,从而共同完成工作任务。
    原生中其并没有负载均衡的机制,但我们可以采用动态代理的设计模式,基于 thrift client ,利用 JS 的原型链来实现。
    均衡的方式有很多种,我们使用轮询机制来实现访问多个 Java 节点。

    session 管理

    Node 本身并无 session 机制,我们可以使用 express-session 包来实现,同时通过 redis 来存储 session 。

    连接池

    传统读取数据库方式:



    连接池需要做什么?

    1 、连接预热 (启动时自动打开 n 个连接以供使用)
    2 、使用 例如 轮转法 均匀分发 连接请求
    3 、当池中的连接即将耗尽得时候动态产生新的连接
    4 、当池中的连接一段时间没有被调用的时候,自动释放连接
    5 、自动丢弃 已经坏掉的 连接
    6 、系统关闭的时自动释放所有连接

    基于此,我们也可以借助几个插件包(如 generic-pool ( node-pool )、 node-thrift-pool ,当然,如果你直接 Node 连接的 DB ,基本上那个包里面也会支持连接池)在 Node 使用连接池。

    使用示例




    利用 Node 可以做的事情

    1 、做一些灰色地带的事情
    利用 Node 可以做一些灰色地带的事情,因为它拥有前端的优点,可以异步,发起异步请求。给开发者带来很大的好处。不过,你需要管理好你的类型。如果说类型自己如果没有管理好就是会出现一些问题。同时它也可以做后端的一些事情。比如说连接池等等。
    2 、模块更加分明
    3 、可前可后便于分工
    从浏览器过来的数据,通过 Node 把这一层数据转化成 java 需要的一种数据结构,就可以使得分工更加明晰。
    4 、共用表单输入验证
    如果你在写系统的时候,出于安全考虑,无论浏览器这边做了多少验证,你都要做输入验证。传统模式下是需要 java 同学写一份,前端同学写一份。因为 Node 跟 java 都是部署在服务器集群或者一个区域,你可以相信这两边之间一个数据。来自浏览器的验证,就可以共用表单输入验证,达到节省成本的目的。

    以上内容来自个推 web 服务首席架构师姜季廷在 3 月 12 日 SegmentFault D-Day 北京:后端的演讲整理而成。
    11 条回复    2016-03-30 10:24:07 +08:00
    dant
        1
    dant  
       2016-03-28 15:38:20 +08:00
    首先我们来依赖一下 left-pad [doge]
    iyaozhen
        2
    iyaozhen  
       2016-03-28 15:42:50 +08:00 via Android
    介绍的很全面呀。赞
    ipconfiger
        3
    ipconfiger  
       2016-03-28 19:32:42 +08:00
    leftpad 一招入魂
    qile1
        4
    qile1  
       2016-03-28 20:26:59 +08:00 via Android
    会这个的可否联系我,开发个小系统,有偿的,感觉用这个好开发
    magicdawn
        5
    magicdawn  
       2016-03-28 20:38:41 +08:00   ❤️ 1
    很喜欢 node.js, 有几点比较好

    1. 社区活跃, 轮子较多, 质量高(100% coverage)的轮子比较多。各种思想的轮子较多, 例如你写单元测试, BDD 式的写厌了,可以换一种,去找一找发现有人已经实现了。
    2. 依赖。 npm 这种虽然有人吐槽,但还是很好用啊。
    3. 并发控制,剥离了线程的概念之后,你要是能处理好 callback hell ,其余部分真是太好玩了。

    缺点
    1. v8 内存狂魔啊,内存都处理不好,要你何用。。。看什么时候能优化吧...或许在微软把查克拉的跨平台 + v8 shim 做完,刺激刺激 v8
    2. 封装程度太高, 例如 net 包中的 socket, 比其他语言中的 socket 多做了很多事情。封装程度太高意味着不能操作底层进行个性化配置。
    3. 语言标准进化过快(现在是每年发布一个新版本 ES2015 ES2016 ...),几天不学新标准,看不懂 js 代码了。。。
    StephenW
        6
    StephenW  
       2016-03-29 10:23:48 +08:00
    好文,已收藏
    holyghost
        7
    holyghost  
       2016-03-29 13:46:11 +08:00
    看到 node 标准库我就想到 left-pad 啊哈哈哈哈哈哈哈
    poke707
        8
    poke707  
       2016-03-29 17:19:54 +08:00
    @magicdawn 矫正缺点 3

    只是 ES6 囤了多年才一次更新这么多。现在恰恰因为每年一个版,跨度小很多了。
    像 ES7 已经出炉了,只增加了 2 个 API 。 stage-{1,2,3} 里的估计就够发两三次新版了。
    http://www.2ality.com/2016/01/ecmascript-2016.html
    magicdawn
        9
    magicdawn  
       2016-03-29 19:58:30 +08:00
    @poke707 还是挺快的。。。貌似我想说的是变化大,加了一堆看起来没什么用的特性。
    frozen2013
        10
    frozen2013  
       2016-03-29 22:17:38 +08:00
    为毛 Nodejs 的文章发到了 Android 节点??
    Androilly
        11
    Androilly  
    OP
       2016-03-30 10:24:07 +08:00
    @StephenW 感谢支持
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2832 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 31ms · UTC 08:48 · PVG 16:48 · LAX 00:48 · JFK 03:48
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.