FastDFS是什么?
FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
FastDFS怎么使用 ?
首先打开虚拟机
第一种方式
第一步 拖入jar包
前置工作下载安装包
# 到 https://github.com/happyfish100 下载 fastdfs-master 、 libfastcommon-master 、fastdfs-nginx-module-master# 到 http://nginx.org/en/download.html 下载 nginx-1.14.2.tar.gz
2.前置安装运行库**
yum install -y unzip zip perl gcc-c ++yum -y install zlib zlib-devel openssl openssl--devel pcre pcre-devel
3.安装FastDFS
# 安装 libfastcommon-master.zipcd /opt /FastDFS
unzip -o libfastcommon-master.zip -d /usr/localcd /usr/local/libfastcommon-master/./make.sh./make.sh install# 安装 fastdfscd /opt /FastDFSunzip -o fastdfs-master.zip -d /usr/localcd /usr/local/fastdfs-master/./make.sh./make.sh install# 拷贝配置文件# 将 fastdfs 安装目录下的 conf 下的文件拷贝到 /etc/fdfs/ 下cd /usr/local/fastdfs-master/cp -r conf/* /etc/fdfs/#出现 conf?一直回车# 配置启动 trackerdcd /etc/fdfs/++++++++++++++++++++++++++# 修改 vi tracker.confvim tracker.confbase_path = /home/yuqing/fastdfs 改 成 base_path = /data/fastdfs++++++++++++++++++++++++++:wqmkdir -p /data/fastdfs#启动trackerd/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart# 查看启动情况ps -ef | grep tracker# 配置并启动 storagedcd /etc/fdfs/++++++++++++++++++++++++++# 修改 vi storage.confvim storage.confbase_path = /home/yuqing/fastdfs 改为 : base_path = /data/fastdfsstore_path0 = /home/yuqing/fastdfs 改为 : store_path0 = /data/fastdfs/storage#有2个tracker_server 注释一个tracker_server = 192 .168.209.121:22122 改为 :tracker_server = 192 .168.42.200:22122 ,这个 ip 改成自己的++++++++++++++++++++++++++:wqmkdir -p /data/fastdfs/storage # 创建数据日志存储目录#启动storage/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart# 查看启动情况ps -ef | grep storage#一定要启动!!
4.ideal 编写代码测试
#1 pom导包
<!-- https://mvnrepository.com/artifact/net.oschina.zcx7878/fastdfs-client-java --><dependency><groupId> net.oschina.zcx7878 </groupId><artifactId> fastdfs-client-java </artifactId><version> 1.27.0.0 </version></dependency>
#2 在resource下配置fastdfs.conftracker_server=192.168.64.138:22122

#3 编写测试类
@SpringBootTest public class myTestpic { @Resource private TccheckService tccheckService; @Test public void cc() throws Exception{ ClientGlobal.init("fastdfs.conf"); TrackerClient tc = new TrackerClient(); TrackerServer server = tc.getConnection(); StorageServer stserver = null; StorageClient stclient = new StorageClient(server, stserver); String[] jpgs = stclient.upload_file("d:/aa/13.gif", "jpg", null); for (String jp:jpgs) { System.out.println(jp); } System.out.println("upload finish!"); }}
图片上传成功!!!安装Nignx 查看图片
5 安装Nignx
# 先安装 fastdfs-nginx-module-mastecd /opt/FastDFS/unzip -o fastdfs-nginx-module-master.zip -d /usr/localcd /usr/local/fastdfs-nginx-module-master/srccp mod_fastdfs.conf /etc/fdfs/cd /etc/fdfs/# 编辑 vi mod_fastdfs.confvim mod_fastdfs.confbase_path = /tmp 改成 : base_path = /data/fastdfs#192.168.42.200填写自己的ip地址tracker_server = tracker:22122 改成 : tracker_server = 192 .168.42.200:22122#可以分成多个组名 存放图片url_have_group_name = false 改成: url_have_group_name = true ; #url 中包含 group 名称store_path0 = /home/yuqing/fastdfs 改成 : store_path0 = /data/fastdfs/storage#nginxcd /opt/FastDFS#解压文件tar -zxf nginx-1.14.2.tar.gz#移动到soft目录下mv nginx-1.14.2 /opt/soft/nginxcd nginx-1.14.2#下面要小心多出个空格在module-后./configure --prefix = /usr/local/nginx --add-module = /usr/local/fastdfs-nginx-module-master/srcmakemake installcd /usr/local/nginx/sbin/#查看nginx版本./nginx -V# 编辑 vi nginx.confvim nginx.confcd /usr/local/nginx/conf===========================================#添加以下红字内容events {use epoll;worker_connections 1024 ;}http {server {listen 80;server_name 192.168.42.200;location /group1/M00/{ngx_fastdfs_module;}}server {listen 8888;server_name 192.168.42.200;location / {root html;index index.html index.htm;}}}===========================================# 启动 nginxcd /usr/local/nginx/sbin/./nginx -c /usr/local/nginx/conf/nginx.conf# 最后浏览器访问地址 查看效果#后面的地址是你idea测试上传后的地址 nginx默认端口80http://192.168.64.138/group1/M00/00/00/wKhAimLZK2yABU5GAABRh_-wc7A040.jpg
第二种方式 springboot整合fdfs
1.导入pom依赖
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.4</version>
</dependency>
</dependencies>
2.配置yml
server: port: 9999 fdfs: #读取时间 so-timeout: 3000 #连接超时时间 connect-timeout: 1000 #缩略图 thumb-image: width: 150 height: 150 #服务器地址 tracker-list: - 192.168.64.138:22122
3.编写配置类FastDFSConfiguration
@Configuration
@Import(FdfsClientConfig.class)
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)//可以不写
public class FastDFSConfiguration {
}
4.编写测试类 启动
@SpringBootTest class MyfastdfsApplicationTests { @Resource private FastFileStorageClient ffsc; @Test void contextLoads() throws Exception{ //读取图片 FileInputStream fis = new FileInputStream("d:/a.jpeg"); //进行图片上传 StorePath sp = ffsc.uploadFile(fis, fis.available(), "jpeg", null); //打印访问后的地址 System.out.println(sp.getFullPath()); } }
# 最后浏览器访问地址 查看效果#后面的地址是你idea测试上传后的地址 nginx默认端口80http://192.168.64.138/group1/M00/00/00/wKhAimLZK2yABU5GAABRh_-wc7A040.jpg
第三种方式 springboot整合fdfs进入项目整合(和第二种差不多)
1.导入pom依赖
<properties> <mysql.version>5.1.38</mysql.version> <mybatis-plus.version>3.4.2</mybatis-plus.version> <druid.version>1.1.9</druid.version> <easyexcel.version>3.0.5</easyexcel.version> <fastdss.verson>1.26.4</fastdss.verson> <fastjson.version>1.2.83</fastjson.version> <swagger.version>2.9.2</swagger.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.version}</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/easyexcel --> <dependency> <groupId>com.alibaba</groupId> <artifactId>easyexcel</artifactId> <version>${easyexcel.version}</version> </dependency> <dependency> <groupId>net.oschina.zcx7878</groupId> <artifactId>fastdfs-client-java</artifactId> <version>1.27.0.0</version> </dependency> <dependency> <groupId>com.github.tobato</groupId> <artifactId>fastdfs-client</artifactId> <version>${fastdss.verson}</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.1</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>${fastjson.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>${swagger.version}</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>${swagger.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-websocket</artifactId> </dependency> </dependencies>
2.配置yml
server:
port: 9090
spring:
application:
name: tc_manager
cloud:
nacos:
discovery:
server-addr: 192.168.64.138:8848
username: nacos
password: nacos
namespace: public
datasource:
druid:
url: jdbc:mysql://192.168.64.138:3306/tc_towercrane?useSSL=false&serverTimezone=Asia/Shanghai&characterEncoding=utf-8&autoReconnect=true
username: root
password: 3090_Cmok
#初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
initial-size: 3
max-active: 30
min-idle: 3
# datasource:
# # druid连接池
# type: com.alibaba.druid.pool.DruidDataSource
# #数据库驱动
# driver: com.mysql.jdbc.Driver
# #最大连接池数量
# max-active: 20
# #初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
# initial-size: 10
# 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,
# 并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
max-wait: 60000
#最小连接池数量
#有两个含义:
#1: Destroy线程会检测连接的间隔时间
#2: testWhileIdle的判断依据,详细看testWhileIdle属性的说明
time-between-eviction-runs-millis: 60000
#配置一个连接在池中最小生存的时间,单位是毫秒
min-evictable-idle-time-millis: 180000
#用来检测连接是否有效的sql,要求是一个查询语句。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会其作用。
validation-query: select 'x'
#连接有效性检查的超时时间 1 秒
validation-query-timeout: 1
#申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
test-on-borrow: false
#设置从连接池获取连接时是否检查连接有效性,true时,如果连接空闲时间超过minEvictableIdleTimeMillis进行检查,否则不检查;false时,不检查
test-while-idle: true
#归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
test-on-return: false
#是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
pool-prepared-statements: true
#要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,
# 不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
max-open-prepared-statements: 20
#数据库链接超过3分钟开始关闭空闲连接 秒为单位
remove-abandoned-timeout: 1800
#对于长时间不使用的连接强制关闭
remove-abandoned: true
#打开后,增强timeBetweenEvictionRunsMillis的周期性连接检查,minIdle内的空闲连接,
# 每次检查强制验证连接有效性. 参考:https://github.com/alibaba/druid/wiki/KeepAlive_cn
keep-alive: true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
#是否超时关闭连接 默认为false ,若为true 就算数据库恢复连接,也无法连接上
break-after-acquire-failure: false
#设置获取连接出错时的自动重连次数
connection-error-retry-attempts: 1
# 设置获取连接出错时是否马上返回错误,true为马上返回
fail-fast: true
#属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:
#监控统计用的filter:stat日志用的filter:log4j防御sql注入的filter:wall
filters: stat,wall
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
#注意顶格
fdfs:
#连接时间
so-timeout: 3000
#超时时间
connect-timeout: 1000
#缩略图
thumb-image:
width: 200
height: 200
#服务地址
tracker-list:
- 192.168.64.138:22122
3.编写配置类 MyBatisConfiguration
@Configuration
@Import(FdfsClientConfig.class)//注册fastdfs服务器工具类
public class MyBatisConfiguration {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor(){
MybatisPlusInterceptor plugs = new MybatisPlusInterceptor();
plugs.addInnerInterceptor(new PaginationInnerInterceptor());
return plugs;
}
}
4.配置controller层 实体类
@Api() @RestController @RequestMapping("/tcinfo") public class TcinfosCtrl { @Resource private TcinfoStoreService tcinfoStoreService;/** * 8 吊塔附件上传 功能 * @param tap * @param file * @return */ @PostMapping("/uploadTcAppendix") //因为上传会有2种协议 前端不能同时发送 所以实体类用string来接 public String uploadAppendix(@RequestParam("tap") String tap,@RequestParam("file") MultipartFile file){ //在把获取的string 转为实体类 TcAppendix tcap = JSON.parseObject(tap, TcAppendix.class); String filename = tcinfoStoreService.uploadAppenddix(tcap, file); return filename; }}
#实体类TcAppendix
@Data @AllArgsConstructor @NoArgsConstructor @Builder public class TcAppendix { @TableId(type = IdType.AUTO) private Long penid; private Long tcid; @JsonFormat(pattern="yyyy-MM-dd") @DateTimeFormat("yyyy-MM-dd") private Date pendate; private String penphoto; private String pentype; }
答案就在上面分成2个@RequestParam!!!
5.配置service接口 实现类
//接口 public interface TcinfoStoreService { /** * 用户上传图片到图片服务器 并返回图片服务器返回的base64图片地址 * @param file * @return */ String uploadAppenddix(TcAppendix tcAppendix,MultipartFile file);//实现类
@Service public class TcinfoStoreServiceImpl implements TcinfoStoreService { @Resource private FastFileStorageClient ffsc; @Resource private TcappendixMapper tcappendixMapper; @Override public String uploadAppenddix(TcAppendix tap, MultipartFile file) { //FilenameUtils.getExtension 工具获取文件尾名 StorePath sp = null; try { //第一步先把上传的文件 上传给fastdfs服务器 InputStream is = file.getInputStream(); //第一个参数是流 第二个是大小 第三个是文件后缀 sp = ffsc.uploadFile(is, is.available(), FilenameUtils.getExtension(file.getOriginalFilename()), null); //第二步 再把fastdfs返回的base64图片名填充到tap对象中 tap.setPenphoto(sp.getFullPath()); //第三步 再把对象存放到数据库 tcappendixMapper.insert(tap); } catch (IOException e) { e.printStackTrace(); } return sp.getFullPath(); } }
6.mapper层
@Mapper //实现mybatis-plus 接口实现CRUD public interface TcappendixMapper extends BaseMapper<TcAppendix> { }