2017-05-10 30 views
0

所以我得到這個異常:如何在使用Azure Eventhub時檢查Payload大小並避免PayloadSizeExceededException?

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可以多於一個字節,但應該用「getBytes」正確計數。

我找不到一個可靠的方式來獲取字符串中的字節,我甚至不知道Azure如何計算字節。 「有效載荷」是一個廣泛的聲明。可以包括樣板材料等。

任何想法?如果有一個

EventHubClient.checkPayload(list); 

方法,但似乎沒有。你們如何檢查有效載荷大小?

+0

使用'SerializedSizeInBytes'屬性,請參閱https://docs.microsoft.com/en-us/dotnet/api/microsoft.servicebus.messaging.eventdata.serializedsizeinbytes?view=azureservicebus-4.0.0。 –

+1

@PeterBons看起來像是關於Java SDK的問題... – Mikhail

+0

你們知道這是否使用JSON傳輸數據?我想知道是否JSON化整個EventData對象,如果這會給我答案。 – markthegrea

回答

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); 
} 

如果先添加了新的事件數據來算有效載荷的大小,這是爲時已晚,這可能是將要發送的事件的數據大小超出了有效載荷的限制。

+0

是的,我看到了這個bug,還沒有修復它。但是,我們所有的有效載荷都在1kb左右,非常統一。你有過這方面的經驗嗎?我目前的理論是整個EventData對象被Jsonized。這對每個對象都會有一些開銷。我們最終發送了不少對象(因爲它們很小),所以任何開銷都可能使我們處於邊緣。 – markthegrea

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,但不計算字節。了toString()的返回地圖是這樣的:

{markiscool=markiscool} 

同樣,我不知道的是,Azure的API被添加樣板人物,但我相信它的並不多。請注意,爲了以防萬一,我仍然退出MAXBYTES。

在api中獲得「有效載荷大小檢查器」方法仍然很好,但我會想象它必須首先構建有效載荷以將其還給您。我嘗試讓我的EHubMessage對象知道這一點,但字符串上的「getBytes()」實際上做了一些我不想做兩次的轉換。

相關問題