node端的服务逐渐成熟,不少公司内部也承担业务处理或者视图渲染工作

发布时间:2021年11月13日 阅读:512 次

node端的服务逐渐成熟,不少公司内部也承担业务处理或者视图渲染工作

需求背景

目前node端的服务逐渐成熟,在不少公司内部也开始承担业务处理或者视图渲染工作。不同于个人开发的简单服务器,企业级的node服务要求更为苛刻:

node端的服务逐渐成熟,不少公司内部也承担业务处理或者视图渲染工作

高稳定性、高可靠性、鲁棒性以及直观的监控和报警

想象下一个存在安全隐患且没有监控预警系统的node服务在生产环境下运行的场景,当某个node实例挂掉的情况下,运维人员或者对应开发维护人员无法立即知晓,直到客户或者测试人员报告bugs才开始解决问题。在这段无人处理的时间内,损失的订单数和用户的忠诚度和信任度将是以后无法弥补的,因此对于node程序的业务开发者而言,这就要求代码严谨、异常处理完备;对于node框架的维护者而言,则需要提供完善的监控预警系统。

功能

当一个服务进程在后端运行时(daemon),作为开发者我们关注的信息主要有以下几点:

服务进程是否正在运行,isalive

服务进程的内存使用率,是否存在未回收(释放)的内存

服务进程的cpu使用率,在计算量大的情况下是否需要分片处理、延时处理

服务进程的实时响应时间和吞吐量

而作为一个运维人员,关注的不仅仅是node服务进程的相关信息,还包括物理主机的使用状况:

物理硬盘所剩存储空间

内存、cpu使用率

网络接入是否正常

可以看出,不管是针对主机还是进程进行监控,我们的关注点大多数是资源使用率和业务量处理能力,因此我们的监控预警系统也着重实现这些功能。

系统简易架构

目前生产环境下的node服务大多采用多进程或者cluster模式,而且为了响应突发流量往往采用多机部署,因此监控和预警的目标实体就是多物理(虚拟)机下的多个子进程。

比如,目前node服务在单机上往往采用1+n的进程模型:所谓1,即1个主进程;n,表示n个工作进程,而且这些工作进程是从主进程上fork出来,同时根据经验,n的值往往等同于主机的cpu核心数,充分利用其并行能力。那么,采用该种进程模型的node服务部署在线上4台物理机上,我们需要监控的则是4xn个进程,这涉及到了分布式数据同步的问题,需要寻找一种方法实现高效、准确和简易的数据存和读,并且尽可能的保证这些数据的可靠性。

在这里,笔者采用了分布式数据一致系统ZooKeeper(下文简写为ZK)实现数据的存和读。之所以没有采用传统的数据库是由于读写表的性能,如为了防止多个进程同时写表造成冲突必须进行锁表等操作,而且读写硬盘的性能相对内存读写较低;之所以没有采用IPC+事件机制实现多进程通信,主要是由于node提供的IPC通信机制仅限于父子进程,对于不同主机的进程无法进行通信或者实现复杂度较高,因此也并未采用该种方式。

采用ZK来实现多节点下的数据同步,可在保证集群可靠性的基础上达到数据的最终一致性,对于监控系统而言,不需要时刻都精确的数据,因此数据的最终一致性完全满足系统的需求。ZK服务集群通过paxos算法实现选举,并采用ZK独特的算法实现数据在各个集群节点的同步,最终抽象为一个数据层。这样ZK客户端就可以通过访问ZK集群的任意一个服务节点获取或读写相同的数据,用通俗的语言来形容,就是ZK客户端看到的所有ZK服务节点都有相同的数据。

另外,ZK提供了一种临时节点,即ephemeral。该节点与客户端的会话session相绑定,一旦会话超时或者连接断开,该节点就会消失,并触发对应事件,因此利用该种特性可以设置node服务的isalive(是否存活)功能。不过,目前node社区针对ZK的客户端还不是很完善(主要是文档),笔者采用node-zookeeper-client模块并且针对所有接口promise化,这样在进行多级znode开发时更可读。

建议架构图

上图是笔者设计的监控预警系统的架构图,这里需要着重关注一下几点:

ZooKeeper部署与znode节点使用

单机内部node进程的进程模型:1+n+1

precaution进程的工作内容以及与master和worker的通信方式下面着重详述以上几点。

ZooKeeper部署与编码细节

上节已提到,ZooKeeper抽象为一个数据一致层,它是由多个节点组成的存储集群,因此在具体的线上环境下,ZK集群是由多个线上主机搭建而成,所有的数据都是存储在内存中,每当对应工作进程的数据发生变化时则修改对应znode节点的数据,在具体实现中每个znode节点存储的是json数据,便于node端直接解析。

在具体的代码中,我们需要注意的是ZK客户端会话超时和网络断开重连的问题。默认,ZK客户端会帮助我们完成网络断开后重连过程的简历,而且在重新连接过程中会携带上次断开连接的session id,这样在session未超时的前提下仍会绑定之前的数据;但是当session超时的情况下,对应session id的数据将会被清空,这就需要我们的自己处理这种情况,又称作现场恢复。其实,在监控系统中,由于需要实时查询对应节点数据,需要始终保持session,在设定session expire时间的情况下终究会出现ZK客户端会话超时的情况,因此需要我们实现现场恢复,需要注意。

node端的服务逐渐成熟,不少公司内部也承担业务处理或者视图渲染工作

进程模型

大多数开发者为了提高node程序的并行处理能力,往往采用一个主进程+多个工作进程的方式处理请求,这在不需要监控预警系统的前提下是可以满足要求的。但是,随着监控预警功能的加入,有很多人估计会把这些功能加入到主进程,这首先不说主进程工作职能的混乱,最主要的是额外增加了风险性(预警系统的职能之一就是打点堆快照,并提醒开发者。因此主进程内执行查询、打点系统资源、发送邮件等工作存在可能的风险)。因此为了主进程的功能单一性和可靠性,创建了一个precaution进程,该进程与主进程同级。

采用1+n+1模型并不会影响请求处理效率,工作进程的职能仍是处理请求,因此新的进程模型完全兼容之前的代码,需要做的就是在主进程和precaution进程执行的代码中添加业务部分代码。

通信方式

在监控预警系统中,需要实现precaution进程<-->master进程、master进程<-->worker进程、precaution进程<-->worker进程的双向通信,如打点内存,需要由precaution进程通知对应worker进程,worker进行打点完成后发送消息给precaution进程,precaution进行处理后发送邮件通知。


Tag:node端 服务 逐渐 成熟 公司 内部 承担 业务 处理 视图 渲染 工作
相关文章

发表评论: