在多个 ASP .NET 应用程序之间共享互斥锁

作者:微信公众号:【架构师老卢】
7-12 20:21
30

概述:最近,我的任务是在将传统文档格式转换为 PDF 时解决隐私问题。问题非常严重:当多个用户同时访问转换服务时,有时他们的文件会被交换。想象一下,当汤姆收到杰瑞的文件时,会有多惊讶(和隐私噩梦),反之亦然。出现此问题的原因是,我们在同一台计算机上运行了两个 ASP.NET 应用程序,它们都共享相同的转换器应用程序。管理层希望快速解决这一隐私问题。经过一番思考,我决定互斥锁将是解决这个问题的最有效方法。这个想法很简单:确保文档转换过程一次只能由一个应用程序访问,即使多个应用程序尝试同时访问它。这种方法将消除文件交换问题,并确保用户数据保持私密。互斥锁互斥锁是一种同步机制,可确保一次只有一个线程或进程

最近,我的任务是在将传统文档格式转换为 PDF 时解决隐私问题。

问题非常严重:当多个用户同时访问转换服务时,有时他们的文件会被交换。

想象一下,当汤姆收到杰瑞的文件时,会有多惊讶(和隐私噩梦),反之亦然。

出现此问题的原因是,我们在同一台计算机上运行了两个 ASP.NET 应用程序,它们都共享相同的转换器应用程序。

管理层希望快速解决这一隐私问题。

经过一番思考,我决定互斥锁将是解决这个问题的最有效方法。

这个想法很简单:确保文档转换过程一次只能由一个应用程序访问,即使多个应用程序尝试同时访问它。

这种方法将消除文件交换问题,并确保用户数据保持私密。

互斥锁

互斥锁是一种同步机制,可确保一次只有一个线程或进程可以进入特定的代码段。

但是,由于两个 ASP .NET 应用程序正在访问同一资源,因此我们需要配置 Mutex 以允许在这两个应用程序之间共享。

必须配置两件事:互斥锁访问规则互斥锁名称。这些将允许互斥锁在两个不同的应用程序之间安全地共享。

互斥访问规则

这里的关键是 的用法。这将使互斥锁能够在两个应用程序之间安全地共享,这两个应用程序由相同的 IIS 用户帐户运行。WellKnownSidType.BuiltinUsersSid

var accessRule = new MutexAccessRule(  
        new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),   
        MutexRights.FullControl,   
        AccessControlType.Allow);  
  
var securitySettings = new MutexSecurity();  
securitySettings.AddAccessRule(accessRule);

我们还可以使用 来扩大范围。但是,它将不太安全,因为计算机上的任何人都可以访问互斥锁。

互斥名称

要在应用程序之间共享相同的互斥锁,我们必须确保正确设置了互斥锁名称。

using (var mutex = new Mutex(false, "Global\\PdfConversion", out _, securitySettings))  
{  
    // ...  
}

互斥名称在应用程序之间必须相同,并且必须具有前缀,以确保它在计算机上的所有会话中都是可见的。

互斥锁实现

配置了访问规则和名称后,我们继续创建互斥锁实现:

var accessRule = new MutexAccessRule(  
        new SecurityIdentifier(WellKnownSidType.BuiltinUsersSid, null),   
        MutexRights.FullControl,   
        AccessControlType.Allow);  
  
var securitySettings = new MutexSecurity();  
securitySettings.AddAccessRule(accessRule);  
  
using (var mutex = new Mutex(false, "Global\\PdfConversion", out _, securitySettings))  
{  
    try  
    {  
        // Attempt to acquire the mutex  
        // Waiting up to 2 minutes for availability  
        mutex.WaitOne(120000);  
  
        // If acquired, run the document conversion process  
        return RunConversion(doc);  
    }  
    catch (AbandonedMutexException)  
    {  
        // If the mutex was abandoned, release it and try to acquire it again  
        mutex.ReleaseMutex();  
  
        // Wait again up to 2 minutes for the mutex  
        mutex.WaitOne(120000);  
  
        // Once acquired, re-run the document conversion process  
        return RunConversion(doc);  
    }  
    finally  
    {  
      // Always release the mutex when done to allow other processes to use the resource  
        mutex.ReleaseMutex();   
    }  
}

测试

我使用 PowerShell 命令同时运行了多个请求以测试应用程序:

Start-Job {Invoke-WebRequest -Uri https://localhost:1000/api/download/1 -OutFile C:\\file1.pdf}  
Start-Job {Invoke-WebRequest -Uri https://localhost:1000/api/download/2 -OutFile C:\\file2.pdf}  
Start-Job {Invoke-WebRequest -Uri https://localhost:2000/api/download/3 -OutFile C:\\file3.pdf}  
Start-Job {Invoke-WebRequest -Uri https://localhost:2000/api/download/4 -OutFile C:\\file4.pdf}  
...etc

在执行测试和回归后,修补程序已部署到生产环境。通过一个相对简单的解决方案解决了复杂的隐私问题。

阅读排行