我正在运行一个基于 Django 的网络服务,在 nginx 后面使用 Gunicorn 作为反向代理。
我的网络服务提供了一个 Django View ,它使用 MATLAB 的外部实例执行计算。由于 MATLAB 启动本身需要几秒钟时间,因此即使只进行非常简单的 MATLAB 计算的请求也需要这么长的时间才能得到答复。
此外,由于在我的代码中进行了 MATLAB 沙箱处理,因此对于网络服务器进程,同一时间只运行一个 MATLAB 实例非常重要。 (因此,目前我正在使用 Gunicorn 同步 worker 模型,它实现了预 fork 网络服务器但不使用任何多线程。)
为了改善用户体验,我现在想通过保持一些(例如 3-5 个)“就绪”MATLAB 实例运行并在请求进入时使用它们来消除 MATLAB 启动的等待时间。请求得到服务后, MATLAB 进程将终止并立即启动一个新进程,为另一个请求做好准备。
我一直在评估两种方法:
继续使用 Gunicorn 同步工作模型并为每个网络服务器进程保留一个 MATLAB 实例。
这个问题似乎是传入的请求没有以循环方式分发到网络服务器工作进程。因此,可能会发生所有计算密集型请求都命中同一个进程并且用户仍然需要等待的情况,因为单个 MATLAB 实例无法尽快重新启动。
将 MATLAB 计算外包给后端服务器,该服务器执行实际工作并由网络服务器进程通过 RPC 进行查询。
在我的构想中,会有许多 RPC 服务器进程在运行,每个进程承载一个正在运行的 MATLAB 进程。处理请求后,MATLAB 进程将重新启动。由于 RPC 服务器进程是循环查询的,因此用户永远不必等待 MATLAB 启动(除非总体请求太多,但这是不可避免的)。
由于第一种方法所描述的问题,我认为 RPC 服务器(方法 2)是解决我的问题的更好方法。
我已经看过一些 Python 的 RPC 解决方案(尤其是 Pyro 和 RPyC),但是我找不到为 RPC 服务器使用预 fork 服务器模型的实现。请记住,由于沙箱的原因,多线程是不可能的,如果服务器仅在接受连接后进行 fork ,我仍然需要在之后启动 MATLAB,这会阻碍整个想法。
有人知道解决我的问题的更好方法吗?或者 RPC 服务器实际上是最好的解决方案吗?但是然后我需要一个预 fork 的 RPC 服务器(= fork 一些进程并让它们都在同一个套接字上的 accept() 上旋转)或者至少一个可以轻松修改的 RPC 框架(猴子补丁?) - fork 。
提前致谢。
最佳答案
我已经通过使我的沙箱线程安全来解决了这个问题。现在我可以使用任何单进程网络服务器并使用 Queue获取在辅助线程中生成的备用 MATLAB 实例。
关于django - 处理对 Django Web 应用程序的计算密集型请求,可能使用预 fork RPC 服务器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11989094/