赞
踩
基于openresty(nginx+lua)的系统框架,设计一种计算密集型的应用框架。本方案将有如下特点:
1、可以避免计算进程阻塞Openresty框架的问题;
2、可避免多个计算进程同时加载大量静态资源数据的问题;
3、算法模块提供标准C接口模块,无需为做额外封装开发。
图1
图2
Openresty可调用luaposix模块实现子进程的创建和退出。
通常一台服务器受限于CPU能力,并发计算请求能力有限, 而Openresty框架下的一个Nginx进程很容易处理1K以上的网络IO,因此,只需在nginx.conf中配置一个Nginx worker承担网络进出,同时,使用该worker进程作为其它Nginx子进程的父进程(如图1)。
Openresty系统代码是原生支持协程的,图1中,Nginx父进程可以无阻塞的与多个Nginx子进程建立tcp连接;tcp传输是单机进程间的socket通信,经过合理配置,效率可与IPC管道相当;因为,tcp通信是合适本方案的Nginx父子进程间通信方式。
图1中,子进程是tcp服务端,可以使用Luasocket等开源模块开发。
有些服务应用(如AI深度学习应用),需要加载大量的静态资源到内存;而Openresty提供了在初始化阶段一次性加载大量数据的方法。
图2是openresty系统的执行阶段示意图。Openresty系统在(1)初始化阶段的init_worker_by_lua*创建定义全局的Lua缓存区,该阶段加载的数据会存储在该全局Lua缓冲区中,且可以被所有Nginx父子进程访问。这样,我们只需要在系统初始阶段加载一次静态资源数据到内存,可避免大量数据在内存中的多次拷贝占用。
如图2,Nginx在(3)内容处理阶段接收到用户请求、处理、转发并输出响应;所有Fork生成的Nginx子进程也工作在该阶段。
整体方案是基于Openresty框架,该框架支持ffi调用C模块,因而算法模块可以是Lua编写的模块或者C/C++编写的C模块。
图3
如图3
1)Nginx在收到用户请求并处理后,若发现是需要计算的请求,则首先判断队列中是否有空闲的Nginx子进程,如果没有则Fork一个新的子进程;
2)Nginx子进程初始化时,会加载算法模块,并创建一个阻塞式的tcp服务;父进程则作为tcp客户端连接tcp服务,连接成功后,推送计算请求到tcp服务;
3)Nginx子进程剥离并处理收到的计算数据,调用算法模块计算,并阻塞等待计算结果;当结果返回时,推送结果给父进程;
4)有些计算请求数据不是一次性传输给子进程的,因此,图1中(5)(7)(8)过程可能会产生多次;
5)Nginx父进程认为计算完成后,将主动断开tcp连接,子进程管理模块则将该子进程标记为空闲,等待下次再次被调用。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。