The good of reverse connect to oracle database

kaven276 edited this page Jul 17, 2015 · 2 revisions

注:目前 NORADLE 已经升级到 dispatcher 架构,client 通过 dispatcher 间接连接到数据库,oracle 从直接反向连接到客户端改为反向连接到 dispatcher。本文基于老版本 NORADLE的文章,但是大部分内容还有效,读者可以另行看其他专门介绍 dispatcher 架构的 wiki。

传统的数据库连接方式都是客户端主动连接数据库,然后管理一个数据库的连接池,但是 NodeJS 没有办法主动连接数据库,因为:

  1. 如果使用基于OCI的 javascript 封装,需要开发这个 driver,实际部署还需要在 NodeJS 所在服务器上安装 Oracle 客户端环境
  2. 如果使用基于JDBC Thin Driver 协议开发 javascript 版本,也会非常的困难

但是,我们是否必须要基于 oracle client driver 主动连库呢?分析如下,OCI 提供的功能过度过于复杂,而我们只需要执行 Oracle 上的存储过程,然后接受响应结果,而无需执行更多复杂的工作如 SQL。也就是说你要在数据库中执行的全部操作都应该封装到存储过程中,你所需要的所有回复都应该由该存储过程输出成一个响应(格式可以是多样的),因此 Noradle 对数据库操作就简化为执行存储过程(当然包括传入入参和请求体等信息),然后取得结果响应。结论是我们无需使用复杂的 oracle client driver 及其封装。

但是不使用基于 oracle client driver 的封装方式怎么才能连接到数据库中呢,恰好 Oracle 提供了 UTL_TCP 包,它提供了连接外部服务器,读取和写入 socket 的功能。因此 Noradle 会在数据库中预先启动一定数量的后台进程(基于scheduler),然后让这些 oracle 服务进程执行主服务程序 gateway.listen,gateway.listen 会首先建立到 NodeJS 服务器的连接,然后等待 NodeJS 发送 socket 信息给自己。在 NodeJS 端被动的接受来自 Oracle 的连接并形成数据库连接池。当 NodeJS 需要执行 oracle 存储过程(PSP.WEB 页面生成程序)时,就从连接池中取出空闲的连接,然后将包括存储过程名、用户 http 请求信息等信息通过该空闲的 socket 发往对应的 oracle 后台服务进程,该进程会将所有请求信息解析并存放到包变量中供要执行的存储过程访问,然后动态执行该存储过程。而存储过程也会读写库表数据然后按照输出 http 响应的方式将结果返回给 NodeJS.

我管这种连接数据库的方式叫做反向连接(reverse db connect),它有着比传统的正向连接的众多优势。

  1. 无需安装基于OCI的 oracle 客户端,无需对 OCI 封装,无需用 javascript 重写 JDBC Think Driver
  2. 应用程序无需做连库的配置和代码书写,只需在 oracle 侧配置哪些 NodeJS server 需要被动连库即可
  3. oracle 服务器端主动发起连接,而不是由客户端随意连接数据库,这样只有注册的连库客户端才能访问到数据库,无需暴露数据库用户名和密码,这不是更加的安全吗
  4. 因为是由 oracle 主动向外发起连接的,防火墙无需配置哪些节点(除了数据库开发和管理人员)可以访问数据库,既简单又安全
  5. 通过一组连接和对应的后台oracle进程,可以选择任意连接和进程执行任意用户的存储过程(只限后缀 _b,_c,_h 等对外服务的存储过程)
  6. oracle 服务器通过标识客户端的可用状态,可以随时动态的拒绝某类客户端的访问
  7. Noradle 服务进程可以在执行了一定量的请求次数和时间后,自动退出,并通过 k_pmon 重启(当然也可以是退出的时候自动将自己重启),从而实现资源的释放而如果采用传统的客户端建立连接池,那么 oracle 服务进程的重启释放资源的操作就不是集中管控的,依赖于每个客户端为了照顾数据库整体而管理好连接池。现在应用程序再也不用管理连接池了,来自各个NodeJS服务器的所有到数据库的连接都会由 Oracle 主动集中管理,它会根据数据库自身的负载来管理,而不是根据客户端的意愿,这难道不是更加合理吗?
  8. 现在已经基本不存在 CS 客户端程序(他们的地址任意不固定)直连数据库的应用了(除了开发人员和数据库管理员),需要连接数据库的都是些在后台运行的有着固定地址的应用服务器等服务器,因此事先将他们注册到 Noradle 并且由 oracle 主动连接他们是非常可行的
  9. NodeJS 对连接池的管理方式如下,一旦有访问 oracle 的请求而没有可用的 oracle 连接,他会将请求打入队列然后不阻塞继续执行其他工作,一旦有新的可用的空闲 oracle 连接,Noradle 会按 PIFO 原则取出一个待执行请求,用新出现的空闲 oracle 连接将该请求发送给 oracle 侧执行。因此即使连接池忙或者 oracle 暂时中断,或者重启了 Noradle 后台进程,都不会影响最终用户的访问,最多只是响应延时变长。对于编程的好处是,执行访问 oracle 的动作时,永远可以认为存在可用的空闲 oracle 链接,即使它们可能是 deferred.
  10. 反向连接使每个 Noradle 服务进程都可以建立一个到 NodeJS proxy router 的连接,从而通过 multiplex 多路复用实现不限量的对外连接数。