赞
踩
启动tracker: docker run -d --name=tracker -v /root/data/fdfs/tracker:/data/fast_data --privileged=true --net=host morunchang/fastdfs sh tracker.sh
启动storage: docker run -d --name=storage -v /root/data/fdfs/storageData:/data/fast_data --privileged=true --net=host -e TRACKER_IP=192.168.15.133:22122 -e GROUP_NAME=group1 morunchang/fastdfs sh storage.sh
pom引入包
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.5</version>
</dependency>
<!--引入包之后boot项目会有自动提示-->
fdfs:
connect-timeout: 601
so-timeout: 1501
tracker-list[0]: 192.168.15.133:22122
/** * @author : LiuMingyao * @date : 2019/8/22 14:38 * @description : TODO */ @Api("fastDfs测试接口") @RestController public class TestDfsController { //tobato的包会自动注入spring.yml中关于dfs的配置,简单使用只需要注入FastFileStorageClient即可 //连接池和tracker可以自行选择是否需要注入使用 @Autowired private FastFileStorageClient storageClient; //自选 @Autowired private TrackerClient trackerClient; @Autowired protected FdfsConnectionPool pool; @ApiOperation("图片文件上传测试") @ApiImplicitParams({@ApiImplicitParam(name = "localPath", value = "本地需要上传的文件路径", required = true, paramType = "query", dataType = "String")}) @GetMapping("/liuUpload") public String liuUpload(String localPath) throws Exception { File file = new File(localPath); Set<MetaData> metaDataSet = new HashSet<>(); metaDataSet.add(new MetaData("Author", "Author")); metaDataSet.add(new MetaData("date", "当前时间")); FileInputStream inputStream = new FileInputStream(file); FastImageFile fastImageFile = new FastImageFile(inputStream, file.length(), "png", metaDataSet); StorePath storePath = storageClient.uploadImage(fastImageFile); return storePath.getFullPath(); } @ApiOperation("图片文件下载测试") @ApiImplicitParams({@ApiImplicitParam(name = "groupName", value = "需要下载的文件所属组", required = true, paramType = "query", dataType = "String") , @ApiImplicitParam(name = "path", value = "需要下载的文件path", required = true, paramType = "query", dataType = "String")}) @GetMapping("/liuDownload")//group1/M00/00/00/wKgPhV1eTUuAYfcmAAARSoVDk74492.png public String liuDownload(String groupName, String path) throws Exception { Object o = storageClient.downloadFile(groupName, path, new DownloadCallback<Object>() { @Override public Object recv(InputStream inputStream) throws IOException { System.out.println("接受到文件"); byte[] bytes = inputStream.readAllBytes(); FileImageOutputStream outputStream=new FileImageOutputStream(new File("d:/aaa.png")); outputStream.write(bytes); return "d:/aaa.png"; } }); return o.toString(); } @ApiOperation("文件上传测试") @ApiImplicitParams({ }) @PostMapping("/upload") public String uploadFile(@RequestParam("file") MultipartFile file) throws IOException { Set<MetaData> metaDataSet = new HashSet<>(); metaDataSet.add(new MetaData("a", "b")); metaDataSet.add(new MetaData("date", "时间")); StorePath path = storageClient.uploadFile(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), metaDataSet); return path.getFullPath(); } @ApiOperation("缩略图") @PostMapping("img") public String uploadImageAndCrtThumbImage(@RequestParam("file") MultipartFile file) throws IOException { Set<MetaData> metaDataSet = new HashSet<>(); metaDataSet.add(new MetaData("a", "b")); metaDataSet.add(new MetaData("date", "时间")); StorePath path = storageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), FilenameUtils.getExtension(file.getOriginalFilename()), metaDataSet); return path.getFullPath(); } }
注意:需要使用swagger测试的需要导入swagger的包:
<!--api测试包--> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.6.1</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.6.1</version> </dependency> 还要自行配置swagger: @Configuration @EnableSwagger2 public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.basePackage("com.example.study")) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("Spring Boot中使用Swagger2构建RESTful APIs") .description("我的CSDN:https://mp.csdn.net/postedit/95599118") .termsOfServiceUrl("GitHub:https://github.com/MrLawrenc") .contact("指是弹琴") .version("1.0") .build(); } }
fdfs:
connect-timeout: 601
so-timeout: 1501
tracker-list[0]: 192.168.15.133:22122
# tracker-list[1]: 192.168.15.132:22122
thumb-image: # 缩略图
width: 60
height: 60
# 连接池配置
pool:
#从池中借出的对象的最大数目
max-total: 5
#获取连接时的最大等待毫秒数100
max-wait-millis: 2000
jmx-name-prefix: liumingyao
@Autowired private FastFileStorageClient storageClient; //在controller里面注入池对象 @Autowired protected FdfsConnectionPool pool; @ApiOperation("300m的文件上传压力测试") @GetMapping("/pullTest") public void testPoll() throws Exception { File file = new File("d:/aaa.png"); final AtomicInteger failCount = new AtomicInteger(0); final AtomicInteger count = new AtomicInteger(0); int totalCount = 20; ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(5); executor.afterPropertiesSet(); log.info("pool.getMaxTotal()" + pool.getMaxTotal()); log.info("pool.getMaxWaitMillis()" + pool.getMaxWaitMillis()); for (int i = 0; i < totalCount; i++) { executor.execute(() -> { try { byte[] bytes = FileUtils.readFileToByteArray(new File("e:/ggg.7z"));//300m+ log.info("活动连接{}", pool.getNumActive()); log.info("空闲连接{}", pool.getNumIdle()); log.info("连接获取总数统计{}", pool.getBorrowedCount()); log.info("连接返回总数统计{}", pool.getReturnedCount()); log.info("连接销毁总数统计{}", pool.getDestroyedCount()); //第一个是参数group StorePath storePath = storageClient.uploadFile(null, new ByteArrayInputStream(bytes), bytes.length, "7z"); log.info("{} storePath {}", Thread.currentThread().getName(), storePath); } catch (Exception e) { e.printStackTrace(); failCount.incrementAndGet(); } finally { count.incrementAndGet(); } }); } //等待线程执行完主线程再放行销毁连接池 while (count.get() < totalCount) { try { Thread.sleep(100); } catch (InterruptedException e) { return; } } executor.destroy(); log.info("total count: {}", count.get()); log.info("fail count: {}", failCount.get());
进入http://localhost/swagger-ui.htm(端口自行配置的)访问该请求,观察日志输出,可以看见连接获取各种的情况。
注意:如果出现从报错->从池中获取对象异常失败,可以适当增大等待时间或是增大连接池对象的数量。
@Autowired private TrackerClient trackerClient; Tracker对象有如下方法: StorageNode getStoreStorage(); StorageNode getStoreStorage(String var1); StorageNodeInfo getFetchStorage(String var1, String var2); StorageNodeInfo getUpdateStorage(String var1, String var2); List<GroupState> listGroups(); List<StorageState> listStorages(String var1); List<StorageState> listStorages(String var1, String var2); void deleteStorage(String var1, String var2); 池对象设置值: @Autowired protected FdfsConnectionPool pool; pool.setMaxTotal(100);
更多方法参见github原作者的单元测试: 原作者的github
出现报错情况可以自行看看,其实作者封装的fastDFS大部分代码都能看懂,而且单元测试基本涵盖了大部分用法
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。