项目场景:
项目场景:项目文件要总一个存储云迁移到另外一个云上面,亚马逊云中其中一个容器文件过大,本来打算压缩到zip包后下载,但运行时间过长,之后修改了代码,改为,获取该容器所有文件后,多线程下载到本地,将近10w条数据,在迁移过程中,下载到5000条数据后,遇到的一个连接超时问题,记录一下。
问题描述
执行代码
Iterable<ListBlobItem> blobItems = container.listBlobs();
blobItems.forEach(blobItem -> {
//文件下载到本地的操作
fileAysncDownBiz.downFile(blobItem);
})
报错信息
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(SocketInputStream.java:210)
原因分析:
考虑过迭代器是否一次只能迭代5000条数据,但报错的是连接超时问题,而且后边测试下来,每5000条遍历都要卡一下,然后才继续遍历,打日志可以看到这个信息,所以应该是亚马逊云连接的问题,也就是说,获取全部容器中的文件,亚马逊提供的API可能是 5000条一次存入迭代器中,遍历完后,再去获取后5000条。
解决方案:
获取到迭代器后,先遍历,插入到数组里边,全部遍历完成后,再遍历数组,进行多线程本地创建文件的操作。
public void getAllFileLocalAsync(String containerName) {
//获取微软云容器
CloudBlobContainer container = AzureStorageBo.getAzureContainer(
azureStorageBo.getStorageConnectionString(), containerName);
Iterable<ListBlobItem> blobItems = container.listBlobs();
// 因为要做大量的添加操作 ,这里用 linkedList,
// 测试下来,容器遍历 ArrayList 话费了10分钟左右,LinkedList 花费了6分钟,时间将近少了一半
// ArrayList<ListBlobItem> blobList = new ArrayList<>();
LinkedList<ListBlobItem> blobList = new LinkedList<>();
blobItems.forEach(blobList::add);
log.info("总文件数:" + blobList.size());
blobList.forEach(blob -> {
fileAysncDownBiz.downFile(blob);
});
log.info("文件下载完毕,下载了:" + blobList.size() + "个文件");
}