Storm クラスターで AWS SQS キューを読み取るときに ParseError 例外が発生する原因は何ですか? 質問する

Storm クラスターで AWS SQS キューを読み取るときに ParseError 例外が発生する原因は何ですか? 質問する

私は Storm 0.8.1 を使用して Amazon SQS キューから受信メッセージを読み取っていますが、その際に一貫して例外が発生します。

2013-12-02 02:21:38 executor [ERROR] 
java.lang.RuntimeException: com.amazonaws.AmazonClientException: Unable to unmarshall response (ParseError at [row,col]:[1,1]
Message: JAXP00010001: The parser has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK.)
        at REDACTED.spouts.SqsQueueSpout.handleNextTuple(SqsQueueSpout.java:219)
        at REDACTED.spouts.SqsQueueSpout.nextTuple(SqsQueueSpout.java:88)
        at backtype.storm.daemon.executor$fn__3976$fn__4017$fn__4018.invoke(executor.clj:447)
        at backtype.storm.util$async_loop$fn__465.invoke(util.clj:377)
        at clojure.lang.AFn.run(AFn.java:24)
        at java.lang.Thread.run(Thread.java:701)
Caused by: com.amazonaws.AmazonClientException: Unable to unmarshall response (ParseError at [row,col]:[1,1]
Message: JAXP00010001: The parser has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK.)
        at com.amazonaws.http.AmazonHttpClient.handleResponse(AmazonHttpClient.java:524)
        at com.amazonaws.http.AmazonHttpClient.executeHelper(AmazonHttpClient.java:298)
        at com.amazonaws.http.AmazonHttpClient.execute(AmazonHttpClient.java:167)
        at com.amazonaws.services.sqs.AmazonSQSClient.invoke(AmazonSQSClient.java:812)
        at com.amazonaws.services.sqs.AmazonSQSClient.receiveMessage(AmazonSQSClient.java:575)
        at REDACTED.spouts.SqsQueueSpout.handleNextTuple(SqsQueueSpout.java:191)
        ... 5 more
Caused by: javax.xml.stream.XMLStreamException: ParseError at [row,col]:[1,1]
Message: JAXP00010001: The parser has encountered more than "64000" entity expansions in this document; this is the limit imposed by the JDK.
        at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.setInputSource(XMLStreamReaderImpl.java:219)
        at com.sun.org.apache.xerces.internal.impl.XMLStreamReaderImpl.<init>(XMLStreamReaderImpl.java:189)
        at com.sun.xml.internal.stream.XMLInputFactoryImpl.getXMLStreamReaderImpl(XMLInputFactoryImpl.java:277)
        at com.sun.xml.internal.stream.XMLInputFactoryImpl.createXMLStreamReader(XMLInputFactoryImpl.java:129)
        at com.sun.xml.internal.stream.XMLInputFactoryImpl.createXMLEventReader(XMLInputFactoryImpl.java:78)
        at com.amazonaws.http.StaxResponseHandler.handle(StaxResponseHandler.java:85)
        at com.amazonaws.http.StaxResponseHandler.handle(StaxResponseHandler.java:41)
        at com.amazonaws.http.AmazonHttpClient.handleResponse(AmazonHttpClient.java:503)
        ... 10 more

キュー上のデータをデバッグしましたが、すべて問題ないようです。API の XML 応答がなぜこのような問題を引き起こすのかわかりません。何かアイデアはありますか?

ベストアンサー1

ここで長年の自分の疑問に答えます。

現在、Oracle と OpenJDK の Java には XML 拡張制限処理のバグがあり、複数の XML ドキュメントを解析するときに共有カウンターがデフォルトの上限に達してしまいます。

  1. https://blogs.oracle.com/joew/entry/jdk_7u45_aws_issue_123
  2. 参考:
  3. 参考:

私たちのバージョン (6b27-1.12.6-1ubuntu0.12.04.4) は影響を受けないと思っていましたが、OpenJDK バグレポートに記載されているサンプルコードを実行すると、実際にバグの影響を受けることが確認されました。

この問題を回避するには、jdk.xml.entityExpansionLimit=0Storm ワーカーに渡す必要がありました。クラスター全体に以下を追加することでstorm.yaml、この問題を軽減できました。

supervisor.childopts: "-Djdk.xml.entityExpansionLimit=0"
worker.childopts: "-Djdk.xml.entityExpansionLimit=0"

技術的には、これはサービス拒否攻撃にさらされる可能性があることに注意する必要がありますが、XML ドキュメントは SQS からのみ送信されるため、誰かが悪意のある XML を偽造してワーカーを強制終了するのではないかと心配する必要はありません。

おすすめ記事