当前位置: 首页 > 知识库问答 >
问题:

Java AmazonS3Client getObject挂起,socketRead0期间线程状态卡在_NATIVE中

邵修诚
2023-03-14

我有一个Java应用程序,它运行一系列并行线程,从AmazonS3下载对象块。我注意到,在没有任何问题的情况下运行了几个小时后,最终得到一个特定的块将挂起并导致程序冻结。

Java进程仍在运行,但CPU占用和网络IO很少。执行线程转储时,有一个线程永远不会离开IN_NATIVE状态,在SSL握手过程中,ocketRead0()似乎永远不会返回。下面是转述的堆栈跟踪:

Thread 17260: (state = IN_NATIVE)
 - java.net.SocketInputStream.socketRead0(java.io.FileDescriptor, byte[], int, int, int) @bci=0 (Compiled frame; information may be imprecise)
 - java.net.SocketInputStream.socketRead(java.io.FileDescriptor, byte[], int, int, int) @bci=8, line=116 (Compiled frame)
 - java.net.SocketInputStream.read(byte[], int, int, int) @bci=79, line=170 (Compiled frame)
 - java.net.SocketInputStream.read(byte[], int, int) @bci=11, line=141 (Compiled frame)
 - sun.security.ssl.InputRecord.readFully(java.io.InputStream, byte[], int, int) @bci=21, line=465 (Compiled frame)
 - sun.security.ssl.InputRecord.read(java.io.InputStream, java.io.OutputStream) @bci=32, line=503 (Compiled frame)
 - sun.security.ssl.SSLSocketImpl.readRecord(sun.security.ssl.InputRecord, boolean) @bci=44, line=973 (Compiled frame)
 - sun.security.ssl.SSLSocketImpl.performInitialHandshake() @bci=84, line=1375 (Compiled frame)
 - sun.security.ssl.SSLSocketImpl.startHandshake(boolean) @bci=13, line=1403 (Compiled frame)
 - sun.security.ssl.SSLSocketImpl.startHandshake() @bci=2, line=1387 (Compiled frame)
 - org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(int, java.net.Socket, org.apache.http.HttpHost, java.net.InetSocketAddress, java.net.InetSocketAddress, org.apache.http.protocol.HttpContext) @bci=87, line=533 (Compiled frame)
 - org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(java.net.Socket, java.net.InetSocketAddress, java.net.InetSocketAddress, org.apache.http.params.HttpParams) @bci=69, line=401 (Compiled frame)
 - com.amazonaws.http.conn.ssl.SdkTLSSocketFactory.connectSocket(java.net.Socket, java.net.InetSocketAddress, java.net.InetSocketAddress, org.apache.http.params.HttpParams) @bci=60, line=128 (Compiled frame)
 - org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(org.apache.http.conn.OperatedClientConnection, org.apache.http.HttpHost, java.net.InetAddress, org.apache.http.protocol.HttpContext, org.apache.http.params.HttpParams) @bci=226, line=177 (Compiled frame)
 - org.apache.http.impl.conn.ManagedClientConnectionImpl.open(org.apache.http.conn.routing.HttpRoute, org.apache.http.protocol.HttpContext, org.apache.http.params.HttpParams) @bci=126, line=304 (Compiled frame)
 - org.apache.http.impl.client.DefaultRequestDirector.tryConnect(org.apache.http.impl.client.RoutedRequest, org.apache.http.protocol.HttpContext) @bci=50, line=610 (Compiled frame)
 - org.apache.http.impl.client.DefaultRequestDirector.execute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) @bci=389, line=445 (Compiled frame)
 - org.apache.http.impl.client.AbstractHttpClient.doExecute(org.apache.http.HttpHost, org.apache.http.HttpRequest, org.apache.http.protocol.HttpContext) @bci=365, line=863 (Compiled frame)
 - org.apache.http.impl.client.CloseableHttpClient.execute(org.apache.http.client.methods.HttpUriRequest, org.apache.http.protocol.HttpContext) @bci=14, line=82 (Compiled frame)
 - org.apache.http.impl.client.CloseableHttpClient.execute(org.apache.http.client.methods.HttpUriRequest, org.apache.http.protocol.HttpContext) @bci=3, line=57 (Compiled frame)
 - com.amazonaws.http.AmazonHttpClient.executeOneRequest(com.amazonaws.Request, com.amazonaws.http.HttpResponseHandler, com.amazonaws.http.HttpResponseHandler, com.amazonaws.http.ExecutionContext, com.amazonaws.util.AWSRequestMetrics, com.amazonaws.http.AmazonHttpClient$ExecOneRequestParams) @bci=369, line=728 (Compiled frame)
 - com.amazonaws.http.AmazonHttpClient.executeHelper(com.amazonaws.Request, com.amazonaws.http.HttpResponseHandler, com.amazonaws.http.HttpResponseHandler, com.amazonaws.http.ExecutionContext) @bci=312, line=489 (Compiled frame)
 - com.amazonaws.http.AmazonHttpClient.execute(com.amazonaws.Request, com.amazonaws.http.HttpResponseHandler, com.amazonaws.http.HttpResponseHandler, com.amazonaws.http.ExecutionContext) @bci=150, line=310 (Compiled frame)
 - com.amazonaws.services.s3.AmazonS3Client.invoke(com.amazonaws.Request, com.amazonaws.http.HttpResponseHandler, java.lang.String, java.lang.String) @bci=168, line=3796 (Compiled frame)
 - com.amazonaws.services.s3.AmazonS3Client.getObject(com.amazonaws.services.s3.model.GetObjectRequest) @bci=235, line=1201 (Compiled frame)
...

下面是如何执行的代码片段:

protected static byte[] getChunk(AmazonS3Client client, long start, int offset, String bucket, String key) {
    if(offset < 1){
        return null;
    }
    S3Object obj = null;
    S3ObjectInputStream is = null;
    byte[] buffer = new byte[offset];

    try {
        GetObjectRequest request = new GetObjectRequest(bucket, key);
        request.setRange(start, start + offset);

        obj = client.getObject(request);
        is = obj.getObjectContent();
        int copied = 0;
        int length;
        while ((length = is.read(buffer,copied,offset-copied)) > 0){
            copied += length;
        }

        buffer = (copied < 1) ? null : Arrays.copyOf(buffer, copied);
    } catch (Exception e) {
        buffer = null;
    } finally {
        Util.close(is);
    }
    return buffer;
}

作为补充说明,如果这可以通过不同的AmazonS3Client配置来解决,下面是如何实例化客户端:

private static final String S3_ENDPOINT = "https://s3.amazonaws.com/";

public static AmazonS3Client getAmazonClient(String accessKey, String secretKey){
    AmazonS3Client client = null;
    try {
        ClientConfiguration clientConfig = new ClientConfiguration();
        clientConfig.setProtocol(Protocol.HTTP);

        AWSCredentials credentials = new BasicAWSCredentials(accessKey, secretKey);

        client = new AmazonS3Client(credentials, clientConfig);
        client.setEndpoint(S3_ENDPOINT);
    } catch (Exception e){
        e.printStackTrace();
        client = null;
    }
    return client;
}

(aws java sdk版本1.10.9也是如此)。以下是JVM规范:

java version "1.8.0_51"
Java(TM) SE Runtime Environment (build 1.8.0_51-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.51-b03, mixed mode)

有没有办法克服套接字初始化的问题?

共有1个答案

李意致
2023-03-14

从你的代码中,我可以看到这一点

ClientConfiguration clientConfig = new ClientConfiguration();

ClientConfiguration提供了很多选项。

也许你可以用这个:

setSocketTimeout

然后设定为5000。根据文件:

设置在连接超时并关闭之前,通过已建立的打开连接传输数据的等待时间(以毫秒为单位)。值为0表示无穷大,不建议使用。

default\u REQUEST\u TIMEOUT的默认值为0。

裁判:

DEFAULT_REQUEST_TIMEOUT

setSocketTimeout

 类似资料:
  • 我正在使用Appium Python AWS Device Farm for iOS设备为我的公司进行自动化测试。 然而,当我将我的. ipa文件和Appium Python测试上传到AWS设备群时,运行卡住了,并向我显示状态为“错误”,如果我单击运行以获取详细视图,它会在所有设备运行中显示“待定”(见下面的截图:) 我很确定这不是我的Appium Python测试脚本的问题,因为当将同一个脚本与

  • 我正在寻找关于如何正确使用Kubernetes本地存储PVC的帮助。 我们在Ubuntu上提供了一个kubespray集群,并启用了本地存储提供器。 我们做错了什么?

  • 我们在Wildfly 16上使用Java应用程序,该应用程序使用Eclipse Link与Postgres 9.4数据库连接。应用程序服务器配置为使用连池。该应用程序在夜间将项目索引到Solr实例,有时我们会遇到阻塞线程的问题。似乎数据库查询终究没有返回。我们在持久性单元中设置了查询超时,这似乎不起作用。我们在persistence.xml中添加了以下条目: 该系统使用Java 11 jre。我们

  • 有人能给我解释一下VisualVM中、、和线程状态之间的区别吗。 这是我发现的: :线程仍在运行 :线程正在Hibernate(对线程对象调用了方法yield()) :线程被互斥锁或屏障阻止,正在等待另一个线程释放锁 :停止的线程被暂停,直到获得许可。解压线程通常是通过调用线程对象上的方法unpark()来完成的。 :线程正在等待条件变为true以恢复执行 我无法理解的是州立公园,到底是什么让这条

  • 问题内容: 我正在尝试的代码 我们如何根据其ID暂停/暂停线程?Thread.suspend已过时,必须有一些替代方法来实现。我有线程ID,我想挂起并杀死线程。 编辑:我用这个。 但是我无法停止该线程。 问题答案: 这些天杀死线程的正确方法就是使用它。这集真和原因,以及一些其他的方法来扔。 在线程代码内部,您应该执行类似以下的操作,检查以确保它没有被中断。 这是一个如何在线程内部处理中断异常的示例