基于 OpenResty 的接口网关设计( 二 )


  • 事件驱动模型设计
  • 全异步的网络 I/O 处理机制
  • 极少的进程切换
  • 内存消耗低,极度“压榨”服务器硬件资源
除了基于事件驱动的架构使其支持百万级的 TCP 连接,另外高度模块化的设计和自由的许可证使其拥有非常多扩展其功能的第三方模块,也是它的重要特性 。所以,后来才会有 OpenResty 的诞生 。
我们看一个 Nginx 作简单配置来提供服务的例子:
worker_processes 1;events { worker_connections 1024; } http { upstream backend { server 127.0.0.1:8080 } server { location / back { proxy_pass http://backend; } } } 
上述配置文件中,分别在 event、http、server 以及 location 块配置项中做了一些简单的配置,当安装完并启动 Nginx 后(监听 80 端口),访问到 /back 路径下的请求会被转发到本地 127.0.0.1:8080 服务上 。
3.1.1 OpenResty 简介
根据官网定义,OpenResty 是一个通过 Lua 扩展 Nginx 实现的可伸缩的 Web 平台 。其核心是基于 Nginx 一个 C 模块将 Lua 语言嵌入到 Nginx 服务器中,对外提供一套完整的 Lua Web 的 API,并透明支持非阻塞 I/O,提供协程 —— “轻量级线程”、定时器等,从而极大地降低了高性能服务端的开发难度和开发周期 。
OpenResty 将两个极为优秀的组件 Nginx 与 Lua 进行糅合,一方面保留了 Nginx 高性能 web 服务特征,另一方面有提供 Lua 特性在极少损失性能情况下便于业务功能的开发 。根据官网介绍,OpenResty 非常便于用来搭建能够处理超高并发、扩展性极高的动态 Web 应用、Web 服务和动态网关 。
我们也是因为 OpenResty 的这些特性,特别是它对搭建动态网关的友好支持,才选择了基于 OpenResty 来开发我们的接口网关 —— APIGateway 与 OpenApi 。
开发接口网关使用到的 OpenResty 一个重要知识:OpenResty 对于一个请求的处理流程 。Nginx 把一个请求分为不同的阶段,从而让第三方模块通过挂载行为在不同的阶段来定制自己的行为;OpenResty 拥有同样的特性,不过在不同阶段挂载的是 Lua 脚本 。下图是基于《OpenResty 最佳实践》原图重绘而来:
基于 OpenResty 的接口网关设计

文章插图
 
 
从上图可知,OpenResty 处理请求大致分为四个阶段:
  • 初始化阶段(Initialization Phase)
  • 重写与访问阶段(Rewrite / Access Phase)
  • 内容生成阶段(Content Phase)
  • 日志记录阶段(Log Phase)
我们看一个 OpenResty 作简单配置来提供服务的例子:
worker_processes 1;events { worker_connections 1024;}http { resolver 127.0.0.1; lua_package_path '$prefix/lua/?.lua;;'; init_by_lua_block { # ... } init_worker_by_lua_file lua/init_work_by_lua.lua; server { listen 80; location / { rewrite_by_lua_file lua/rewrite_by_lua.lua; access_by_lua_file lua/access_by_lua.lua; proxy_pass http://<url>; } }} 
上述配置文件中,分别在 event、http、server 以及 location 块配置项中做了一些简单的配置,当安装完并启动 Nginx 后(监听 80 端口),首先执行 init_by_lua_block、init_worker_by_lua_file 进行初始化,接着接受请求,所有的请求都会匹配上 "/" 路径,进而执行 rewrite_by_lua_file、access_by_lua_file进行重写与访问,最后转发请求到本地 127.0.0.1 服务上 。
在实际的接口网关开发中,我们主要是使用到了 OpenResty 中初始化阶段的 init_by_lua*、init_worker_by_lua*、重写与访问阶段 的 rewrite_by_lua*、access_by_lua* 以及内容生成阶段 content_by_lua* 过程 。
3.2 接口网关的架构
这一节是本文的核心内容,重点讲述接口网关的架构设计 。如前文所述,本文主要以 OpenApi 为例来讲述接口网关的架构设计 。先看图:
基于 OpenResty 的接口网关设计

文章插图
 
 
下面我们来一步步来分析架构图的各个部分,首先是两层的 HAProxy。
3.2.1 两层 HAProxy 代理
根据维基百科定义,HAProxy 是一个使用 C 语言编写的自由及开放源代码软件,其提供高可用性、负载均衡,以及基于 TCP 和 HTTP 的应用程序代理 。
基于 OpenResty 的接口网关设计

文章插图
 
 
如图所示,隔离的内网与外网上分别提供了 HAProxy 代理,外层暂且称为 HAProxy internet ,内层称为 HAProxy internal 。外层暴露于外网中,使用统一地址如 http://openapi.company.com 来接受外部请求(这里指第三方的请求);中间是基于 OpenResty 的 Nginx 网关层,外部请求经过网关后通过 HAProxy internal 转发到内网的服务上,内网服务遵循 Restful 风格,网关转发到内网的地址由接口网关控制 。


推荐阅读