Azure Service Bus因NOTFOUND异常

时间:2018-03-14 02:40:01

标签: node.js azure azure-functions azureservicebus

我将超过400,000条需要从我的NodeJS Azure功能发送的json消息迭代到Azure Service Bus中。该功能可以创建主题,并开始发布消息。

它开始经历循环并发布消息。在发布失败之前,我在队列中看到了几千个土地,并出现以下错误:

{ 
    Error: getaddrinfo ENOTFOUND ABC.servicebus.windows.net ABC.servicebus.windows.net:443 at errnoException (dns.js:53:10) at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:95:26)
    code: 'ENOTFOUND',
    errno: 'ENOTFOUND',
    syscall: 'getaddrinfo',
    hostname: 'ABC.servicebus.windows.net',
    host: 'ABC.servicebus.windows.net',
    port: '443' 
}

我发布消息的代码组成了一条消息,并通过JS API推送它。消息正文是一个小JSON对象:

{
    "adult":false,
    "id":511351,
    "original_title":"Nossa Carne de Carnaval",
    "popularity":0,
    "video":false
}

我的Azure功能中将此消息推送到服务总线的方法如下:

function publishNewMovies(context, movies) {
    var azure = require('azure');
    var moment = require('moment');

    var topic = process.env["NewMovieTopic"];
    var connectionString = process.env["AZURE_SERVICEBUS_CONNECTION_STRING"];

    context.log("Configuring Service Bus.");
    return new Promise((resolve, reject) => {
        var serviceBusService = azure.createServiceBusService(connectionString);
        serviceBusService.createTopicIfNotExists(topic, function(error) {
            if (error) {
                context.log(`Failed to get the Service Bus topic`);
                reject(error);
            }

            context.log("Service Bus setup.");

            // Delay the receiving of these messages by 5 minutes on any subscriber.
            var scheduledDate = moment.utc();
            scheduledDate.add('5', 'minutes');
            context.log("Sending new movie messages.");

            var message = {
                body: '',
                customProperties: { 
                    messageNumber: 0
                },
                brokerProperties: {
                    ScheduledEnqueueTimeUtc: scheduledDate.toString()
                }
            }

            for(index = 0; index < movies.length; index += 40) {
                message.brokerProperties.ScheduledEnqueueTimeUtc = scheduledDate.add('11', 'seconds').toString();
                for(batchIndex = 0; batchIndex < 40; batchIndex++) {
                    var currentIndex = index + batchIndex;
                    if (currentIndex >= movies.length) {
                        break;
                    }

                    message.customProperties.messageNumber = currentIndex;
                    message.body = JSON.stringify(movies[currentIndex]);

                    serviceBusService.sendTopicMessage(topic, message, function(error) {
                        if (error) {
                            context.log(`Failed to send topic message for ${message.body}: ${error}`);
                            reject(error);
                        }
                    })
                }
            }
        });
    });
}

这将创建一条从第一次Service Bus推送开始5分钟后可见的消息。然后我批量发送40个消息,在那个预定的时间。第一批完成后,我将在未来11秒内安排另外40条消息。这是因为将要编写另一个Azure函数来监听此Service Bus主题并发出第三方API请求。我每10秒钟限制40条消息。

我已经阅读了Azure Functions documentation on quotas,看起来我可能会达到10,000主题/队列限制。有了这个限制,有人应该如何将大量的消息推送到总线?当我发送相同的消息时,设置多个命名空间来解决这个问题似乎是倒退的,只是使用不同的内容 - 它属于同一个命名空间。我收到的错误并不表示我达到了限制或任何限制。听起来它出于某种原因未能找到实际的服务总线终点。

这个问题的答案是处理分区吗?我无法找到有关如何使用NodeJ处理分区的文档。他们的大多数API文档都在C#中,对我来说,它并没有很好地转换为NodeJ。

编辑以显示总线指标

总线指标 enter image description here

主题指标 enter image description here

1 个答案:

答案 0 :(得分:-1)

您能详细说明为什么要创建这么多主题吗? 这个:  var topic = process.env [&#34; NewMovieTopic&#34;];

您可以拥有1个主题,可以获得数百万条消息,然后将这些消息转移到您将添加过滤条件的单个订阅中。因此,不需要这么多主题。

通常主题,订阅和队列将在管理平面(portal,arm,PS或cli)运行时创建,或者数据操作将是函数,云应用程序,VM,因此服务总线可能很容易处理您的卷,除非您有创建这些主题的一个非常具体的原因是什么?