Azure Blob存储中等大小视频上传最优方案及内存错误解决
解决Azure Blob存储大视频上传问题的两种方案
一、修复Azure Function中multipart.Parse()的内存溢出问题
内存错误的核心原因是multipart.Parse()会将整个文件加载到内存中,3.5分钟的音乐视频通常几十MB以上,容易超过Azure Function的默认内存配额。可通过以下方式解决:
1. 改用流式解析库替代multipart.Parse()
使用支持流式处理的库(如busboy),直接将文件流传输到Blob存储,避免全量加载到内存。示例代码(Node.js Function):
const { BlobServiceClient } = require("@azure/storage-blob"); const Busboy = require("busboy"); module.exports = async function (context, req) { return new Promise((resolve, reject) => { const busboy = new Busboy({ headers: req.headers }); const blobServiceClient = BlobServiceClient.fromConnectionString(process.env.AZURE_STORAGE_CONNECTION_STRING); const containerClient = blobServiceClient.getContainerClient("your-container-name"); busboy.on("file", async (fieldname, file, filename) => { const blockBlobClient = containerClient.getBlockBlobClient(filename); // 直接将流上传到Blob,不经过内存缓存 await blockBlobClient.uploadStream(file); }); busboy.on("finish", () => { context.res = { status: 200, body: "上传成功" }; resolve(); }); busboy.on("error", (err) => { context.res = { status: 500, body: err.message }; reject(err); }); req.pipe(busboy); }); };
2. 调整Azure Function资源配置
- 若使用消费计划(Consumption Plan),可在Function App配置中调高内存配额(最高支持1.5GB);
- 预算允许时,切换到Basic/Standard计划,选用更大内存的实例(如B1实例含1GB内存),提升大文件处理能力。
二、前端直传Azure Blob存储(推荐方案)
绕过Azure Function中转,让移动端/桌面端直接上传到Blob存储,是更高效的方案,可彻底避免中转带来的内存和性能瓶颈。核心是通过临时SAS令牌实现安全授权:
1. 后端生成临时SAS令牌
用轻量服务(如Azure Function)生成仅含上传权限、有效期较短的SAS令牌,示例代码(Node.js):
const { BlobServiceClient, StorageSharedKeyCredential } = require("@azure/storage-blob"); module.exports = async function (context, req) { const accountName = process.env.AZURE_STORAGE_ACCOUNT_NAME; const accountKey = process.env.AZURE_STORAGE_ACCOUNT_KEY; const containerName = "your-container-name"; const filename = req.query.filename; const sharedKeyCredential = new StorageSharedKeyCredential(accountName, accountKey); const blobServiceClient = new BlobServiceClient( `https://${accountName}.blob.core.windows.net`, sharedKeyCredential ); const containerClient = blobServiceClient.getContainerClient(containerName); const blockBlobClient = containerClient.getBlockBlobClient(filename); // 生成有效期1小时的上传SAS令牌 const sasToken = await blockBlobClient.generateSasUrl({ permissions: "c", // 仅授予创建/上传权限 expiresOn: new Date(Date.now() + 3600 * 1000), }); context.res = { status: 200, body: { sasUrl: sasToken } }; };
2. 前端直接上传(Web端示例)
使用@azure/storage-blob SDK实现自动分块上传,适配大文件:
import { BlockBlobClient } from "@azure/storage-blob"; async function uploadVideo(file) { // 调用后端接口获取SAS URL const res = await fetch(`/api/getSasToken?filename=${file.name}`); const { sasUrl } = await res.json(); const blockBlobClient = new BlockBlobClient(sasUrl); // 分块上传,默认块大小4MB,可根据网络环境调整 await blockBlobClient.uploadBrowserData(file, { blockSize: 4 * 1024 * 1024, concurrency: 4, }); console.log("上传完成"); }
移动端适配
- iOS:使用Azure Storage Blob官方SDK(
AzureStorageBlob),通过SAS URL实现分块上传; - Android:集成
azure-storage-blob库,基于SAS令牌完成直传逻辑。
注意事项
- SAS令牌需严格控制权限和有效期,避免泄露导致存储资源被滥用;
- 分块上传的块大小可根据网络环境调整(如移动端可设为2MB);
- 上传前确认学生套餐的Blob存储流量、容量配额是否满足需求。
内容的提问来源于stack exchange,提问作者Lucas McKamey
相关产品推荐
相关产品推荐

