1.OpenResty的由来OpenResty是一个基于Nginx和Lua的高性能Web平台,集成了大量优秀的Lua库、第三方模块和大部分依赖。用于方便地构建能够处理超高并发和高扩展性的动态Web应用程序、Web服务和动态网关。Nginx由俄罗斯工程师IgorSysoev于2002年基于C语言开发,并于2004年开源,用于解决ApacheHTTP服务器无法满足C10K(单个HTTP服务器处理10,000个并发连接)的问题。随着Web的飞速发展和普及,Nginx以其开源、跨平台、支持百万级并发TCP连接、稳定性高等特点迅速普及。目前,全球近三分之一的HTTP服务器使用Nginx。Nginx生态系统的丰富性,归功于其高内聚低耦合的模块化设计。Nginx提供的主要模块包括Core模块、Event模块、Http模块、Mail模块、Stream模块等,开发者可以根据Nginx模块开发规范轻松扩展Nginx的功能。Nginx有局限性:对于一般使用Nginx的业务系统,业务变更只需要修改Nginx相关配置文件并重启即可,但如果需要开发或更新第三方模块,则需要重新编译安装Nginx,不适合对于在线系统友好,重新编译安装Nginx是一个繁琐且有风险的过程。因此,Nginx支持脚本语言是很有必要的。Perl、Python、Js和Lua都有CAPI。从近几年开发者的应用来看,自然是C脚本语言的Lua应用最为广泛。Lua脚本可以方便的被C/C++代码调用,也可以反向调用C/C++函数。一个完整的Lua解释器才200k。在所有脚本引擎中,Lua是最快的。OpenResty应运而生:OpenResty基于Nginx,支持LuaJIT扩展,允许开发者使用Lua脚本语言调动Nginx支持的各种C和Lua模块,大大提高了Nginx模块开发的生产力。2.OpenResty的工作原理OpenResty的本质是基于Nginx的单Master多进程模型。进程中嵌入LuaVM,通过LuaVM执行Lua代码,实现高性能。同时,LuaVM的自动内存管理也提高了开发者的开发效率。OpenResty的两大技术特点:(1)多阶段处理;(2)Lua协程与Nginx事件的高效NIO组合。下面分别介绍。2.1OpenResty的多阶段处理OpenResty的多阶段处理是基于Nginx的HTTP多阶段处理。前面说过,Nginx对Http的处理也是通过HTTP模块的配合完成的。对于HTTP模块、数据传输和连接的管理,Nginx将其分为11个处理阶段,每个处理阶段由多个HTTP模块执行。管道处理:typedefenum{NGX_HTTP_POST_READ_PHASE=0,//读取请求体阶段NGX_HTTP_SERVER_REWRITE_PHASE,//服务器URI重写阶段NGX_HTTP_FIND_CONFIG_PHASE,//位置查找阶段NGX_HTTP_REWRITE_PHASE,//位置URI重写阶段NGX_HTTP_POST_REWRITE_PHASE发生,//检查XURI_NGPHASE重写P,//检查XURI_NGPHASEP/访问限制阶段NGX_HTTP_ACCESS_PHASE,//访问控制阶段NGX_HTTP_POST_ACCESS_PHASE,//检查请求权限处理阶段NGX_HTTP_TRY_FILES_PHASE,//try_file配置处理静态文件阶段NGX_HTTP_CONTENT_PHASE,//返回内容生成阶段NGX_HTTP_LOG_PHASE//日志记录阶段}ngx_http_phases;OpenResty将这11个阶段简化为Rewrite/AccessPhase、ContentPhase、LogPhase,加上进程启动初始化的InitializationPhase,四大阶段一共11条*_by_lua可重写指令。每个阶段分工明确,每个阶段处理http请求不同阶段的数据,分层更容易理解和开发。2.2Lua协程结合NginxEvent的NIO处理Http请求,性能消耗主要在网络IO处理上,而Nginx之所以比ApacheServer的多线程模型处理效率更高,是因为Nginx的Event处理机制。具体针对Linux,Event处理机制是基于Epoll实现的。所有的读写事件都不会阻塞主线程,而是注册到epoll。主线程通过调用epoll_wait获取可读可写事件,并对准备好的事件进行相应的回调处理。实现非阻塞IO。回到OpenResty,每个Worker进程都有一个LuaVM,OpenResty通过LuaVM执行Lua代码,每个外部请求都通过一个Lua协程处理,各个协程之间互不影响,每当Lua代码需要处理IO时,两者都会yield当前协程,并将IO事件交给NginxEvent处理,这样Worker主线程就不会被阻塞。NginxEvent处理完后,Resume协程继续处理。协程只在用户态处理,比多线程切换开销小。通过协程和Nginx的非阻塞I/O模型的结合,不仅HTTP客户端请求,还可以对MySQL、PostgreSQL、Memcached、Redis等远程后端进行一致的高性能响应。3.OpenResty在网站安全建设中的应用中国移动关中安全云WAF是一款网站应用防火墙产品,通过对Http/Https流量的分析检测拦截恶意流量,为Web服务的安全运行提供保障。截至目前,中国移动关中安全云WAF已为超过2000家网站提供网站安全防护服务。团队在研发之初进行技术选型时采用了OpenResty,主要考虑其优点:开发门槛低,Lua库极其丰富,研发效率高,能适应功能快速迭代的需求;轻松支持热更新、研发、高效测试发布,业务无感知;云原生支持,裸机、容器等可部署维护;高性能,基于Nginx的高性能Http应用,还支持MySQL、Redis等的非阻塞IO。关中安全云的WAF部署架构图大致如下:由于WAF节点在系统中串联,这对WAF节点的性能和稳定性有很高的要求。如图,我们使用DPVS+KeepAlived做四层负载均衡,保证包的高速转发和可靠性,然后直接通过OpenResty集群分析流量。经过WAF的流量已经被检测了十几步。每一步相互独立,互不影响。非阻塞IO保证了检测的性能。使用的主要阶段如下:如上表所示,各阶段相互配合,分工明确,配置与云WAF配置中心实时同步,业务配置、防护配置、规则库等可热更新,运维成本低。在防护阶段,对性能要求较高的检测方法会用C语言编写成动态库。lua的ffi调用方便,需要存储和统计计算的使用cosocket与数据库交互。非阻塞特性保证了与数据库交互的高性能。4.总结OpenResty是一个优秀的基于Nginx和Lua的开源组件。在保留Nginx高性能的同时,引入了Lua,降低了开发门槛,研发效率高,运维成本低。对于有大量Web平台需要管理的企业,可以试试看。基于OpenResty可以开发动态路由、限流、缓存、权限控制、安全防护等能力,替代Nginx管理企业内部站点。参考文献[1]OpenResty.http://openresty.org/cn/。[2]陶辉.深入理解nginx:模块开发与架构分析[M].机械工业出版社.2013-4.[3]LuaNginx模块。https://github.com/openresty/lua-nginx-module。
