繁体   English   中英

如何在 ASP.NET 中限制每个请求 memory 的使用?

[英]How to limit per-request memory usage in ASP.NET?

我有一个多租户 .NET 5 应用程序,在 ASP.NET 中运行,其中一个请求可以运行任意代码并使用任意数量的 memory。 如何防止用户在每个请求的基础上使用过多的 memory?

我知道我可以限制每个进程,也可以限制发出的 HTTP 请求的大小,但这不是我需要的。 我需要一种方法,如果用户运行像int array = int[1,000,000,000,000,000,000,000]这样的代码,他们将得到一个异常而不是整个站点都崩溃。

编辑:这是一个 jsfiddle 风格的应用程序(具体来说,它是 darklang.com),虽然使用自定义语言和运行时,所以我对运行时有很好的控制。

.NET 核心和 .NET 5

因为问题是关于.Net Core 我必须包括为什么去 AppDomain 路线行不通。

应用程序域

为什么停产了? AppDomain 需要运行时支持并且通常非常昂贵。 虽然仍由 CoreCLR 实现,但它在 .NET Native 中不可用,我们不打算在那里添加此功能。

我应该改用什么? AppDomain 用于不同的目的。 对于代码隔离,我们推荐进程和/或容器。 对于程序集的动态加载,我们推荐新的 AssemblyLoadContext class。

来源:移植到 .NET 内核 | .NET 博客

如果您想获得有关 memory 使用情况的“自动”信息,那么我们只有一种方法可以做到这一点。

如何测量 memory 对单独进程的使用情况

要测量其他进程 memory 我们可以使用Process句柄并获取其WorkingSetPrivateMemoryVirtualMemory 有关 memory 类型的更多信息

处理另一个进程的代码非常简单。

private Process InterpreterProcess;

// Run every how often you want to check for memory
private void Update()
{
    var workingSet = InterpreterProcess.WorkingSet64;
    if(workingSet > Settings.MemoryAllowed)
    {
        InterpreterProcess.Kill(true);
    }
}

private void Start()
{
    InterpreterProcess = new Process(...);
    // capture standard output and pass it along to user
    Task.Run(() =>
    {
        Update();
        Thread.Sleep(50);
        // This will be also convenient place to kill process if we exceeded allowed time
    });
}

然而,这给我们留下了一个非常重要的问题,因为我们可能允许用户访问系统关键资源——即使我们没有在进程上运行管理员权限。

替代方法

既然您提到您有一个自定义解释器,您可能更容易为解释器添加 memory 管理、memory 计数和安全性。

由于我们可以假设 memory 分配仅使用new分配,您的解释器只需测试每个新分配的大小并进行相应测试。

要测试托管 object 大小,您需要“分析”创建的实例并在每个简单类型上使用sizeof() ,正在制定正确的方法没有办法在 ZCD69B4957F06CD818D7BF3D20980 中获取托管 object 大小

您需要使用一个进程(在作业 object 或 cgroup 中),在 .NET 的应用程序级别无法执行此操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM