Skip to content

由dispatcher直接支持FCGI SCGI WCGI访问oracle

kaven276 edited this page Jan 26, 2016 · 15 revisions

参考

SCGI 思路

connection graph

                                       (parse scgi protocol stream data)
         (scgi)                           (scgi)      v
nginx  ----------> noradle-dispatcher  -----------> oracle
                           ^
         (just pipe connection to a free oracle connection)

process cycle

  • 使用 unix domain socket 连接 nginx 和 noradle-dispatcher
  • 使用 nginx scgi_param 配置
    • 指定连接到那个 db,
    • 指定连接到那个 dbu,
    • 指定连接 noradle-dispatcher 的那个监听口 (代表了 oracle 实例和 dbu 的组合)
  • noradle-dispatcher
    • 找空闲的oracle连接,找到就绑定该连接,否则就进队列等有空间连接再处理
    • pipe to oracle,不包括 socket end
    • 接受 oracle 回复的 frame,去掉 frame head,直接转发 frame body
    • 接收到 end frame 后,向 SCGI socket 发送 end,并释放该 oracle 连接
  • oracle 可以直接读 SCGI 内容
    • noradle-dispatcher 对原始包前增加 noradle 协议内容,主要是 protocol=SCGI,而不是 HTTP/DATA/NDBC
    • 发送给 oracle 的 request header 需要解析,名称从大写改成小写,换行分隔符从“\0”改成“\r\n”
  • 实现和 noradle-http 类似的 noradle-scgi 模块
    • 不解析 http 格式 request,解析 scgi 格式的 request,但是同样的对 url,query-string,cookie 进行解析后再发送到oracle
    • 实现 in-process, 直接调用 in-process dispatcher API 接口发送请求,接受响应

goodness

  • nginx pipe to noradle-dispatcher then dispatch to oracle, noradle-dispatcher doesn't parse request/response content, just dispatch, lowest overhead, best performance
  • only one noradle-dispatcher can hold all oracle reverse connections and dispatch all nginx SCGI request, configuration is minimal, just listen port/path to oracle db/dbu mapping is ok

FCGI

connection graph

              (dispatch on connect and kept mapping)  (parse fcgi protocol stream data) 
         (FastCGI)              v                                v
nginx ===============> noradle-dispatcher <=========== oracle server processes
  (multiple connections kept)   ^
                    (just as a multi-path tunnel)

process cycle

  • 启动 noradle-dispatcher for fastGI
  • 接受到 web server 管理查询包,回复单连接,多路复用,并发数按照端口映射到的cid从oracle取来填写
  • 接受到 FCGI_BEGIN_REQUEST 后,查找是否有free oSlot,有就绑定,没有就 buffer,记录 FCGI[port][request_id] 绑定信息
    • oSlotID bound
    • buffered array
  • 如果可以有oSlot发送,先发送一个 noradle input stream 头,其中包含了基本信息,就是协议为fcgi,通道附加信息等等
  • 后续还有该 request_id 的数据包,直接转发到绑定的 oSlot 或者继续 buffer
  • oracle 侧看到是 fcgi 信息,则按照 raw fcgi 协议来处理

SCGI vs FCGI

Aspect SCGI FCGI
request parsing un-touched partial parse header(8 bytes)
response wrap in noradle frame, discard head, pipe body wrap in FCGI frame, pipe all

advantages of direct dispatch

  • node.js do dispatch only, do no parse tunneled data
    • no cluster need: lowest overhead one process is ok, no need for cluster, just simple
    • no version lock: any version of node.js is ok, if only support stream that can pause/resume, do flow control
    • no copyright problem: no 3rd-party node.js module need, just relay protocols data to oracle where data is parsed
  • file in db
    • upload file go into database, pl/sql handle them directly, integrate seamlessly
    • cached data(including partial) save in database, cache policy integrate seamlessly
  • oracle parse protocol content, leveraging multi-processes and RAC/DG scalibility
    • SCGI: parse header length, body length
    • FCGI: parse record header, got request_id, bind/dispatch to oSlot
  • response from oracle
    • is just untouched
    • but how dispatcher determine the end of response?, must wrap in noradle frame
    • SCGI: just discard head and return body, head name-value pairs add extra CRLF
    • FCGI: use its name-value format, wrap in its frame
  • a big nginx server and a group of oracle 12c cloud databases
    • all internet request go to nginx server and dispatch to oracle databases
    • one server deploy nginx in DMZ
    • all other servers deploy oracle12c
    • create pluggable databases on these oracle cloud database
    • the architecture is just clear and simple
              (with dispatcher)      (pluggable databases)     
  clients   |   nginx server   |  oracle cloud database servers
------------|------------------|--------------------------------
(internet)  |    (DMZ area)    |          (intranet)
           HTTP             SCGI/FCGI  

接入多样性的意义

接入类型 接入拓扑 意义
noradle-http 通过 dispatcher 和其他 node.js 处理器 meshup 处理,灵活不受限制的策略和定制可能,支持最多的http特性
raw HTTP dispatcher 直接提供 部署方案最为简单,除了 dispatcher,什么都不需要
raw HTTP nginx -> dispatcher 通过 nginx 导流,性能更好
raw SCGI nginx -> dispatcher 基于 CGI 的输入环境,参考用
raw FCGI nginx -> dispatcher 实现 nginx 到 dispatcher 的多路复用,性能最佳