Java负载均衡服务器实现上传文件同步
负载服务器Z,应用服务器A和B,从A上传的附件,如何在B上下载下来?
这个问题我的解决思路如下(后来被一个装逼的面试官给批评了这种做法,不过我瞧不起他)
服务器A、B上传附件的时候,将这个附件备份到服务器Z,当A、B下载文件的时候,首先会在自己服务器的目录下寻找,如果找不到,就会从服务器Z上下载一份到当前服务器。
服务器之间的文件备份通过sftp,参考:https://www.nhooo.com/article/196008.htm(下文中的SftpCustom类就是这个链接里的“SFTP上传下载文件例子”中的类)
这里主要介绍一下重写上传、下载的方法时应该添加的代码
上传文件,异步操作
newThread(()->{ SftpCustomfu=newSftpCustom(); fu.upload(file.getAbsolutePath(),getFileName(fileDescr)); fu.closeChannel(); }).start();
下载文件,先从当前服务器寻找
StringtmpPath=roots[0].getPath()+'/'+getFileName(fileDescr); Filefile2=newFile(tmpPath); if(file2.exists()){ returnFileUtils.openInputStream(file2); } SftpCustomfu=newSftpCustom(); fu.download(getFileName(fileDescr),tmpPath); file2=newFile(tmpPath); inputStream=FileUtils.openInputStream(file2); fu.closeChannel(); returninputStream;
cuba框架中重写上传文件类FileStorage.java的代码如下:
packagecom.haulmont.cuba.core.app.custom; importcom.google.common.util.concurrent.ThreadFactoryBuilder; importcom.haulmont.cuba.core.app.FileStorageAPI; importcom.haulmont.cuba.core.app.ServerConfig; importcom.haulmont.cuba.core.entity.FileDescriptor; importcom.haulmont.cuba.core.global.*; importcom.haulmont.cuba.core.sys.AppContext; importcom.haulmont.cuba.core.sys.SecurityContext; importorg.apache.commons.io.FileUtils; importorg.apache.commons.io.IOUtils; importorg.apache.commons.lang.StringUtils; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importjavax.annotation.PostConstruct; importjavax.annotation.PreDestroy; importjavax.inject.Inject; importjava.io.*; importjava.nio.charset.StandardCharsets; importjava.text.SimpleDateFormat; importjava.util.ArrayList; importjava.util.Calendar; importjava.util.List; importjava.util.concurrent.ExecutorService; importjava.util.concurrent.Executors; importstaticcom.haulmont.bali.util.Preconditions.checkNotNullArgument; publicclassFileStorageimplementsFileStorageAPI{ privatefinalLoggerlog=LoggerFactory.getLogger(FileStorage.class); @Inject protectedUserSessionSourceuserSessionSource; @Inject protectedTimeSourcetimeSource; @Inject protectedConfigurationconfiguration; protectedbooleanisImmutableFileStorage; protectedExecutorServicewriteExecutor=Executors.newFixedThreadPool(5, newThreadFactoryBuilder().setNameFormat("FileStorageWriter-%d").build()); protectedvolatileFile[]storageRoots; @PostConstruct publicvoidinit(){ this.isImmutableFileStorage=configuration.getConfig(ServerConfig.class).getImmutableFileStorage(); } /** *INTERNAL.Don'tuseinapplicationcode. */ publicFile[]getStorageRoots(){ if(storageRoots==null){ Stringconf=configuration.getConfig(ServerConfig.class).getFileStorageDir(); if(StringUtils.isBlank(conf)){ StringdataDir=configuration.getConfig(GlobalConfig.class).getDataDir(); Filedir=newFile(dataDir,"filestorage"); dir.mkdirs(); storageRoots=newFile[]{dir}; }else{ Listlist=newArrayList<>(); for(Stringstr:conf.split(",")){ str=str.trim(); if(!StringUtils.isEmpty(str)){ Filefile=newFile(str); if(!list.contains(file)) list.add(file); } } storageRoots=list.toArray(newFile[list.size()]); } } returnstorageRoots; } @Override publiclongsaveStream(finalFileDescriptorfileDescr,finalInputStreaminputStream)throwsFileStorageException{ checkFileDescriptor(fileDescr); File[]roots=getStorageRoots(); //Storetoprimarystorage checkStorageDefined(roots,fileDescr); checkPrimaryStorageAccessible(roots,fileDescr); Filedir=getStorageDir(roots[0],fileDescr); dir.mkdirs(); checkDirectoryExists(dir); finalFilefile=newFile(dir,getFileName(fileDescr)); checkFileExists(file); longsize=0; OutputStreamos=null; try{ os=FileUtils.openOutputStream(file); size=IOUtils.copyLarge(inputStream,os); os.flush(); writeLog(file,false); newThread(()->{ SftpCustomfu=newSftpCustom(); fu.upload(file.getAbsolutePath(),getFileName(fileDescr)); fu.closeChannel(); }).start(); }catch(IOExceptione){ IOUtils.closeQuietly(os); FileUtils.deleteQuietly(file); thrownewFileStorageException(FileStorageException.Type.IO_EXCEPTION,file.getAbsolutePath(),e); }finally{ IOUtils.closeQuietly(os); } //Copyfiletosecondarystoragesasynchronously finalSecurityContextsecurityContext=AppContext.getSecurityContext(); for(inti=1;i 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。