职场文秘网

首页 > 心得体会 > 学习材料 / 正文

一种基于Node.js,的校园高并发Web,应用架构

2023-02-07 18:55:07

袁文光

(长沙商贸旅游职业技术学院 网络中心, 长沙 410116)

高校校园Web 应用服务平台承载了学校众多业务系统,日常承担着师生海量在线并发访问请求。师生线上业务办理、信息查询、文件上传下载等均属网络、磁盘I/O 密集型操作。师生线上活跃程度越高,平台的网络和磁盘I/O 承载压力越大,给Web 系统带来的负担越重[1],往往导致访问速度下降、响应时间过长、请求失败,甚至出现系统崩溃等问题。随着高校的办学规模的扩大和教育资源的丰富,Web 应用平台的服务能力逐渐不能满足学校发展需求。传统的解决方法大多是通过横向扩展提升平台的并发和数据处理能力,然而单纯的软硬件数量的扩充并不能从根本上解决问题,因此,需通过纵向扩展法提升服务器单机系统的I/O 能力。本文拟提出一种基于Node.js 的Web 应用架构,为解决校园Web 高并发性能问题提供一种新方法。

Node.js 最早衍生于RyanDahl 的一个Web 项目,其将V8 引擎从Chrome 浏览器中剥离出来,并做二次封装[2],使V8 引擎在服务器端状态更佳,突破了JavaScript 只能在浏览器环境中运行的局限。在后端Web 应用的开发中,JavaScript 不再依赖浏览器的解析,可随意访问本地文件,直接操作数据库[3]。由于JavaScript 异步、非阻塞I/O的特性,Node.js 不断完善的功能及丰富的第三方库,使其在高并发的应用场景中优势凸显。Node.js拥有两项核心技术:一是事件驱动、单线程;
二是异步、非阻塞I/O。

1.1 事件驱动、单线程

Node.js 可将用户请求抽象成事件,按照事件机制处理用户的并发请求,并用线程循环监测事件。当监测到事件发生时,将该事件添加到事件队列中,线程不必等待事件处理完成,即可持续监测和触发新事件。在单线程模式下,可以同时处理海量请求,避开了多线程模式下系统需要不断创建、销毁线程及在线程间切换管理所需的开销和复杂性,使Node.js 对系统内存的依赖程度更低,消耗的系统I/O 资源更少。

1.2 异步、非阻塞I/O

Web 系统是典型的I/O 密集型应用系统,Web 应用性能瓶颈主要在于I/O 操作,包括磁盘I/O(连接数、机器性能等)、缓存服务、网络I/O等。在异步I/O 方式下,遇到I/O(磁盘/网络)操作时,线程不会被阻塞挂起,也无须等待操作结果,可另行处理其他请求,大大提高事务处理效率。在同步I/O 方式下,要同时处理多个请求,必须开启多个线程,需耗费大量的系统内存资源。

2.1 多线程框架

当前,各高校主流的Web 服务器如IIS、Apache、Tomcat 等,都是以多线程机制应对高并发请求[4]。譬如Apache+PHP,虽然PHP 是单线程语言,但Apache 为多线程机制,一个外部请求触发一个Apache 线程,同时开启一个PHP 线程。以创建一个线程消耗2 M 内存计算,标配16 G 内存的服务器,理论上也只能创建8 000 个线程。当线程数超过线程池上限时,服务器响应请求的数量会骤减。因此,多线程框架可以处理的用户请求数量,受限于服务器物理内存的大小。同时,系统在多线程模式下,进行线程频繁开启、销毁、上下文切换、状态同步等操作时,需额外消耗CPU、I/O 资源,使系统资源紧张加剧。

2.2 同步、阻塞I/O

校园 Web 系统的编程语言(JAVA,ASP.net等)基本是多线程、同步、阻塞I/O 机制[5],在与用户建立连接时,每个连接都创建一个线程。N 个连接,服务器上就有N 个线程。线程在执行I/O 操作时,经常会被阻塞,需在整个I/O 操作完成后才能继续执行。譬如:传统服务器(Apache、Tomcat)采用了I/O 阻塞机制,每条数据写入数据库都要等待一段时间(等上一条写完再写下一条),导致I/O占用的资源无法及时释放,后续任务需持续等待,降低了系统资源利用率。

2.3 横向扩展

针对高校Web 系统的性能问题,传统的解决方法主要是增加服务器数量,搭建服务器集群及数据库集群等。增加服务器数量的横向扩展法,虽能暂时提高并发能力,但多线程架构易导致平台硬件资源紧张,同步、阻塞I/O 会导致服务器资源利用率降低,建设成本高昂等问题。因此,从单机系统出发,修改、优化、强化系统架构,实施纵向扩展法,提升服务器并发能力,非常必要。

3.1 应用架构设计

Node.js 具有事件驱动、异步I/O 等特性,能满足高校高并发Web 应用需求。结合Node.js 技术特性,通过构建新架构、多服务器技术集成等可提升服务器单机性能。架构设计的重点是提升系统应对密集型磁盘I/O 操作的能力,其分层架构如图1 所示。

图1 Web 应用架构设计

架构纵向分为服务、缓存、数据、消息队列4层。每一层承担相应职责,分工又合作,共同构建高效系统。

(1)服务层纵向分割为负载均衡层、业务逻辑层、基础服务层。负载均衡层实现负载均衡功能,接收HTTP 请求,将静态、动态请求分别分发至静态资源服务器和Node.js 服务器。业务逻辑层主要处理业务逻辑,调用基础服务层处理用户请求,并将结果返回用户浏览器;
使用局域NPM(Node Package Manage)包服务,将业务逻辑层的各功能纵向拆分;
实施分布式部署,且各功能独立成模块并分别部署为一个微服务,使用消息队列、Rest 请求等,保持各微服务间的通信,可充分调用高速缓存,将高频数据的读写从数据库迁移至内存,降低磁盘I/O 频次。基础服务层实现文件存储、权限管理、日志记录、异常处理等功能,为业务逻辑层提供基础支撑。

(2)缓存层纵向分割为缓存访问层和缓存更新层。缓存访问层为上层提供缓存服务,访问和更新缓存;
缓存更新层实现系统缓存更新,接收队列信息更新RabbitmQ 的消息。

(3)数据层纵向分割为数据访问层和数据存储层。数据层调用Node.js 的数据接口,访问和更新数据库,数据存储层可以是关系数据库(MySQL、SQLserver) 或者 NoSQL 数据库(HBase、MongoDB)。

(4)消息队列层可降低系统耦合度,增加系统内聚性,构成异构系统,实现服务器间或业务间的消息接收和发送(如数据库更新、用户注销、缓存更新等)延缓耗时的I/O 操作,使系统具备更好的扩展性和维护性。

3.2 基于Node.js 的高并发架构的实现技术

如图2 所示,基于Node.js 的Web 应用架构实现技术主要包括负载均衡、Cluster 多核、功能模块化、高速缓存、数据库、RabbitmQ 消息队列等技术。

图2 高并发架构的实现技术

(1)负载均衡技术

负载均衡层处于架构的第一层,是网络用户请求的开始。使用HAProxy 编制路由规则,通过负载均衡算法,将请求分为动态和静态两类,将静态请求直接路由至静态资源服务器,将动态请求分发至不同的业务服务器,以平衡各服务器的负载。HAProxy 适合负载较大的Web 应用,能支持海量并发连接,同时,HAProxy 具备可视化的管理端,实时监控服务器负荷,配合人工调控,可达到最佳效果。

(2)Cluster 多核技术

Node.js 默认单进程单线程模式,默认模式下的Node.js 只能使用服务器多核CPU 中的一核,造成资源浪费。为了充分利用多核CPU 的计算资源,Node.js 内置Cluster 模块,以创建多个进程,由多个进程共同提供服务。Cluster 多核技术发挥了多核CPU 的优势,可以很好地用于集群式部署。

(3)功能模块化技术

作为主流前端开发语言,JavaScript 的显著缺点是缺乏完善的模块机制,必须使用<Script>#标签来引用文件。Node.js 制订了CommonJS 规范,完善了JavaScript 语言,使其在前后端都能运行。Node.js 的包管理器 NPM 是基于 CommonJS 的Package 规范实现的。

局域NPM 仓库实现业务功能模块化,如图3所示,局域NPM 仓库系统按照业务逻辑进行功能拆分,分解成相互独立的模块,模块之间通过接口调用。

图3 局域NPM 仓库设计

(4)高速缓存技术

在高并发环境下,Web 系统性能瓶颈集中于磁盘I/O。因此,在Web 服务器与数据库间设计加入Redis 缓存数据库,以降低磁盘I/O 频次。Redis是内存数据库,数据直接写在内存,也直接从内存中读取,避免直接读写磁盘。具体而言,对于实时性高的数据杜绝用户直接访问磁盘数据库(DB),而是访问缓存数据库,降低磁盘I/O 频次。如图4所示,Redis 实现缓存中数据的读取和更新,同时监听消息队列并更新缓存,保证数据的一致性。

图4 高速缓存实现技术

(5)数据库技术

在Web 系统中,数据的读操作远多于数据的写操作,一个写操作尚未完成,读操作将无法进行。在高并发背景下,为解决用户的读和写操作的冲突,设计主从数据库,以实现读写分离,即主数据库进行写操作,从数据库进行读操作。采用Keepalive 双机热备技术保证主从数据库中内容的一致性和安全性,可有效减少数据读写的时间,其设计如图5 所示。

图5 Keepalive 双机热备

图 5 中,Master 数据库、Slave 数据库互为主从,但master 只进行写操作,slave 只进行读操作。主从数据库通过keepalive 做成高可用,当master出问题,由slave 接替master 工作,即读写都在slave 操作。当master 恢复正常,master 自动同步故障时间段数据,接替slave 的写操作。

(6)RabbitmQ 消息队列技术

RabbitmQ 消息队列技术优点有:延缓业务逻辑执行,缓解应用的负载压力;
解耦应用,各模块间更加独立,提高了开发效率;
构筑异构应用,可使用不同技术实现内部应用。

4.1 测试指标

对所构建的基于Node.js 的Web 应用架构进行压力测试,主要测试响应时间、响应率和吞吐量等并发性能指标。响应时间指用户从开始发起请求到接收返回信息所耗用的时间,一般取平均值;
响应率代表系统在规定时间内,成功处理的请求占总请求的百分比;
吞吐量则表示系统在1 s 内最大能处理请求的数量。

4.2 测试方法

上述并发性能指标需通过系统关键路径进行测试验证。系统关键路径由系统外部响应、CPU计算、I/O 操作等构成。Web 系统用户的注册过程包含外部响应、CPU 校验、数据库I/O 读写等环节,因此,选择Web 用户注册这条关键路径进行架构指标压力测试。

4.3 测试环境

基于控制变量的方法,分别搭建多核+Node.js和Apache+J2ee 两种不同架构的Web 应用,编制相同的业务逻辑和数据库,并部署于硬件完全相同的2 台服务器上,配置为操作系统CentOS,CPU型号为Intel(R)Xeon(R)CPU E5-2430@2.20 GHz,物理核数为6,线程数量为12,内存16 G,安置在同一局域网内,以降低网络传输的不稳定可能带来的偏差。使用Apache 自带工具,对两种不同架构搭建的Web 应用进行性能测试并加以比较。两种架构实验条件配置如表1 所示。

表1 Node.js 和Apache 实验条件配置

4.4 测试实施

对两种架构搭建的Web 应用的关键路径(用户注册模块接口)进行压力测试,在模拟高并发场景下分别向这两台服务器发送测试请求(10 次到20 万次不等),比较两种不同架构的服务器响应时间、响应率和吞吐量的变化,结果如图6、7、8。

从图6 可以看出,当并发数小于1 500 时,Node.js 和Apache 的平均响应时间差距很小。随着并发数的增大,Node.js 与Apache 的平均响应时间差距拉大,Node.js 的响应时间显著低于Apache,表明在面对高并发问题时,Node.js 的处理更高效。

图6 平均响应时间比较

由图7 可知,当每秒并发数小于4 500 时,Node.js 和Apache 请求响应率基本持平,随着并发量的增大,Node.js 请求响应优势明显。

图7 请求响应率比较

由图8 可见,随着并发数增大,Node.js 和Apache 的吞吐量均有所降低,Apache 不断创建和销毁线程的开销,线程间频繁切换的开销,制约了其高并发处理能力,而Node.js 则具有更高的吞吐量。

图8 吞吐量对比

本文提出了一种基于Node.js 的高并发Web应用架构,通过纵向扩展法提升服务器单机并发性能。与传统的多线程、同步阻塞I/O 架构相比,面对海量用户请求,使用Node.js 和多服务器技术集成构建的Web 服务器,处理更高效,优势更明显,可大幅提升Web 应用服务平台的处理效率,改善用户体验,能为高校校园网业务提供更优质的服务平台。

猜你喜欢 磁盘线程内存 实时操作系统mbedOS 互斥量调度机制剖析现代电子技术(2022年8期)2022-04-13它的好 它的坏 详解动态磁盘电脑爱好者(2020年18期)2020-09-26基于国产化环境的线程池模型研究与实现网络安全技术与应用(2020年1期)2020-01-07创建虚拟机磁盘方式的选择网络安全和信息化(2019年10期)2019-11-26解决Windows磁盘签名冲突电脑爱好者(2019年2期)2019-10-30笔记本内存已经在涨价了,但幅度不大,升级扩容无须等待电脑报(2019年31期)2019-09-10“春夏秋冬”的内存当代陕西(2019年13期)2019-08-20Windows系统下动态磁盘卷的分析与研究电脑知识与技术(2017年14期)2017-07-10内存搭配DDR4、DDR3L还是DDR3?电脑爱好者(2015年21期)2015-09-10计算机中的多线程问题科技传播(2013年22期)2013-08-15

Tags: 并发   架构   校园  

搜索
网站分类
标签列表