docker安装部署、fastDFS文件服务器搭建与springboot项目接口
一、docker安装部署
1、更新yum包:sudo yum update 2、安装需要的软件包,yum-util 提供yum-config-manager功能,另外两个是devicemapper驱动依赖的 sudo yum install -y yum-utils device-mapper-persistent-data lvm2 3、设置yum源:sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo 4、可以查看所有仓库中所有docker版本,并选择特定版本安装:yum list docker-ce --showduplicates | sort -r 5、安装docker:yum install docker-ce-18.03.0.ce 6、启动、设置开启开机启动 sudo systemctl start docker sudo systemctl enable docker 7、验证安装是否成功(有client和service两部分表示docker安装启动都成功了):docker version 8、查看docker启动状态:systemctl status docker(启动成功active(running))
二、fastDFS文件服务器搭建
fastdfs 安装 1、拉取镜像: docker pull morunchang/fastdfs 2、启动tracker: docker run -d --name tracker --net=host morunchang/fastdfs sh tracker.sh 3、启动storage (172.21.91.218 ip 自行替换为docker 所在服务器的ip )( 此镜像不支持-p 参数) docker run -d --name storage --net=host -e TRACKER_IP=172.21.91.218:22122 -e GROUP_NAME=group1 morunchang/fastdfs sh storage.sh 可选配置 storage 内部nginx 端口修改 以22999为例 1.进入容器内部: docker exec -it storage /bin/bash 2.修改nginx配置文件: vim /etc/nginx/conf/nginx.conf 修改 http.server.listen 8080 为 22999 sed -i 's/8080/22999/g' /etc/nginx/conf/nginx.conf 3.退出容器 exit 4.重启storage docker restart storage //浏览器访问路径 http://172.21.91.218:22999/group1/M00/00/00/rBVb2lwPNYeAZtTLAAAXxD4H4Z8674.txt 相关端口开放 firewall-cmd --zone=public --add-port=22122/tcp --permanent firewall-cmd --zone=public --add-port=23000/tcp --permanent firewall-cmd --zone=public --add-port=8080/tcp --permanent firewall-cmd --reload
三、java springboot项目相关接口
1、引入依赖
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.27.2</version>
</dependency>
2、controller接口 package com.lihe.mes.identity.controller; import com.github.tobato.fastdfs.domain.fdfs.MetaData; import com.github.tobato.fastdfs.domain.fdfs.StorePath; import com.github.tobato.fastdfs.domain.fdfs.ThumbImageConfig; import com.github.tobato.fastdfs.domain.proto.storage.DownloadByteArray; import com.github.tobato.fastdfs.service.FastFileStorageClient; import com.lihe.mes.base.model.Result; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import io.swagger.annotations.ApiParam; import lombok.extern.slf4j.Slf4j; import org.apache.commons.io.FilenameUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.OutputStream; import java.util.*; /** * 文件服务器上传下载 controller */ @Api(value = "文件服务器上传下载", tags = "文件服务器上传下载") @RequestMapping("/file") @RestController @Slf4j public class FileServerController { /** 文件服务器 客户端 */ @Autowired private FastFileStorageClient storageClient; /** 缩略图 配置 */ @Autowired private ThumbImageConfig thumbImageConfig; /** 图片后缀集合 */ private static final Set<String> IMAGE_PREFIX_SET = new HashSet<>(Arrays.asList("JPG", "JPEG", "PNG", "GIF", "BMP", "WBMP")); /** 文件名称 */ private static final String META_DATA_NAME_FILE_NAME = "FILE_NAME"; /** * 上传 * @param file 文件 * @return 文件路径 * @throws IOException 异常 */ @ApiOperation(value = "上传", notes = "上传") @PostMapping("/upload") public Result<String> upload(MultipartFile file) throws IOException { Map<String, String> result = uploadFile(file); return Result.of("上传成功!", result.get("uri")); } /** * 上传并返回文件路径和文件名 * @param file 文件 * @return 文件信息 * @throws IOException 异常 */ private Map<String, String> uploadFile(MultipartFile file) throws IOException { String fileName = file.getOriginalFilename(); String filePrefix = FilenameUtils.getExtension(fileName); StorePath storePath; if (IMAGE_PREFIX_SET.contains(filePrefix.toUpperCase())) { // 图片上传并且生成缩略图 storePath = this.storageClient.uploadImageAndCrtThumbImage(file.getInputStream(), file.getSize(), filePrefix, Collections.singleton(new MetaData(META_DATA_NAME_FILE_NAME, fileName))); } else { // 普通文件上传 storePath = this.storageClient.uploadFile(file.getInputStream(), file.getSize(), filePrefix, Collections.singleton(new MetaData(META_DATA_NAME_FILE_NAME, fileName))); } Map<String, String> result = new HashMap<>(); result.put("uri", storePath.getFullPath()); result.put("name", fileName); return result; } /** * 上传并返回文件路径和文件名 * @param file 文件 * @return 文件路径 * @throws IOException 异常 */ @ApiOperation(value = "上传并返回文件路径和文件名", notes = "上传并返回文件路径和文件名") @PostMapping("/upload/info") public Result<Map<String, String>> uploadAndInfo(MultipartFile file) throws IOException { Map<String, String> result = uploadFile(file); return Result.of("上传成功!", result); } /** * 获取缩略图路径 * @param fullPath 文件路径 * @return 缩略图路径 */ @ApiOperation(value = "缩略图路径", notes = "缩略图路径") @GetMapping("/thumbImagePath") public Result<String> getThumbImagePath(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath) { StorePath storePath = StorePath.parseFromUrl(fullPath); return Result.of(thumbImageConfig.getThumbImagePath(storePath.getFullPath())); } /** * 下载 * @param fullPath 文件路径 * @param response 请求响应 * @throws IOException 异常 */ @ApiOperation(value = "下载", notes = "下载") @GetMapping(value = "/download", produces = MediaType.APPLICATION_OCTET_STREAM_VALUE) public void download(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath, HttpServletResponse response) throws IOException { StorePath storePath = StorePath.parseFromUrl(fullPath); Set<MetaData> metaDataSet = storageClient.getMetadata(storePath.getGroup(), storePath.getPath()); String fileName = metaDataSet.stream().findFirst() .filter(metaData -> META_DATA_NAME_FILE_NAME.equals(metaData.getName())) .map(MetaData::getValue) .orElse(FilenameUtils.getName(fullPath)); byte[] bytes = storageClient.downloadFile(storePath.getGroup(), storePath.getPath(), new DownloadByteArray()); response.reset(); response.setContentType("multipart/form-data;charset=UTF-8;"); fileName = new String(fileName.getBytes("gb2312"), "ISO8859-1"); response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); try (OutputStream outputStream = response.getOutputStream()) { outputStream.write(bytes); } } /** * 删除 * @param fullPath 文件路径 */ @ApiOperation(value = "删除", notes = "删除") @DeleteMapping("/delete") public void delete(@ApiParam(value = "文件路径", required = true) @RequestParam String fullPath) { storageClient.deleteFile(fullPath); } }
四、yml文件配置
#文件服务器 fdfs: so-timeout: 1501 connect-timeout: 601 thumb-image: # 缩略图 width: 200 height: 200 tracker-list: # tracker地址 - 文件服务器ip:22122
五、图片地址
http://文件服务器ip:22999/group1/M00/00/00/rBGFRF8MIM6AELWcAA2pJsnuHLk149.png 端口号后为上传返回路径
做人如果没有梦想,那根咸鱼有什么区别!!!