自 PDC 2008 首次发布以来,我一直在使用 Microsoft Azure 云服务。从那时起,我就一直是“云服务”的 忠实 粉丝,云中的牛虚拟机是无状态的。这些年来,我从未见过这个错误,直到昨天:
磁盘空间不足。
在 System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
在 System.IO.FileStream.WriteCore(字节 [] 缓冲区,Int32 偏移量,Int32 计数)
在 System.IO.BinaryWriter.Write(字节 [] 缓冲区,Int32 索引,Int32 计数)
帮助!那个是从哪里来的!我决定建立一个远程桌面连接到我的一个虚拟机,看看是否有任何磁盘已满或接近满。没有!
异常的堆栈跟踪告诉我异常源于创建一个临时文件,所以我决定检查所有明显干净的 Windows 临时路径。接下来我查看的是配额:是否启用了任何磁盘配额?没有。但是在 Azure 云服务虚拟机上启用 了 文件夹配额!
具有 100 MB 硬配额的那个引起了我的注意。路径是 C:\Resources\temp\… 。将一个和一个放在一起,我推断出 Azure 正在将我的应用程序的临时文件夹重定向到这个文件夹。事实上,经过一些搜索,这一点得到了证实:云服务 确实会 重定向临时文件夹并使用硬配额对其进行限制。但是我需要更多的临时空间……
增加 Azure 云服务上的临时磁盘空间
事实证明, System.IO 命名空间有几个调用来获取临时路径(例如在 Path.GetTempPath() 中),这些调用都在后台使用 Win32 API。为此, 文档 阅读:
GetTempPath 函数按以下顺序检查环境变量是否存在,并使用找到的第一个路径:
- TMP 环境变量指定的路径。
- TEMP 环境变量指定的路径。
- USERPROFILE 环境变量指定的路径。
- Windows 目录。
太棒了,所以我们所要做的就是在没有配额(或更大配额)的 VM 上创建一个文件夹,并将 TMP 和/或 TEMP 环境变量设置为指向它。
让我们从第一步开始:创建一个文件夹,作为我们 VM 上的临时文件夹。我们可以从我们的 Visual Studio 云服务项目中做到这一点。对于每个角色,我们可以创建一个具有给定配额的本地资源(确保不超过您正在使用 的 VM 大小的本地资源限制 !)
下一步是设置 TMP / TEMP 环境变量。我们可以通过将以下代码添加到角色的 RoleEntryPoint 中来完成此操作(在此处粘贴完整类以供参考):
public class WorkerRole : RoleEntryPoint
{
private const string _customTempPathResource = "CustomTempPath";
private CancellationTokenSource _cancellationTokenSource;
public override bool OnStart()
{
// Set TEMP path on current role
string customTempPath = RoleEnvironment.GetLocalResource(_customTempPathResource).RootPath;
Environment.SetEnvironmentVariable("TMP", customTempPath);
Environment.SetEnvironmentVariable("TEMP", customTempPath);
return base.OnStart();
}
}
就是这样!全新的部署和我们的临时文件现在存储在一个更大的文件夹中。