最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java負載均衡服務器實現上傳文件同步

 更新時間:2020年09月19日 16:22:03   作者:賈樹丙  
這篇文章主要介紹了Java負載均衡服務器實現上傳文件同步,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下

負載服務器Z,應用服務器A 和B ,從A上傳的附件,如何在B上下載下來?

這個問題我的解決思路如下(后來被一個裝逼的面試官給批評了這種做法,不過我瞧不起他)

服務器A、B 上傳附件的時候,將這個附件備份到服務器Z ,當A、B下載文件的時候,首先會在自己服務器的目錄下尋找,如果找不到,就會從服務器Z 上下載一份到當前服務器。

服務器之間的文件備份通過sftp,參考:http://m.fzitv.net/article/196008.htm(下文中的SftpCustom 類就是這個鏈接里的 “SFTP上傳下載文件例子” 中的類)

這里主要介紹一下重寫上傳、下載的方法時應該添加的代碼

上傳文件,異步操作

 new Thread(() -> {

  SftpCustom fu = new SftpCustom();
  fu.upload(file.getAbsolutePath(), getFileName(fileDescr));
  fu.closeChannel();
}).start();

下載文件,先從當前服務器尋找

String tmpPath = roots[0].getPath() + '/' + getFileName(fileDescr);
File file2 = new File(tmpPath);
if (file2.exists()) {
  return FileUtils.openInputStream(file2);
}

SftpCustom fu = new SftpCustom();
fu.download(getFileName(fileDescr), tmpPath);
file2 = new File(tmpPath);
inputStream = FileUtils.openInputStream(file2);
fu.closeChannel();
return inputStream;

cuba 框架中重寫上傳文件類FileStorage.java 的代碼如下:

package com.haulmont.cuba.core.app.custom;

import com.google.common.util.concurrent.ThreadFactoryBuilder;
import com.haulmont.cuba.core.app.FileStorageAPI;
import com.haulmont.cuba.core.app.ServerConfig;
import com.haulmont.cuba.core.entity.FileDescriptor;
import com.haulmont.cuba.core.global.*;
import com.haulmont.cuba.core.sys.AppContext;
import com.haulmont.cuba.core.sys.SecurityContext;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import static com.haulmont.bali.util.Preconditions.checkNotNullArgument;

public class FileStorage implements FileStorageAPI {

  private final Logger log = LoggerFactory.getLogger(FileStorage.class);

  @Inject
  protected UserSessionSource userSessionSource;

  @Inject
  protected TimeSource timeSource;

  @Inject
  protected Configuration configuration;

  protected boolean isImmutableFileStorage;

  protected ExecutorService writeExecutor = Executors.newFixedThreadPool(5,
      new ThreadFactoryBuilder().setNameFormat("FileStorageWriter-%d").build());

  protected volatile File[] storageRoots;

  @PostConstruct
  public void init() {
    this.isImmutableFileStorage = configuration.getConfig(ServerConfig.class).getImmutableFileStorage();
  }

  /**
   * INTERNAL. Don't use in application code.
   */
  public File[] getStorageRoots() {
    if (storageRoots == null) {
      String conf = configuration.getConfig(ServerConfig.class).getFileStorageDir();
      if (StringUtils.isBlank(conf)) {
        String dataDir = configuration.getConfig(GlobalConfig.class).getDataDir();
        File dir = new File(dataDir, "filestorage");
        dir.mkdirs();
        storageRoots = new File[]{dir};
      } else {
        List<File> list = new ArrayList<>();
        for (String str : conf.split(",")) {
          str = str.trim();
          if (!StringUtils.isEmpty(str)) {
            File file = new File(str);
            if (!list.contains(file))
              list.add(file);
          }
        }
        storageRoots = list.toArray(new File[list.size()]);
      }
    }
    return storageRoots;
  }

  @Override
  public long saveStream(final FileDescriptor fileDescr, final InputStream inputStream) throws FileStorageException {
    checkFileDescriptor(fileDescr);

    File[] roots = getStorageRoots();

    // Store to primary storage

    checkStorageDefined(roots, fileDescr);
    checkPrimaryStorageAccessible(roots, fileDescr);

    File dir = getStorageDir(roots[0], fileDescr);
    dir.mkdirs();
    checkDirectoryExists(dir);

    final File file = new File(dir, getFileName(fileDescr));
    checkFileExists(file);

    long size = 0;
    OutputStream os = null;
    try {
      os = FileUtils.openOutputStream(file);
      size = IOUtils.copyLarge(inputStream, os);
      os.flush();
      writeLog(file, false);

      new Thread(() -> {
        SftpCustom fu = new SftpCustom();
        fu.upload(file.getAbsolutePath(), getFileName(fileDescr));
        fu.closeChannel();
      }).start();

    } catch (IOException e) {
      IOUtils.closeQuietly(os);
      FileUtils.deleteQuietly(file);

      throw new FileStorageException(FileStorageException.Type.IO_EXCEPTION, file.getAbsolutePath(), e);
    } finally {
      IOUtils.closeQuietly(os);
    }

    // Copy file to secondary storages asynchronously

    final SecurityContext securityContext = AppContext.getSecurityContext();
    for (int i = 1; i < roots.length; i++) {
      if (!roots[i].exists()) {
        log.error("Error saving {} into {} : directory doesn't exist", fileDescr, roots[i]);
        continue;
      }

      File copyDir = getStorageDir(roots[i], fileDescr);
      final File fileCopy = new File(copyDir, getFileName(fileDescr));

      writeExecutor.submit(new Runnable() {
        @Override
        public void run() {
          try {
            AppContext.setSecurityContext(securityContext);
            FileUtils.copyFile(file, fileCopy, true);
            writeLog(fileCopy, false);
          } catch (Exception e) {
            log.error("Error saving {} into {} : {}", fileDescr, fileCopy.getAbsolutePath(), e.getMessage());
          } finally {
            AppContext.setSecurityContext(null);
          }
        }
      });
    }

    return size;
  }

  protected void checkFileExists(File file) throws FileStorageException {
    if (file.exists() && isImmutableFileStorage)
      throw new FileStorageException(FileStorageException.Type.FILE_ALREADY_EXISTS, file.getAbsolutePath());
  }

  protected void checkDirectoryExists(File dir) throws FileStorageException {
    if (!dir.exists())
      throw new FileStorageException(FileStorageException.Type.STORAGE_INACCESSIBLE, dir.getAbsolutePath());
  }

  protected void checkPrimaryStorageAccessible(File[] roots, FileDescriptor fileDescr) throws FileStorageException {
    if (!roots[0].exists()) {
      log.error("Inaccessible primary storage at {}", roots[0]);
      throw new FileStorageException(FileStorageException.Type.STORAGE_INACCESSIBLE, fileDescr.getId().toString());
    }
  }

  protected void checkStorageDefined(File[] roots, FileDescriptor fileDescr) throws FileStorageException {
    if (roots.length == 0) {
      log.error("No storage directories defined");
      throw new FileStorageException(FileStorageException.Type.STORAGE_INACCESSIBLE, fileDescr.getId().toString());
    }
  }

  @Override
  public void saveFile(final FileDescriptor fileDescr, final byte[] data) throws FileStorageException {
    checkNotNullArgument(data, "File content is null");
    saveStream(fileDescr, new ByteArrayInputStream(data));
  }

  protected synchronized void writeLog(File file, boolean remove) {
    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");

    StringBuilder sb = new StringBuilder();
    sb.append(df.format(timeSource.currentTimestamp())).append(" ");
    sb.append("[").append(userSessionSource.getUserSession().getUser()).append("] ");
    sb.append(remove ? "REMOVE" : "CREATE").append(" ");
    sb.append("\"").append(file.getAbsolutePath()).append("\"\n");

    File rootDir;
    try {
      rootDir = file.getParentFile().getParentFile().getParentFile().getParentFile();
    } catch (NullPointerException e) {
      log.error("Unable to write log: invalid file storage structure", e);
      return;
    }
    File logFile = new File(rootDir, "storage.log");
    try {
      try (FileOutputStream fos = new FileOutputStream(logFile, true)) {
        IOUtils.write(sb.toString(), fos, StandardCharsets.UTF_8.name());
      }
    } catch (IOException e) {
      log.error("Unable to write log", e);
    }
  }

  @Override
  public void removeFile(FileDescriptor fileDescr) throws FileStorageException {
    checkFileDescriptor(fileDescr);

    File[] roots = getStorageRoots();
    if (roots.length == 0) {
      log.error("No storage directories defined");
      return;
    }

    for (File root : roots) {
      File dir = getStorageDir(root, fileDescr);
      File file = new File(dir, getFileName(fileDescr));
      if (file.exists()) {
        if (!file.delete()) {
          throw new FileStorageException(FileStorageException.Type.IO_EXCEPTION, "Unable to delete file " + file.getAbsolutePath());
        } else {
          writeLog(file, true);
        }
      }
    }
  }

  protected void checkFileDescriptor(FileDescriptor fd) {
    if (fd == null || fd.getCreateDate() == null) {
      throw new IllegalArgumentException("A FileDescriptor instance with populated 'createDate' attribute must be provided");
    }
  }

  @Override
  public InputStream openStream(FileDescriptor fileDescr) throws FileStorageException {
    checkFileDescriptor(fileDescr);

    File[] roots = getStorageRoots();
    if (roots.length == 0) {
      log.error("No storage directories available");
      throw new FileStorageException(FileStorageException.Type.FILE_NOT_FOUND, fileDescr.getId().toString());
    }

    InputStream inputStream = null;
    for (File root : roots) {
      File dir = getStorageDir(root, fileDescr);

      File file = new File(dir, getFileName(fileDescr));
      if (!file.exists()) {
        log.error("File " + file + " not found");
        continue;
      }

      try {
        inputStream = FileUtils.openInputStream(file);
        break;
      } catch (IOException e) {
        log.error("Error opening input stream for " + file, e);
      }
    }
    if (inputStream != null) {
      return inputStream;
    } else {
      try {
        String tmpPath = roots[0].getPath() + '/' + getFileName(fileDescr);
        File file2 = new File(tmpPath);
        if (file2.exists()) {
          return FileUtils.openInputStream(file2);
        }

        SftpCustom fu = new SftpCustom();
        fu.download(getFileName(fileDescr), tmpPath);
        file2 = new File(tmpPath);
        inputStream = FileUtils.openInputStream(file2);
        fu.closeChannel();
        return inputStream;
      } catch (Exception e) {
        throw new FileStorageException(FileStorageException.Type.FILE_NOT_FOUND, fileDescr.getId().toString());
      }
    }
  }

  @Override
  public byte[] loadFile(FileDescriptor fileDescr) throws FileStorageException {
    InputStream inputStream = openStream(fileDescr);
    try {
      return IOUtils.toByteArray(inputStream);
    } catch (IOException e) {
      throw new FileStorageException(FileStorageException.Type.IO_EXCEPTION, fileDescr.getId().toString(), e);
    } finally {
      IOUtils.closeQuietly(inputStream);
    }
  }

  @Override
  public boolean fileExists(FileDescriptor fileDescr) {
    checkFileDescriptor(fileDescr);

    File[] roots = getStorageRoots();
    for (File root : roots) {
      File dir = getStorageDir(root, fileDescr);
      File file = new File(dir, getFileName(fileDescr));
      if (file.exists()) {
        return true;
      }
    }
    return false;
  }

  /**
   * INTERNAL. Don't use in application code.
   */
  public File getStorageDir(File rootDir, FileDescriptor fileDescriptor) {
    checkNotNullArgument(rootDir);
    checkNotNullArgument(fileDescriptor);

    Calendar cal = Calendar.getInstance();
    cal.setTime(fileDescriptor.getCreateDate());
    int year = cal.get(Calendar.YEAR);
    int month = cal.get(Calendar.MONTH) + 1;
    int day = cal.get(Calendar.DAY_OF_MONTH);

    return new File(rootDir, year + "/"
        + StringUtils.leftPad(String.valueOf(month), 2, '0') + "/"
        + StringUtils.leftPad(String.valueOf(day), 2, '0'));
  }

  public static String getFileName(FileDescriptor fileDescriptor) {
    return fileDescriptor.getId().toString() + "." + fileDescriptor.getExtension();
  }

  @PreDestroy
  protected void stopWriteExecutor() {
    writeExecutor.shutdown();
  }
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。

相關文章

  • 解決SpringMVC獲取請求參數亂碼問題

    解決SpringMVC獲取請求參數亂碼問題

    在使用SpringMVC和thymeleaf進行請求參數處理時,可能會遇到亂碼問題,對于GET方法亂碼,可通過修改Tomcat的server.xml文件,添加URIEncoding="UTF-8"解決,而POST方法亂碼,則需在web.xml配置SpringMVC提供的過濾器
    2024-11-11
  • obix協議在java中的配置和使用詳解

    obix協議在java中的配置和使用詳解

    這篇文章主要給大家介紹了關于obix協議在java中的配置和使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-08-08
  • SpringBoot中的6種API請求參數讀取方式總結

    SpringBoot中的6種API請求參數讀取方式總結

    使用Spring Boot開發(fā)API的時候,讀取請求參數是服務端編碼中最基本的一項操作,Spring Boot中也提供了多種機制來滿足不同的API設計要求,通過本文,為大家總結6種常用的請求參數讀取方式,需要的朋友可以參考下
    2024-07-07
  • 基于OpenCv與JVM實現加載保存圖像功能(JAVA?圖像處理)

    基于OpenCv與JVM實現加載保存圖像功能(JAVA?圖像處理)

    openCv有一個名imread的簡單函數,用于從文件中讀取圖像,本文給大家介紹JAVA?圖像處理基于OpenCv與JVM實現加載保存圖像功能,感興趣的朋友一起看看吧
    2022-01-01
  • Spring MVC攔截器的基本使用方法

    Spring MVC攔截器的基本使用方法

    這篇文章主要給大家介紹了關于Spring MVC攔截器的基本使用方法,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Spring MVC具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-07-07
  • Java詳細講解Math和Random類中有哪些常用方法

    Java詳細講解Math和Random類中有哪些常用方法

    Math類位于java.lang包中,包含很多用于科學計算的類方法,這些方法可以直接通過類名調用。Random類獲取隨機數,位于java.util包中,本篇帶你了解它們的常用方法
    2022-05-05
  • Java內存模型之重排序的相關知識總結

    Java內存模型之重排序的相關知識總結

    重排序是指編譯器和處理器為了優(yōu)化性能而對指令序列進行重新排序的一種手段,文中詳細介紹了Java重排序的相關知識,需要的朋友可以參考下
    2021-06-06
  • Java中多個線程交替循環(huán)執(zhí)行的實現

    Java中多個線程交替循環(huán)執(zhí)行的實現

    有些時候面試官經常會問,兩個線程怎么交替執(zhí)行呀,本文就來詳細的介紹一下Java中多個線程交替循環(huán)執(zhí)行的實現,文中通過示例代碼介紹的非常詳細,需要的朋友們下面隨著小編來一起學習學習吧
    2024-01-01
  • 最詳細的Java循環(huán)結構解析之for循環(huán)教程(適合小白)

    最詳細的Java循環(huán)結構解析之for循環(huán)教程(適合小白)

    :循環(huán)結構是指在程序中需要反復執(zhí)行某個功能而設置的一種程序結構,下面這篇文章主要給大家介紹了關于Java循環(huán)結構解析之for循環(huán)的相關資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2021-09-09
  • 關于Hibernate的一些學習心得總結

    關于Hibernate的一些學習心得總結

    Hibernate是一個優(yōu)秀的Java 持久化層解決方案,是當今主流的對象—關系映射(ORM)工具
    2013-07-07

最新評論

延寿县| 昭通市| 轮台县| 崇明县| 娄底市| 兴业县| 凤凰县| 华容县| 固始县| 铜鼓县| 桓台县| 灵寿县| 东城区| 拉孜县| 潍坊市| 穆棱市| 广宗县| 务川| 边坝县| 天柱县| 汶川县| 林甸县| 宝山区| 渝中区| 雷州市| 望都县| 钟山县| 佛教| 漳平市| 平陆县| 隆子县| 视频| 滨海县| 德钦县| 正定县| 金寨县| 德令哈市| 米易县| 海晏县| 涟水县| 云南省|