如何在使用Azure Eventhubs时检查Payload大小并避免PayloadSizeExceededException?

时间:2017-05-10 17:54:35

标签: java azure azure-eventhub

所以我得到了这个例外:

com.microsoft.azure.servicebus.PayloadSizeExceededException: Size of the payload exceeded Maximum message size: 256 kb

我认为例外是自我解释的,但是,我不知道该怎么做。

private int MAXBYTES = (int) ((1024 * 256) * .8);
for (EHubMessage message : payloads) {
    byte[] payloadBytes = message.getPayload().getBytes(StandardCharsets.UTF_8);
    EventData sendEvent = new EventData(payloadBytes);
    events.add(sendEvent);
    byteCount += payloadBytes.length;
    if (byteCount > this.MAXBYTES) {
        calls.add(ehc.sendASync(events));
        logs.append("[Size:").append(events.size()).append(" - ").append(byteCount / 1024).append("kb] ");
        events = new LinkedList<EventData>();
        byteCount = 0;
        pushes++;
    }
}

我在计算字节等。我已经考虑过UTF-8,但我认为这无关紧要。 UTF-8可以是多个字节,但应使用&#34; getBytes&#34;来正确计算。

我找不到一种可靠的方法来获取字符串中的字节,我甚至不确定Azure如何计算字节数。 &#34;有效载荷&#34;是一个广泛的声明。可以包括样板材等。

任何想法?如果有一个

那就太好了
EventHubClient.checkPayload(list);

方法但似乎没有。你们如何查看有效载荷大小?

2 个答案:

答案 0 :(得分:0)

根据我的经验,我认为您需要在将新的有效负载添加到events之前先检查当前有效负载计数的大小和新的有效负载,如下所示。

const int MAXBYTES = 1024 * 256; // not necessary to multiply by .8 
for (EHubMessage message : payloads) {
    byte[] payloadBytes = message.getPayload().getBytes(StandardCharsets.UTF_8);
    if (byteCount + payloadBytes.length > this.MAXBYTES) {
        calls.add(ehc.sendASync(events));
        logs.append("[Size:").append(events.size()).append(" - ").append(byteCount / 1024).append("kb] ");
        events = new LinkedList<EventData>();
        byteCount = 0;
        pushes++;
    }
    EventData sendEvent = new EventData(payloadBytes);
    events.add(sendEvent);
}

如果您首先添加新事件数据以计算有效负载大小,则为时已晚,并且将要发送的事件的数据大小可能超出有效负载限制。

答案 1 :(得分:0)

好吧,我应该在原帖中添加更多实际代码。以下是我提出的建议:

private int MAXBYTES = (int) ((1024 * 256) * .9);
for (EHubMessage message : payloads) {
    byte[] payloadBytes = message.getPayload().getBytes(StandardCharsets.UTF_8);
    int propsSize = message.getProps() == null ? 0 : message.getProps().toString().getBytes().length;
    int messageSize = payloadBytes.length + propsSize;
        if (byteCount + messageSize > this.MAXBYTES) {
            calls.add(ehc.sendASync(events));
            logs.append("[Size:").append(events.size()).append(" - ").append(byteCount / 1024).append("kb] ");
            events = new LinkedList<EventData>();
            byteCount = 0;
            pushes++;
        }
        byteCount += messageSize;
        EventData sendEvent = new EventData(payloadBytes);
        sendEvent.getProperties().putAll(message.getProps());
        events.add(sendEvent);
    }
    if (!events.isEmpty()) {
        calls.add(ehc.sendASync(events));
        logs.append("[Size:").append(events.size()).append(" - ").append(byteCount / 1024).append("kb]");
        pushes++;
    }
    // lets wait til they are done.
    CompletableFuture.allOf(calls.toArray(new CompletableFuture[0])).join();
}

如果您注意到,我正在向EventData添加属性,但不计算字节数。 Map的toString()返回类似于:

的内容
{markiscool=markiscool}

同样,我不确定Azure api正在添加的样板字符,但我确信它并不多。请注意,为了以防万一,我仍然支持MAXBYTES。

在api中获得“有效负载大小检查器”方法仍然很好,但我认为它必须首先构建有效负载以将其返回给您。我尝试让我的EHubMessage对象为我解决这个问题,但是字符串上的“getBytes()”实际上做了一些我不想做两次的转换。