当前位置:   article > 正文

基于Openresty(nginx+lua)的计算密集型应用开发方法_基于openresty 框架

基于openresty 框架

概要

基于openresty(nginx+lua)的系统框架,设计一种计算密集型的应用框架。本方案将有如下特点:

  • 1、可以避免计算进程阻塞Openresty框架的问题;

  • 2、可避免多个计算进程同时加载大量静态资源数据的问题;

  • 3、算法模块提供标准C接口模块,无需为做额外封装开发。

技术方案

子进程管理设计

在这里插入图片描述

图1

在这里插入图片描述

图2

  • 1、Openresty的Lua代码执行是在事件循环里的, 在Lua代码里不能有任何复杂的计算或其它可能阻塞主循环的代码,因此,基于Openresty框架计算密集型服务需要设计Nginx子进程管理模块;子进程负责阻塞式计算,而该模块提供Nginx子进程创建、空闲子进程管理、异常子进程回收和防过载负载保护等功能。

Openresty可调用luaposix模块实现子进程的创建和退出。

  • 2、只配置一个Nginx worker

通常一台服务器受限于CPU能力,并发计算请求能力有限, 而Openresty框架下的一个Nginx进程很容易处理1K以上的网络IO,因此,只需在nginx.conf中配置一个Nginx worker承担网络进出,同时,使用该worker进程作为其它Nginx子进程的父进程(如图1)。

  • 3、Nginx父子进程间通过tcp通信

Openresty系统代码是原生支持协程的,图1中,Nginx父进程可以无阻塞的与多个Nginx子进程建立tcp连接;tcp传输是单机进程间的socket通信,经过合理配置,效率可与IPC管道相当;因为,tcp通信是合适本方案的Nginx父子进程间通信方式。

图1中,子进程是tcp服务端,可以使用Luasocket等开源模块开发。

  • 4、共享全局静态资源数据

有些服务应用(如AI深度学习应用),需要加载大量的静态资源到内存;而Openresty提供了在初始化阶段一次性加载大量数据的方法。

图2是openresty系统的执行阶段示意图。Openresty系统在(1)初始化阶段的init_worker_by_lua*创建定义全局的Lua缓存区,该阶段加载的数据会存储在该全局Lua缓冲区中,且可以被所有Nginx父子进程访问。这样,我们只需要在系统初始阶段加载一次静态资源数据到内存,可避免大量数据在内存中的多次拷贝占用。

  • 4、子进程工作阶段

如图2,Nginx在(3)内容处理阶段接收到用户请求、处理、转发并输出响应;所有Fork生成的Nginx子进程也工作在该阶段。

  • 5、算法模块编写

整体方案是基于Openresty框架,该框架支持ffi调用C模块,因而算法模块可以是Lua编写的模块或者C/C++编写的C模块。

2.2.2 计算执行流程

在这里插入图片描述

图3

如图3

  • 1)Nginx在收到用户请求并处理后,若发现是需要计算的请求,则首先判断队列中是否有空闲的Nginx子进程,如果没有则Fork一个新的子进程;

  • 2)Nginx子进程初始化时,会加载算法模块,并创建一个阻塞式的tcp服务;父进程则作为tcp客户端连接tcp服务,连接成功后,推送计算请求到tcp服务;

  • 3)Nginx子进程剥离并处理收到的计算数据,调用算法模块计算,并阻塞等待计算结果;当结果返回时,推送结果给父进程;

  • 4)有些计算请求数据不是一次性传输给子进程的,因此,图1中(5)(7)(8)过程可能会产生多次;

  • 5)Nginx父进程认为计算完成后,将主动断开tcp连接,子进程管理模块则将该子进程标记为空闲,等待下次再次被调用。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小丑西瓜9/article/detail/163766
推荐阅读
相关标签
  

闽ICP备14008679号