我想阅读Azure队列存储的所有消息并将它们写入Blob。理想情况下,我想阅读10000或更多的批次,并将它们写入Blob。
我正在使用带有队列存储绑定的Azure云功能进行输入和Blob存储绑定输出,但我无法找到能够让我读取多条消息的API或配置选项。 有谁知道这样的API?
答案 0 :(得分:3)
官方文档未提及在Azure Function的单次执行中批量处理Storage Queue消息的任何支持。有an open issue in WebJobs SDK。所以,它不受支持。
如果您可以灵活地使用哪种服务用于消息传递中间件,则可以切换到事件中心。 Event Hub触发器支持(并鼓励)批量处理消息。但它不可能是10.000:批量大小限制为256k的数据。
要批量处理存储队列消息,您必须远离队列触发函数(例如,在计时器上运行函数并连接到表存储以处理所有消息,或者具有自定义轮询Web作业,或者使用带有自定义触发器的Web Job SDK。
答案 1 :(得分:0)
我终于找到了一个我非常满意的解决方案。 使用缓冲区是不可扩展的,因为运行时很容易超过Azure Functions运行时强加的5分钟限制,加上明显的内存消耗问题,而且我不得不使用定时器触发器,所以我需要以某种方式确保所有相关消息都在在某个时间排队。
我现在所做的是使用普通队列绑定来获取消息,以及节点存储SDK,以实现某种"假的"流入附加Blob。因此,每条消息都会逐个转换为CSV行,并附加到相应的blob。
以下是该功能的代码:
const config = require('./config/config.js')
const storage = require('azure-storage')
const csvTransformer = require('./lib/csvTransform')
const async = require('async')
module.exports = function (context, myQueueItem) {
context.log(
'JavaScript queue trigger function processed work item',
myQueueItem
)
let blobService = storage.createBlobService(config.targetBlobConnection)
let messageDayString = csvTransformer.determineDayFromMessage(myQueueItem)
let blobName = messageDayString + '.csv'
let csvMessage
async.waterfall(
[
function (callback) {
blobService.createContainerIfNotExists(
config.targetBlobContainer,
{ publicAccessLevel: 'blob' },
err => {
callback(err)
}
)
},
function (callback) {
blobService.doesBlobExist(
config.targetBlobContainer,
blobName,
null,
(err, blobResult) => {
context.log('got blobResult: ', blobResult)
callback(err, blobResult)
}
)
},
function (blobResult, callback) {
if (blobResult && blobResult.exists) {
csvMessage = csvTransformer.transformMessageToCSV(myQueueItem, false)
blobService.appendFromText(
config.targetBlobContainer,
blobName,
csvMessage,
null,
(err, appendedBlobResult) => {
context.log('appended to existing blob: ', appendedBlobResult)
callback(err, appendedBlobResult)
}
)
} else {
csvMessage = csvTransformer.transformMessageToCSV(myQueueItem, true)
blobService.createAppendBlobFromText(
config.targetBlobContainer,
blobName,
csvMessage,
null,
(err, createdBlobResult) => {
context.log('created new blob: ', createdBlobResult)
callback(err, blobResult)
}
)
}
}
],
function (err, result) {
if (err) {
context.log.error('Error happened!')
context.log.error(err)
context.done(err)
} else {
context.log('appended CSV message to blob')
context.bindings.outputQueueItem = csvMessage
context.done()
}
}
)
}