大量执行OSS PutObject时卡住的问题排查-阿里云开发者社区

开发者社区> 开发与运维> 正文

大量执行OSS PutObject时卡住的问题排查

简介: ##问题反馈 接到有客户反馈,在批量putobject时,发现上传到一定数量后应用卡住了,同时句柄数增加明显。 客户表示 1.使用10个worker线程进行put操作。 2.每个线程独立使用OssClient。 3.OssClient没有执行shutdown ##排查过程 根据客户的描述,写了一个类似的程序来进行复现 开启五个线程,每个线程上传10000次object来测试

问题反馈

接到有客户反馈,在批量putobject时,发现上传到一定数量后应用卡住了,同时句柄数增加明显。
客户表示
1.使用10个worker线程进行put操作。
2.每个线程独立使用OssClient。
3.OssClient没有执行shutdown

排查过程

根据客户的描述,写了一个类似的程序来进行复现
开启五个线程,每个线程上传10000次object来测试

代码片段:

public static void main(String args[]) {
RunnableDemo R1 = new RunnableDemo( "Thread-1");
R1.start();
RunnableDemo R2 = new RunnableDemo( "Thread-2");
R2.start();
RunnableDemo R3 = new RunnableDemo( "Thread-3");
R3.start();
RunnableDemo R4 = new RunnableDemo( "Thread-4");
R4.start();
RunnableDemo R5 = new RunnableDemo( "Thread-5");
R5.start();
 }
public void run() {
          System.out.println("Running " +  threadName );
             for(int i = 0; i < 10000; i++) {
                 try {
                    System.out.println("Thread: " + threadName + ", " + i);
                    //上传部分
                    String content = new String();
                    content="12345";
                // 创建上传Object的Metadata
                ObjectMetadata meta = new ObjectMetadata();
                // 设置上传文件长度
                meta.setContentLength(content.length());
                // 设置上传MD5校验
                String md5 = BinaryUtil.toBase64String(BinaryUtil.calculateMd5(content.getBytes()));
                meta.setContentMD5(md5);
                // 设置上传内容类型
                meta.setContentType("text/plain");
                meta.setServerSideEncryption("AES256");
                // 上传文件
                PutObjectRequest putObjectRequest=new PutObjectRequest("ruide", "1.txt", new ByteArrayInputStream(content.getBytes()), meta);
                PutObjectResult por = ossclient.putObject(putObjectRequest);
                System.out.println("requestid:"+por.getRequestId());
                Thread.sleep(0);
                 }catch (Exception e) {
                     System.out.println("Thread " +  threadName + " interrupted.");
                  }
             }
          System.out.println("Thread " +  threadName + " exiting.");
       }

测试5W次上传请求正常。

而在增加callback后出现了问题

PutObjectRequest putObjectRequest=new PutObjectRequest("ruide", "1.txt", new ByteArrayInputStream(content.getBytes()), meta);
Callback callback = new Callback();
callback.setCallbackUrl("http://xx.xxx.xx.xx/Revice.ashx");
callback.setCallbackBody("bucket:${bucket},size:${size}");
putObjectRequest.setCallback(callback);
PutObjectResult por = ossclient.putObject(putObjectRequest);

1.png

总结

看到上传确实卡住了。减少到1个线程,依然如此,看来并非是线程导致。
在putobject上传的时候,同时也会看到javaw进程的句柄数不断增加。
通过和OSS后端同学确认,在putobject时,如果没有callback是不需要句柄开销的。但如果
PutObjectResult putObjectResult = ossClient.putObject(putObjectRequest);
即使不显性的read,那么也会产生句柄开销。而目前的句柄数是1000,当句柄数用完也就无法分配新的句柄导致程序卡住。需要增加
putObjectResult.getCallbackResponseBody().close();

添加后测试,测试OK
2.png
相关文档说明见https://help.aliyun.com/document_detail/32013.html

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章