菜鸟教程小白 发表于 2022-12-13 00:01:13

java - Apple 收据验证时的连接重置 (Java 8)


                                            <p><p>我正在使用 Java 服务器验证 Apple 付款收据及其 <a href="https://buy.itunes.apple.com/verifyReceipt" rel="noreferrer noopener nofollow">validation server</a>。 .对于有效收据,我们大约 50% 的请求失败并出现“SocketException:连接重置”(稍后重试成功)。</p>

<p>我在部署在 Java 7 上的另一台服务器上没有遇到这种行为,但在部署到 Java 8 时开始遇到这种情况。</p>

<p>我看到 Java 8 中的默认 TLS 协议(protocol)从 TLSv1 更改为 TLSv1.2,因此我尝试将默认协议(protocol)更改为使用 Java 7 的默认值,但没有看到任何改进。这是我使用的 JVM 属性:</p>

<pre><code>-Djdk.tls.client.protocols=&#34;TLSv1,TLSv1.2,TLSv1.1&#34;
</code></pre>

<p>知道为什么我在大约一半的时间内收到错误“SocketException:连接重置”吗?</p>

<p>谢谢!</p>

<p>[更新]</p>

<p>我设法获取失败请求的调试和 ssl 日志:</p>

<pre><code>DEBUG    org.apache.http.impl.conn.PoolingClientConnectionManager: Connection request:
DEBUG org.apache.http.impl.conn.PoolingClientConnectionManager: Connection leased:
DEBUG org.apache.http.impl.client.DefaultHttpClient: Stale connection check
dw-66 - POST /v1/reqrep, setSoTimeout(1) called
dw-66 - POST /v1/reqrep, handling exception:   java.net.SocketTimeoutException: Read timed out
dw-66 - POST /v1/reqrep, setSoTimeout(15000) called
dw-66 - POST /v1/reqrep, setSoTimeout(15000) called
DEBUG org.apache.http.client.protocol.RequestAddCookies: CookieSpec selected: ignoreCookies
DEBUG org.apache.http.client.protocol.RequestAuthCache: Auth cache not set in the context
DEBUG org.apache.http.client.protocol.RequestTargetAuthentication: Target auth state: UNCHALLENGED
DEBUG org.apache.http.client.protocol.RequestProxyAuthentication: Proxy auth state: UNCHALLENGED
DEBUG org.apache.http.impl.client.DefaultHttpClient: Attempt 1 to execute request
DEBUG org.apache.http.impl.conn.DefaultClientConnection: Sending request: POST /verifyReceipt HTTP/1.1
DEBUG org.apache.http.wire:&gt;&gt; &#34;POST /verifyReceipt HTTP/1.1[\r][\n]&#34;
DEBUG org.apache.http.wire:&gt;&gt; &#34;Content-Type: application/x-www-form-urlencoded[\r][\n]&#34;
DEBUG org.apache.http.wire:&gt;&gt; &#34;Content-Length: 6839[\r][\n]&#34;
DEBUG org.apache.http.wire:&gt;&gt; &#34;Host: buy.itunes.apple.com[\r][\n]&#34;
DEBUG org.apache.http.wire:&gt;&gt; &#34;Connection: Keep-Alive[\r][\n]&#34;
DEBUG org.apache.http.wire:&gt;&gt; &#34;[\r][\n]&#34;
DEBUG org.apache.http.headers: &gt;&gt; POST /verifyReceipt HTTP/1.1
DEBUG org.apache.http.headers: &gt;&gt; Content-Type: application/x-www-form-urlencoded
DEBUG org.apache.http.headers: &gt;&gt; Content-Length: 6839
DEBUG org.apache.http.headers: &gt;&gt; Host: buy.itunes.apple.com
DEBUG org.apache.http.headers: &gt;&gt; Connection: Keep-Alive
dw-66 - POST /v1/reqrep, WRITE: TLSv1.2 Application Data, length = 179
dw-66 - POST /v1/reqrep, WRITE: TLSv1.2 Application Data, length = 6863
dw-66 - POST /v1/reqrep, handling exception: java.net.SocketException: Connection reset
%% Invalidated:
dw-66 - POST /v1/reqrep, SEND TLSv1.2 ALERT:fatal, description = unexpected_message
dw-66 - POST /v1/reqrep, WRITE: TLSv1.2 Alert, length = 26
dw-66 - POST /v1/reqrep, Exception sending alert: java.net.SocketException: Broken pipe
dw-66 - POST /v1/reqrep, called closeSocket()
dw-66 - POST /v1/reqrep, called close()
dw-66 - POST /v1/reqrep, called closeInternal(true)
DEBUG org.apache.http.impl.conn.DefaultClientConnection: Connection 0.0.0.0:59028&lt;-&gt;17.173.66.179:443 closed
DEBUG org.apache.http.impl.client.DefaultHttpClient: Closing the connection.
DEBUG org.apache.http.impl.conn.DefaultClientConnection: Connection 0.0.0.0:59028&lt;-&gt;17.173.66.179:443 closed
ERROR com.spaceape.http.client.HttpClient$$anon$1: http retry for it. executionCount=1
! java.net.SocketException: Connection reset
&lt;ommitted stack trace&gt;
INFO org.apache.http.impl.client.DefaultHttpClient: I/O exception (java.net.SocketException) caught when processing request to {s}-&gt;https://buy.itunes.apple.com:443: Connection reset
DEBUG org.apache.http.impl.client.DefaultHttpClient: Connection reset
! java.net.SocketException: Connection reset
&lt;ommitted stack trace&gt;
INFO org.apache.http.impl.client.DefaultHttpClient: Retrying request to {s}-&gt;https://buy.itunes.apple.com:443
DEBUG org.apache.http.impl.client.DefaultHttpClient: Reopening the direct connection.
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
Ignoring unavailable cipher suite: TLS_DHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
Ignoring unavailable cipher suite: TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
DEBUG org.apache.http.impl.conn.DefaultClientConnectionOperator: Connecting to buy.itunes.apple.com:443
dw-66 - POST /v1/reqrep, setSoTimeout(15000) called
Allow unsafe renegotiation: false
Allow legacy hello messages: true
Is initial handshake: true
Is secure renegotiation: false
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1
Ignoring unsupported cipher suite: TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 for TLSv1.1
Ignoring unsupported cipher suite: TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 for TLSv1.1
%% No cached client session
*** ClientHello, TLSv1.2
...
</code></pre>

<p>之后,SSL 连接成功重新打开并进行验证。
上面日志中连接被重置的具体位是:</p>

<pre><code>dw-66 - POST /v1/reqrep, WRITE: TLSv1.2 Application Data, length = 179
dw-66 - POST /v1/reqrep, WRITE: TLSv1.2 Application Data, length = 6863
dw-66 - POST /v1/reqrep, handling exception: java.net.SocketException: Connection reset
%% Invalidated:
dw-66 - POST /v1/reqrep, SEND TLSv1.2 ALERT:fatal, description = unexpected_message
dw-66 - POST /v1/reqrep, WRITE: TLSv1.2 Alert, length = 26
dw-66 - POST /v1/reqrep, Exception sending alert: java.net.SocketException: Broken pipe
dw-66 - POST /v1/reqrep, called closeSocket()
dw-66 - POST /v1/reqrep, called close()
dw-66 - POST /v1/reqrep, called closeInternal(true)
DEBUG org.apache.http.impl.conn.DefaultClientConnection: Connection 0.0.0.0:59028&lt;-&gt;17.173.66.179:443 closed
DEBUG org.apache.http.impl.client.DefaultHttpClient: Closing the connection.
DEBUG org.apache.http.impl.conn.DefaultClientConnection: Connection 0.0.0.0:59028&lt;-&gt;17.173.66.179:443 closed
</code></pre>

<p>任何帮助将不胜感激!</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我们目前遇到了同样的问题。如果我们从服务器调用此命令大约 5-10 次:</p>

<pre><code>openssl s_client -connect buy.itunes.apple.com:443 -tls1_2
</code></pre>

<p>它最终会挂起而没有任何响应。并且推测 java <em>SocketException</em> (我们也在日志中看到)正在发生,因为它达到了超时。 Apple 的验证服务器之一可能有问题?</p></p>
                                   
                                                <p style="font-size: 20px;">关于java - Apple 收据验证时的连接重置 (Java 8),我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/42485299/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/42485299/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: java - Apple 收据验证时的连接重置 (Java 8)