Liferay并发FileEntry上传

时间:2017-04-04 07:52:33

标签: java file concurrency upload liferay

问题陈述:

在liferay中我必须将一个zip文件导入到liferay cms中的某个文件夹中,到目前为止,我已经实现了zip文件的串行解压缩,创建了它的文件夹,然后是它的文件。这里的问题是整个过程需要花费很多时间。所以我不得不在创建文件夹和创建文件时使用并行方法。

我的解决方案:

我使用了java java.util.concurrent.ExecutorService 来创建 Executors.newFixedThreadPool(NTHREDS),其中NTHREDS是要并行运行的线程数(比如5)

  1. 我从zip和放置的zip列表中读取了所有文件夹路径 将文件夹路径作为HashMap中的键进行(文件)
  2. 遍历地图中的所有键并按顺序创建文件夹
  3. 现在遍历地图中的zip条目(文件)列表并传递给线程工作者,每个工作者一个文件,然后将这些工作人员发送到 ExecutorService执行
  4. 到目前为止,我没有发现整个过程的时间有任何显着缩短,我是否正朝着正确的方向前进? liferay是否支持并发文件添加?我究竟做错了什么?

    我将非常感谢这方面的任何帮助

    下面是我的代码

    imports 
    ...
    ...
    public class TestImportZip {
    
        private static final int NTHREDS = 5;
        ExecutorService executor = null;
        ...
            ...
            ....
        Map<String,Folder> folders = new HashMap<String,Folder>();
        File zipsFile = null;
    
        public TestImportZip(............,File zipFile, .){
    
            .
                    .
            this.zipsFile = zipFile;
            this.executor = Executors.newFixedThreadPool(NTHREDS);
        }
    
           // From here the process starts
        public void importZip() {
    
            Map<String,List<ZipEntry>> foldersMap = new HashMap<String, List<ZipEntry>>();
    
            try (ZipFile zipFile = new ZipFile(zipsFile)) {
                zipFile.stream().forEach(entry -> {
    
                       String entryName = entry.getName();
                       if(entryName.contains("/")) {
    
                           String key = entryName.substring(0, entryName.lastIndexOf("/"));
    
                           List<ZipEntry> zipEntries = foldersMap.get(key);
    
                           if(zipEntries == null){
                               zipEntries = new ArrayList<>();
                           }
    
                           zipEntries.add(entry);
    
                           foldersMap.put(key,zipEntries);
    
                       }
                   });
    
                createFolders(foldersMap.keySet());
    
                createFiles(foldersMap);
    
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        private void createFolders(Set<String> folderPathSets) {
    
            // create folder and put the folder in map
           .
           .
           .
    
        folders.put(folderPath,folder); 
        }
    
        private void createFiles(Map<String, List<ZipEntry>> foldersMap) {
              .
                  .
                  . 
             //Traverse all the files from all the list in map and send them to worker
           createFileWorker(folderPath,zipEntry);
    
        }
    
        private void createFileWorker(String folderPath,ZipEntry zipEntry) {
    
            CreateEntriesWorker cfw = new CreateEntriesWorker(folderPath, zipEntry);
            executor.execute(cfw);
        }
    
        class CreateEntriesWorker implements  Runnable{
    
            Folder folder = null;
            ZipEntry entryToCreate = null;
    
    
            public CreateEntriesWorker(String folderPath, ZipEntry zipEntry){
    
                this.entryToCreate = zipEntry;
                // get folder from already created folder map
                this.folder = folders.get(folderPath);
    
            }
    
            public void run() {
    
                if(this.folder != null) {
                    long startTime = System.currentTimeMillis();
    
                    try (ZipFile zipFile = new ZipFile(zipsFile)) {
    
                            InputStream inputStream = zipFile.getInputStream(entryToCreate);
    
                            try{
    
                                String name = entryToCreate.getName();
                                // created file entry here 
                            }catch(Exception e){
    
                            }finally{
    
                                if(inputStream != null)
                                    inputStream.close();
                            }
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
        }
    
    }
    

1 个答案:

答案 0 :(得分:1)

您的简化代码不包含我识别的任何Liferay参考。您提供的说明会提示您尝试优化某些代码,但不会在尝试中获得更好的性能。这通常表明您正在尝试优化问题的错误方面(或者它已经非常优化)。

您需要确定操作的实际瓶颈,以便了解优化是否可行。有一个常见的说法,即过早优化是所有邪恶的根源&#34;。这是什么意思?

我在这里完全编号 - 不要引用我的话:他们是为了说明而自由发明的。让我们说,您将Zip文件的内容添加到Liferay的存储库的操作将分配到以下百分比的操作资源:

  • 4%zip文件解码/解压缩
  • 拉链操作和临时文件的6%文件I / O
  • 用于存储文件的10%数据库操作
  • 60%用于从zip文件中存储的word,pdf,excel和其他文件中提取纯文本,以便在全文索引中索引文档
  • 用于汇总索引的全文索引库的20%开销。

假设您正在优化zip文件解码/解压缩 - 您可以期待数字的总体改进吗?

虽然我的数字已经弥补:如果您的优化没有任何结果,我建议您撤消它们,测量您需要优化的位置并追踪该位置(或接受它并升级您的硬件,如果地方遥不可及)。

运行CPU,I / O,内存和其他潜在瓶颈的数字。确定您的实际瓶颈#1,修复它,再次测量。你会发现#2的瓶颈已经得到了提升。冲洗重复,直到你开心