APP下载

Node.js对多种数据库协同访问实践
——以图书馆短信服务系统为例

2019-08-02刘红卫

天津科技 2019年7期
关键词:代码短信数据库

刘红卫

(泰达图书馆档案馆 天津300457)

0 引 言

数据库几乎是信息管理系统开发中的标配。数据库的应用,使得数据的管理井井有条,数据的利用也非常方便。在一个信息系统中一般都是访问一个数据库,但也有一些特殊的系统,尤其是在原有多个信息系统上建立整合的应用系统,往往要对多种类型数据库进行访问,以便对那些分散在异构数据库中的数据进行协同访问,然后再将数据重新整合进行利用。

1 图书馆短信服务系统

随着信息技术的进步,移动互联网普遍应用,短信已经不是人们之间通讯的主要手段,但是短信以其随身性和及时性,依然是当今作为推送服务信息不可或缺的方式。

笔者所在的图书馆自 2007年开始,应用短信系统开展图书馆服务,至今已有十多年的时间,旧的短信平台系统是一台中国移动定制的硬件设备,配合短信猫的使用才能做到全网短信的发送,短信的业务逻辑实现也是在这台设备上配置的。

2018年中国移动公司将短信平台升级为云端方式,称为云 MAS平台。为了继续保持短信服务的开展,我们考察云 MAS平台的功能,发现其只提供了普通短信的发送功能,用户通过浏览器直接登录云 MAS平台,通过操作页面的方式进行短信发送,没有提供像旧版本那样,能与本单位系统相结合来定义的业务短信的配置功能,但是提供了HTTP、SDK、CMPP等方式的短信网关接口[1],需要自行编写程序、开发系统。新的短信服务系统的相关数据库和网络拓扑如图1所示。

图1 数据库访问和网络拓扑图Fig.1 Database access and network topology diagrams

在图 1中,LAS服务器上运行着图书馆核心管理系统,读者借阅和图书单册信息存储在 Oracle数据库中。eCard服务器上运行的是读者证卡管理系统,为了避免读者接收到无关的服务短信,读者可以自己定制所需要的短信类型,此项功能包括在 eCard系统中,读者信息(包括手机号码)、读者定制服务信息和消费信息存储在 DB2数据库中。短信服务器上运行短信服务管理系统,也就是需要开发的系统,需要发送的服务短信内容存放在本机的 Mysql数据库中(在旧系统中有定制服务短信内容的Web系统,后台是 MySql数据库,这部分沿用,无需重新开发,如此也可以缩短新系统的开发时间)。对于读者手机号及所借图书的到期情况等信息,需要从 LAS的Oracle数据库和 eCard的 DB2数据库中提取,然后将数据组装成一条短信内容,通过中国移动(CMCC)短信网关提供的HTTP接口发送出去,最后将相关发送情况进行登记。

图书馆短信服务系统,涉及的服务短信的类型如图2所示。

图2 服务短信类型Fig.2 Type of SMS service

上行短信是读者发给系统的,由 CMCC网关接收转发到系统,系统接收分析后按要求提取信息再反馈给读者。下行短信由系统按照读者的定制情况直接发给读者。另外,短信的发送有 2种情况,一对多是同样的短信内容发给多个读者,一对一是对不同的读者发送不同的短信内容。上行短信的反馈信息都是一对一形式。

目前,Node.js凭借其优秀的性能受到全球各大公司的重视,如 eBay、Microsoft、PayPal、Uber、Yahoo等,国内阿里巴巴、百度、腾讯等也在很多的项目中应用,可见 Node.js的发展已经很成熟,它能快速创建大规模的网络应用,处理高吞吐量的实时连接。Node.js有 Windows、Linux、macOS、SunOS、AIX等系统平台版本,因而具有良好的跨平台可移植性,可以在 Windows上开发,然后部署到 Linux等其他系统上[2]。

短信服务系统的服务器,采用的操作系统是CentOS 6.10版,综合以往基于 Linux系统的开发经验,以及 Node.js对 Mysql、Oracle、DB2数据库系统的强大支持和良好的性能,我们最终采用 Node.js进行短信服务系统的开发工作。

2 数据库的访问

Node.js是通过数据库访问模块实现对数据库访问的,访问不同类型的数据库需要加载不同的模块,这些模块的使用过程包括安装、连接配置和访问操作。

2.1 模块的安装

在短信服务系统中涉及的数据库类型有 Mysql、Oracle和 DB2。Node.js访问数据库的模块可以在npmjs.com搜寻,这里有厂商官方提供的以及个人编写的很多模块,良莠不齐,具体采用哪个需要甄别。我们根据模块的使用量和使用效果选择了 mysql、ibm_db、oracledb这3个模块。

mysql模块的安装比较简单,只需使用命令 npm install mysql安装即可。而 oracledb、ibm_db这 2个模块,首先需要根据操作系统下载并安装驱动程序,然后再进行编译和安装。下面将安装过程中需要注意的问题进行总结。

2.1.1 ibm_db模块

选择 Node.js 8.12版。首先,安装 gcc和 gccc++(即g++,在CentOS中称为gcc-c++),安装后gcc版本如果是 4.7,需要升级到 4.8,再安装 devtoolset-2-gcc、devtoolset-2-binutils、devtoolset-2-gcc-c++ 3 个软件包,它们会被安装在/opt/rh/devtoolset-2/root/中,要注意在/usr/bin中建立它们的软连接,以便使用。

然后,安装DB2客户端程序,在/app文件夹中释放linuxx64_odbc_cli.tar.gz,再在/etc/profile文件中增加以下环境变量。

export LD_LIBRARY_PATH=/app/clidriver/lib:$LD_LIBRARY_PATH

最后是安装 ibm_db。使用命令 npm install ibm_db并注意此时在系统环境中不能有IBM_DB_HOME变量定义,否则无法安装,如果变量已经定义,则用 export n IBM_DB_HOME命令去掉。当安装过程提示访问权限问题时,使用下面的命令:

npm install --unsafe-perm=true --allow-root ibm_db

命令执行完成后,进入 node_modules/ibm_db目录中,首先需要定义变量 export IBM_DB_HOME=/app/clidriver,然后执行以下命令:

node-gyp configure build --IBM_DB_HOME=$IBM_DB_HOME --IS_DOWNLOADED=false -verbose[3]

在编译过程可能会有警告出现,不用理会,只要执行过程中没有报错就说明安装成功了。

2.1.2 oracledb模块

首先,安装 oracle instant client,12.2.0.1.0 版,可到 oracle官网下载 instantclient-basic-linux.x64-12.2.0.1.0.zip文件,解压缩到指定目录。

然后,把下面的内容写入环境变量文件/etc/profile中:

export ORACLE_HOME=/app/instantclient_12_2

export PATH=$ORACLE_HOME:$PATH

export LD_LIBRARY_PATH=$ORACLE_HOME:$LD_LIBRARY_PATH

export TNS_ADMIN=$ORACLE_HOME/tns

最后,安装 oracledb 模块,运行命令npm install oracledb[4],如果出现访问权限问题,则使用下面的命令安装:

npm install --unsafe-perm=true --allow-root oracledb

2.2 连接方式

首先,引入模块并定义数据库连接参数,再建立数据库的链接,然后执行 sql查询语句并获取数据,最后关闭连接。下面是使用mysql模块获取预设的短信内容的例子。

下面代码是执行查询语句并获取数据。

其他数据库访问模块的使用方法大同小异,只是一些代码细节有所不同,如 oracledb中使用connection.execute语句来执行 sql查询语句获取数据,具体使用方法还需仔细阅读相关文档。

3 数据库连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能[5]。

在 Node.js中可以方便地使用数据库连接池技术,以oracle为例,在oracledb中连接池的最大连接数poolMax缺省是4,通过代码可以设置。

var oracledb=require('oracledb');oracledb.pool Max=10;

下面一段代码是短信服务系统中完整的应用oralcedb连接池的例子。义数据库连接池的名字

使用数据库连接池技术,并发执行数量越大时比普通连接方式越有明显的优势,程序执行效率高,支持的最大并发执行数也会远超普通连接。

4 数据库的异步操作

Node.js的异步处理是其精华所在,可以有效地利用资源,提高系统的性能,更好地改善用户的体验,同样会提高对多种数据库协同访问的效率,但也使编程的难度提高了很多。传统的 Node.js在处理异步问题时,一般采用callback回调的方式,callback回调存在一个很严重的金字塔问题——大量的回调函数慢慢向右侧屏幕延伸的一种状态[6]。回调函数嵌套过多,可读性极差,容易出错,形成“回调地狱”。

Promise为 Javascript中的改进铺平了道路。EcmaScript 2017以 async和 await语句的形式,在JavaScript的 Promise之上引入了语法糖。它们允许编写基于 Promise的代码,就好像它是同步的,但不会阻塞主线程[7]。

在Node.js版本8中已经支持async和await语法。async函数返回一个Promise对象,当函数执行的时候,一旦遇到 await就会先等待,等到异步操作完成,再接着执行函数体内后面的语句。这样就将异步的代码写成同步的形式,代码容易理解,可读性大为提高,减少代码错误的产生,避免了“回调地狱”发生。下段代码是发送“年检提醒”访问数据库的程序,从中可见一斑。

5 结 语

图书馆短信服务系统从2018年10月上线至今,系统运行稳定,处理速度快。这说明 Node.js应用于多种异构数据库的协同访问,效果良好,异步和并发的性能优异、稳定可靠,是一个值得采用和深入研究的方案。

Node.js自身哲学是花最小的硬件成本,追求更高的并发,更高的处理性能[8]。Node.js使用的是JavaScript语言,相对学习成本较低、模块化的开发模式,可以利用的资源丰富,现在已经形成了完整的资源生态,而且社区发达,许多人把问题都放到社区交流讨论,可以帮助缩短开发周期。另外,开发中所用的操作系统、工具、模块大都是免费的,运行时系统对硬件资源的消耗相对于其他流行语言如 Java要小,这也降低了开发成本。

Node.js经历了10年的发展历程,今后一定会更加完善,它的使用范围有待我们进一步探索。

猜你喜欢

代码短信数据库
道歉短信
创世代码
创世代码
创世代码
创世代码
代发短信
数据库
数据库
数据库
数据库