如何利⽤Node.js构建分布式集
在软件定义的世界⾥,企业通过Web应⽤和移动应⽤程序来提供⼤部分的服务,⽽Node.js迅速成为时下最为流⾏的⼀个平台之⼀,就和它可以搭建响应速度快、易于扩展的web应⽤和移动应⽤很很⼤关系,并凭借这点成为了新的主流。作为⼤规模使⽤Node.js 的云计算服务提供商,UCloud积累了丰富的使⽤经验。
本⽂为UCloud 公司⾼级⼯程师⽂天乐在深JS⼤会上发表的演讲内容,主要介绍了UCloud内部如何利⽤Node.js 构建分布式集,并分享了实践过程中⾛过的坑,希望对正在使⽤Node.js或是即将使⽤Node.js的朋友有⼀些帮助。
UCloud内部⼤规模使⽤了Node.js 技术,利⽤Node.js研发了⼀套RPC框架,主要涉及API、Web Console、服务中间层、运营报表、内部运营⼯具和内部系统等,解决以下四个问题:
1. 服务调动发现程序间解耦;
2. ⾃动快速扩容服务能⼒;
3. 脚本语⾔⾔提⾼研发效率;
4. 配置集中管理变更应⽤⾃动加载。
架构演进
在RPC框架V1版本的架构中,如下图。从图中可以看出,是⼀个⾦字塔架构,也就意味所有通信服务需要⾸先和名字服务进⾏通信,获取到对端节点状态和IP端⼝信息,然后再进⾏通信,这样导致系统的⾼耦合,增加了系统的复杂性,这并不是⼀件好事。
图1
为此,我们改进了RPC框架架构,如图2。在V2版本中,可以看到改进的架构已是⼀个⽹状架构,实现了将所有消息出⼊⼝统⼀到RabbitMQ Server ,以便所有的通信可以在不知道对端节点状态时,就可以调⽤对端服务,从⽽实现了服务端调⽤关系解耦。
图2
实现⽅案
那么到底是如何实现服务端调⽤解耦的呢?在实现⽅案中,我们采⽤了(Node.js + Protocol Buffers + Zookeeper + RabbitMQ)的组合,从⽽实现配置集中化管理:
1. Node.js,主要⽤于开发业务逻辑。
作为天⽣的异步脚本语⾔,Node.js 使⽤事件驱动、⾮阻塞I/O模型⼤⼤提升了研发效率,⾮常适合在分布式设备上运⾏的数据密集型的实时应⽤。
我们通过 fibers库采⽤协程的⽅式来解决Node.js 异步编程匿名回调问题,将异步回调逻辑转化为同步,同时也满⾜了程序员使⽤同步⽅法编写异步程序的情怀。
2. Protocol Buffers,⽤于强约束消息定义。
3. Zookeeper,实现配置集中管理。
Zookeeper分布式服务框架是Apache Hadoop 的⼀个⼦项⽬,简单的说,Zookeeper=⽂件系统+通知机制。它主要是⽤来解决分布式应⽤中经常遇到的⼀些数据管理问题,如:统⼀命名服务、状态同步服务、集管理、分布式应⽤配置项的管理等。
4. RabbitMQ,实现异构通讯服务间的解耦。
Rabbitmq是⼀种应⽤程序对应⽤程序的通信⽅法,选择RabbitMQ的原因在于它可以⽀持集⾼可⽤、简单易⽤、性能出⾊和完善的管理⼯具(如:Web ui / Rest API )的特点。
⾛过的⼀些坑
hadoop分布式集搭建最后,总结经验避免犯同样的错,是⾮常重要的,还有⼀些技术遗留问题,需要我们⾃⾏避开这些坑。以下是我们在构建RPC框架过程中遇到的⼀些坑:
♦异步编程效率问题(Fibers)& Node.js 内存泄漏问题
在复杂在构建复杂应⽤的时候,很多地⽅都可能发⽣内存泄露,也需要考虑异步编程效率问题。为解决这两个问题,我们⽬前主要采取以下四个⼿段来解决:
a) 框架封装所有⽹络通信,业务⽅只关注业务逻辑、提⾼研发效率;
b) 通过Fibers 封装所有异步匿名函数调⽤转换为同步⽅法;
c) 谨慎选择第三⽅库。
♦异步框架中⽇志跟踪
异步程序记录⽇志乱序不利于跟踪业务逻辑调⽤路径。为解决这个问题,我们通过包装 Fibers 对每⼀个 Fiber 实例进⾏编号,在所有⽇志输出中打印 Fiber id 记录异步调⽤路径,并配合跨模块会话编号实现请求调⽤跟踪,以此解决⽇志纪录的⽆序问题。
♦ RabbitMQ HA ⾼可⽤问题
如果需要实现RabbitMQ HA ⾼可⽤特性,有两种途径可以实现:Server 端 HA 和 Client HA。Server 端的⾼可⽤性可使⽤ LVS 或HAProxy来实现,Client 端的⾼可⽤性也是⼀种选择,这样可以减少架构复杂度和层次依赖。值得注意的是,实现⾼可⽤特性时,要记得开启Queue ⾼可⽤配置。
♦ RabbitMQ HA ⽹络闪断导致节点分区问题
⽹络不稳定导致RabbitMQ HA ⽹络闪断,进⽽导致节点分区问题。针对这个问题,需要添加对 /api/nodes 进⾏监控,并及时处理分区问题。
♦ ZooKeeper Session Expired
针对ZooKeeper 会话过期问题,需要⼤家特别关注处理Zookeeper 集断开后的重连处理,因为如果重连逻辑没有处理好的话,所有依赖ZooKeeper的特性都将不可⽤。
【结语】
经过应⽤实践,⽬前看来 Node.js⼏乎可以做到其他后端语⾔所能做到所有的事情,ES6特性正式发布如今有⼈已经开始⾼
喊“JavaScript: The World's Best Programming Language”,但我也并不认为整个后端完全⽤Node.js来实现会是⼀个很好的⽅案。
本⽂中提到了Node.js的诸多优点,如异步、⾮阻塞和事件驱动等,但其也存在⼀些缺点,如默认单进程单线程不能利⽤多核,脚本弱类型容易出现运⾏时BUG,同时因为它简单易⽤,也导致了代码质量不易控制,对开发⼈员也提出了更⾼的要求。所以,就个⼈经验来看,建议偏复杂业务逻辑控制使⽤ Node.js,如果是偏极致性能的业务建议和C++等其他⽅案结合使⽤。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论