概述
分布式文件系统
-
分布式文件系统(Distributed File System)是一个软件/软件服务器 此软件可以用来管理在多个服务器节点中的文件(这些服务器节点通过网络相连并构成一个庞大的文件存储服务器集群 即这些服务器节点都是用来存储文件资源的 且用dfs来管理这些文件)
-
传统文件系统与分布式文件系统的对比
-
传统文件系统的缺点
- 若用户数量多 则io操作会很频繁 则对磁盘的访问压力会较大
- 若磁盘故障 则可能会造成数据的丢失
- 一个磁盘的存储容量有限
FastDFS
-
fastdfs是一个开源的轻量级分布式文件系统 由c语言开发
-
fastdfs对文件进行管理的功能有存储、同步、访问(上传、下载、删除)等
-
fastdfs有冗余备份、线性扩容等机制 高可用、高性能 且解决了较大文件的存储问题 特别适合应用于如相册网站、文档网站、图片网站、视频网站等以文件为载体的在线服务的网站
-
架构
- 客户端
- 即使用java去连接/操作fastdfs的代码
- 服务端
- 跟踪器(tracker)
- 负责调度且在内存中记录集群中storage的状态信息 是客户端与storage的中间枢纽
- 因为信息都保存在内存中 因此性能高 一般的 一个较大的集群有3台tracker就够了
- 存储节点(storage)
- 负责存储文件与文件属性等信息到服务器磁盘中 文件的存储、同步、访问都由storage来完成
- 跟踪器(tracker)
- 客户端
在linux-minimal上安装fastdfs
-
linux-mini与linux的区别
-
linux-mini没有图形界面 但占用磁盘资源小 且公司里一般使用的都是linux-mini
-
由于linux-mini较linux来说缺少一些常用的工具库 因此推荐先安装下面的工具库 否则使用起来可能会不太方便
#net-tools为使用ifconfig命令等的工具库yum install git lrzsz wget vim unzip net-tools -y
-
#先安装第三方库(gcc编译器、libevent库) 否则配置/编译时可能会报错yum install gcc libevent libevent-devel -y#从github中下载(若显示连不上github则需要自己手动下载 手动下载后用tar -zxvf命令解压缩)、编译且安装libfastcommon库#libfastcommon库是从fastdfs中分离出来的c语言公用函数库git clone https://github.com/happyfish100/libfastcommon.git --depth 1cd libfastcommon./make.sh./make.sh install#从github中下载、编译且安装libserverframe库#注意 若不安装libserverframe库则在编译fastdfs时会出现错误:../common/fdfs_global.h:15:26: fatal error: sf/sf_global.h: No such file or directorygit clone https://github.com/happyfish100/libserverframe.git --depth 1cd libserverframe./make.sh./make.sh install#从github中下载、编译且安装fastdfsgit clone https://github.com/happyfish100/fastdfs.git --depth 1cd fastdfs./make.sh./make.sh install#fastdfs的编译出来的文件在/usr/bin目录下(以fdfs开头)#fastdfs的配置文件在/etc/fdfs目录下#复制fastdfs的conf目录下的两个文件到/etc/fdfs目录下 否则实际应用时可能会出现奇奇怪怪的问题cp http.conf /etc/fdfscp mime.types /etc/fdfs#备份配置文件cd /etc/fdfscp client.conf client.conf.samplecp storage.conf storage.conf.samplecp storage_ids.conf storage_ids.conf.samplecp tracker.conf tracker.conf.sample#修改tracker.conf文件#base_path为存储tracker的数据与日志文件的目录路径base_path = /opt/fastdfs/tracker#修改storage.conf文件#base_path为存储storage的数据与日志文件的目录路径base_path = /opt/fastdfs/storage#store_path为存储真正文件的目录 可以写多个 结尾为0、1、..的数字 若写多个 则要改store_path_countstore_path0 = /opt/fastdfs/storage/files#store_path1 = /home/yuqing/fastdfs1store_path_count = 1#tracker_server表示将此storage注册到哪个tracker下tracker_server = 192.168.190.131:22122#测试时使用一个tracker即可 剩余的要么注释掉要么删除掉#tracker_server = 192.168.209.122:22122#创建上述目录mkdir -p /opt/fastdfs/trackermkdir -p /opt/fastdfs/storage/files#启动fastdfs#启动tracker(在任意目录下)fdfs_trackerd /etc/fdfs/tracker.conf#启动storage(在任意目录下)#首次启动storage后会在$store_path$/data目录下新建256^2个存储文件的目录fdfs_storaged /etc/fdfs/storage.conf#查看storage是否已经注册到了tracker下fdfs_monitor /etc/fdfs/storage.conf#若有此信息说明注册成功tracker server is 192.168.190.131:22122#重启trackerfdfs_trackerd /etc/fdfs/tracker.conf restart#重启storagefdfs_storaged /etc/fdfs/storage.conf restart#关闭trackerfdfs_trackerd /etc/fdfs/tracker.conf stop#关闭storagefdfs_storaged /etc/fdfs/storage.conf stop#或kill命令关闭#但不建议使用kill -9命令强制关闭 因为可能会产生文件信息不同步的问题
本地上传本地访问
#启动/重启fastdfsfdfs_trackerd /etc/fdfs/tracker.conf (restart)fdfs_storaged /etc/fdfs/storage.conf (restart)#修改client.conf文件以测试文件上传#base_path为存储client的日志文件的目录路径base_path = /opt/fastdfs/client#tracker_server表示将此client注册到哪个tracker下tracker_server = 192.168.190.131:22122#创建上述目录mkdir -p /opt/fastdfs/client#测试文件上传fdfs_test /etc/fdfs/client.conf upload /opt/fastdfs-6.09.tar.gz-----------------------------------------------------------------------------------#tracker查询到有一个storage注册到它的名下tracker_query_storage_store_list_without_group: server 1. group_name=, ip_addr=192.168.190.131, port=23000group_name=group1, ip_addr=192.168.190.131, port=23000#此为上传的文件的信息且fastdfs会对上传的文件进行重新命名storage_upload_by_filenamegroup_name=group1, remote_filename=M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gzsource ip address: 192.168.190.131file timestamp=2022-10-11 10:52:15file size=800112file crc32=3103841170#/group1为组名(非cluster下默认只有一个组group1)#/M00为linux的虚拟磁盘名#/00/00为目录名#/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz为文件名example file url: http://192.168.190.131/group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz#此为上传的文件的从文件的信息#一般的 上传的文件只需要存一份主文件即可#在存放图片时需要存放它的大图与小图时可以存放从文件storage_upload_slave_by_filenamegroup_name=group1, remote_filename=M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gzsource ip address: 192.168.190.131file timestamp=2022-10-11 10:52:15file size=800112file crc32=3103841170example file url: http://192.168.190.131/group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz-----------------------------------------------------------------------------------#查看上传的文件情况cd /opt/fastdfs/storage/files/data/00/00ll#此为从文件wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz#此为从文件的属性信息(m为meta)wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz-m#此为主文件wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz#此为主文件的属性信息(m为meta)wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz-m#删除测试文件#删除主文件及其属性信息fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz#删除从文件及其属性信息fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz
本地上传远程访问
#通过nginx访问已经上传到fastdfs中的文件#从github中下载fastdfs-nginx模块#注意 在nginx的安装过程中才能配置fastdfs-nginx模块 因此得重新安装一遍nginxgit clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1#下载并解压nginxwget https://nginx.org/download/nginx-1.22.0.tar.gztar -zxvf nginx-1.22.0.tar.gz#先安装第三方库(gcc编译器、openssl库、pcre库、zlib库) 否则配置/编译nginx时可能会报错yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel -y#配置nginx的安装路径以及要添加的模块的源代码路径cd nginx-1.22.0./configure --prefix=/opt/nginx --add-module=/opt/fastdfs-nginx-module/src#编译且安装nginxmakemake install#拷贝文件 否则可能不能正常启动nginxcp /opt/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs#修改mod_fastdfs.conf文件#base_path为存储fastdfs-nginx模块的日志文件的目录路径base_path=/opt/fastdfs/fastdfs-nginx#tracker_server表示将此fastdfs-nginx模块注册到哪个tracker下tracker_server=192.168.190.131:22122#若url中带有组名则设为true 默认为falseurl_have_group_name = true#store_path为storage存储真正文件的目录 可以写多个 若写多个 则要改store_path_countstore_path0=/opt/fastdfs/storage/files#store_path1=/home/yuqing/fastdfs1store_path_count=1#创建上述目录mkdir -p /opt/fastdfs/fastdfs-nginx#配置nginx#表示拦截此请求路径并用fastdfs的nginx模块进行转发#ngx_fastdfs_module:此指令非nginx提供 而是由fastdfs-nginx模块提供的 而nginx根据此指令会找到mod_fastdfs.conf文件 进而找到tracker与storagelocation ~ /group[1-9]/M0[0-9] {ngx_fastdfs_module;}#启动nginx./nginx -c /opt/nginx/conf/nginx.conf#启动/重启fastdfsfdfs_trackerd /etc/fdfs/tracker.conf (restart)fdfs_storaged /etc/fdfs/storage.conf (restart)#测试文件上传cp /opt/fastdfs-6.09/conf/http.conf /opt/a.txtfdfs_test /etc/fdfs/client.conf upload /opt/a.txt#访问http://192.168.190.131/group1/M00/00/00/wKi-g2NFIHaAE1jiAAADxfUPwyI976.txt
远程上传远程/本地访问
-
即使用java代码来连接与操作fastdfs并在浏览器中访问fastdfs
-
先在github上下载fastdfs-client-java-master压缩包(此压缩包实则为java代码) 解压后将此压缩包打成jar包并放到maven仓库中
#进入源码包中打开cmd并输入maven命令(../fastdfs-client-java-master>)mvn clean install
fastdfs-java
- 使用maven项目即可
添加依赖
org.csource fastdfs-client-java 1.29-SNAPSHOT
拷贝源码包的fdfs_client.conf文件到resources目录中并修改
tracker_server = 192.168.190.131:22122
编写文件上传、下载、删除的代码
public class FastDFS { public static void main(String[] args) { fileUpload(); } public static void fileUpload() { try { //获取StorageClient对象 StorageClient sc = getStorageClient(); //local_filename为需要上传的文件的绝对路径 //file_ext_name为需要上传的文件的扩展名 //meta_list为需要上传的文件的属性信息 通常为null 即不用上传 //返回值为String[] strings[0]为组名(如group1) strings[1]为远程文件名(如M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png) //此返回值很重要 建议存入数据库 String[] result = sc.upload_file("D:/001.png", "png", null); for (String s : result) { System.out.println(s); } } catch (IOException | MyException e) { e.printStackTrace(); } } public static void fileDownload() { try { //获取StorageClient对象 StorageClient sc = getStorageClient(); //group_name为需要下载的文件的组名 //remote_filename为需要下载的文件的远程文件名 //local_filename为需要下载的文件保存到哪个位置的绝对路径名 //返回值为int 若为0则表示下载成功 其它值都表示下载失败 int result = sc.download_file("group1", "M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png", "D:/002.png"); System.out.println(result); } catch (IOException | MyException e) { e.printStackTrace(); } } public static void fileDelete() { try { //获取StorageClient对象 StorageClient sc = getStorageClient(); //group_name为需要删除的文件的组名 //remote_filename为需要删除的文件的远程文件名 //返回值为int 若为0则表示删除成功 其它值都表示删除失败 int result = sc.delete_file("group1", "M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png"); System.out.println(result); } catch (IOException | MyException e) { e.printStackTrace(); } } public static StorageClient getStorageClient() { StorageClient sc = null; try { //读取fastdfs的配置文件以将所有的tracker_server地址读取到内存中 //默认从classpath中读取 ClientGlobal.init("fdfs_client.conf"); //创建TrackerClient对象以获取TrackerServer对象与StorageServer对象 TrackerClient tc = new TrackerClient(); TrackerServer ts = tc.getTrackerServer(); StorageServer ss = tc.getStoreStorage(ts); //通过TrackerServer对象与StorageServer对象来获取StorageClient对象 //使用StorageClient对象以实现对文件的操作 sc = new StorageClient(ts, ss); } catch (IOException | MyException e) { e.printStackTrace(); } return sc; }}
启动nginx、fastdfs以进行测试
#永久关闭防火墙systemctl stop firewalldsystemctl disable firewalld#启动nginx./nginx -c /opt/nginx/conf/nginx.conf#启动fastdfsfdfs_trackerd /etc/fdfs/tracker.conffdfs_storaged /etc/fdfs/storage.conf#访问http://192.168.190.131/group1/M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png或查看fastdfs的存储文件的目录
fastdfs-web
- 使用springboot项目
配置pom
添加依赖
org.springframework.boot spring-boot-starter-thymeleaf org.springframework.boot spring-boot-starter-web org.mybatis.spring.boot mybatis-spring-boot-starter 2.2.2 mysql mysql-connector-java runtime org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test org.csource fastdfs-client-java 1.29-SNAPSHOT
配置build
org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok org.mybatis.generator mybatis-generator-maven-plugin 1.4.1 GeneratorMapper.xml true true src/main/java ***.xml false src/main/resources ** public static String[] fileUpload(byte[] file_buff, String file_ext_name, NameValuePair[] meta_list) { try { //获取StorageClient对象 StorageClient sc = getStorageClient(); //file_buff为需要上传的文件的字节数组 //file_ext_name为需要上传的文件的扩展名 //meta_list为需要上传的文件的属性信息 通常为null 即不用上传 //返回值为String[] strings[0]为组名(如group1) strings[1]为远程文件名(如M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png) //此返回值很重要 建议存入数据库 String[] result = sc.upload_file(file_buff, file_ext_name, meta_list); return result; } catch (IOException | MyException e) { e.printStackTrace(); } return null; } public static byte[] fileDownload(String group_name, String remote_filename) { try { //获取StorageClient对象 StorageClient sc = getStorageClient(); //group_name为需要下载的文件的组名 //remote_filename为需要下载的文件的远程文件名 //返回值为int 若为0则表示下载成功 其它值都表示下载失败 byte[] result = sc.download_file(group_name, remote_filename); return result; } catch (IOException | MyException e) { e.printStackTrace(); } return null; } public static Integer fileDelete(String group_name, String remote_filename) { try { //获取StorageClient对象 StorageClient sc = getStorageClient(); //group_name为需要删除的文件的组名 //remote_filename为需要删除的文件的远程文件名 //返回值为int 若为0则表示删除成功 其它值都表示删除失败 int result = sc.delete_file(group_name, remote_filename); return result; } catch (IOException | MyException e) { e.printStackTrace(); } return null; } public static StorageClient getStorageClient() { StorageClient sc = null; try { //读取fastdfs的配置文件以将所有的tracker_server地址读取到内存中 //默认从classpath中读取 ClientGlobal.init("fdfs_client.conf"); //创建TrackerClient对象以获取TrackerServer对象与StorageServer对象 TrackerClient tc = new TrackerClient(); TrackerServer ts = tc.getTrackerServer(); StorageServer ss = tc.getStoreStorage(ts); //通过TrackerServer对象与StorageServer对象来获取StorageClient对象 //使用StorageClient对象以实现对文件的操作 sc = new StorageClient(ts, ss); } catch (IOException | MyException e) { e.printStackTrace(); } return sc; }}
在resources下生成fdfs_client.conf文件
connect_timeout = 2network_timeout = 30charset = UTF-8http.tracker_http_port = 8080http.anti_steal_token = nohttp.secret_key = FastDFS1234567890tracker_server = 192.168.190.131:22122connection_pool.enabled = trueconnection_pool.max_count_per_entry = 500connection_pool.max_idle_time = 3600connection_pool.max_wait_time_in_ms = 1000
创建controller
@Controllerpublic class UserController { @Resource private UserService userService; @GetMapping("/") public String selectAll(Model model) { List list = userService.selectAll(); model.addAttribute("list", list); return "index"; } @GetMapping("/toUpload/{id}") public String toUpload(Model model, @PathVariable Integer id) { User user = userService.selectById(id); model.addAttribute("user", user); return "upload"; } //MultipartFile为spring提供的一个接口 专门用来获取文件的数据 //注意 MultipartFile的参数名必须与表单中的文件的name属性保持一致 否则获取不到MultipartFile @PostMapping("/upload") public String upload(Model model, Integer id, MultipartFile myFile) { try { System.out.println(myFile.getOriginalFilename()); //myFile.getName()获取的是表单中的文件的name属性 System.out.println(myFile.getName()); System.out.println(myFile.getContentType()); System.out.println(myFile.getSize()); System.out.println(myFile.isEmpty()); byte[] file_buff = myFile.getBytes(); String filename = myFile.getOriginalFilename(); //注意 有些文件是没有扩展名的 因此此处并不能这样写 而要做逻辑控制 但此处为测试 因此不做处理 String file_ext_name = filename.substring(filename.lastIndexOf(".") + 1); String[] result = FastDFSUtil.fileUpload(file_buff, file_ext_name, null); User user = new User(); user.setId(id); user.setFilename(myFile.getOriginalFilename()); user.setFilesize(myFile.getSize()); user.setGroupname(result[0]); user.setRemotefilepath(result[1]); int ret = userService.updateUser(user); if (ret == 1) { model.addAttribute("message", "文件上传成功,点击 确定 返回主页面!"); } else { model.addAttribute("message", "文件上传失败,点击 确定 返回主页面!"); } model.addAttribute("url", "/"); } catch (IOException e) { e.printStackTrace(); } return "result"; } //ResponseEntity为spring提供的一个类 @GetMapping("/download/{id}") public ResponseEntity download(@PathVariable Integer id) { User user = userService.selectById(id); byte[] result = FastDFSUtil.fileDownload(user.getGroupname(), user.getRemotefilepath()); //创建响应头对象以设置其属性 HttpHeaders httpHeaders = new HttpHeaders(); //设置响应头的类型为流类型 httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); //设置响应头的文件大小 用来提供下载器的属性(如下载速度)显示 httpHeaders.setContentLength(user.getFilesize()); //设置下载文件时的文件名为user.getFilename() 也可以使用时间戳+扩展名的方式 httpHeaders.setContentDispositionFormData("attachment", //处理下载的文件的文件名的中文乱码问题 new String(user.getFilename().getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1)); //创建响应体对象 //body为响应数据 此数据可以为html代码/js代码/字符串/一个文件的流/.. //headers为响应头的信息 //status为响应后想要显示的状态码 ResponseEntity responseEntity = new ResponseEntity<>(result, httpHeaders, HttpStatus.OK); return responseEntity; } @GetMapping("/delete/{id}") public String delete(Model model, @PathVariable Integer id) { User user = userService.selectById(id); //此处应添加事务控制 但此处为测试 因此不做处理 int ret = userService.deleteUserById(id); Integer result = FastDFSUtil.fileDelete(user.getGroupname(), user.getRemotefilepath()); if (result == 0 && ret == 1) { model.addAttribute("message", "文件删除成功,点击 确定 返回主页面!"); } else { model.addAttribute("message", "文件删除失败,点击 确定 返回主页面!"); } model.addAttribute("url", "/"); return "result"; }}
在templates下创建对应的页面
index
upload
result result
确定
测试
fastdfs-cluster
-
架构图
环境搭建
安装7个linux-minimal
安装fastdfs与nginx
#先安装linux-minimal缺少的但常用的工具库yum install git lrzsz wget vim unzip net-tools -y#再安装fastdfs与nginx所需要的第三方库 否则配置/编译时可能会报错yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel libevent libevent-devel -y#下载、编译且安装libfastcommon库git clone https://github.com/happyfish100/libfastcommon.git --depth 1cd /opt/libfastcommon-1.0.62./make.sh./make.sh install#下载、编译且安装libserverframe库git clone https://github.com/happyfish100/libserverframe.git --depth 1cd /opt/libserverframe-1.1.21./make.sh./make.sh install#从github中下载、编译且安装fastdfs、nginx、fastdfs-nginx模块#下载、编译且安装fastdfsgit clone https://github.com/happyfish100/fastdfs.git --depth 1cd /opt/fastdfs-6.09./make.sh./make.sh install#下载并解压nginxwget https://nginx.org/download/nginx-1.22.0.tar.gztar -zxvf nginx-1.22.0.tar.gz#下载fastdfs-nginx模块git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1#配置nginx的安装路径以及要添加的模块的源代码路径cd /opt/nginx-1.22.0#对tracker与入口即192.168.190.131的nginx的配置./configure --prefix=/opt/nginx#对storage的配置./configure --prefix=/opt/nginx --add-module=/opt/fastdfs-nginx-module/src#编译且安装nginxmakemake install
修改配置文件
#先拷贝/备份文件cp /opt/fastdfs-6.09/conf/http.conf /etc/fdfscp /opt/fastdfs-6.09/conf/mime.types /etc/fdfscd /etc/fdfscp client.conf client.conf.samplecp storage.conf storage.conf.samplecp storage_ids.conf storage_ids.conf.samplecp tracker.conf tracker.conf.sample#tracker不需要 storage才需要cp /opt/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs#修改tracker.conf文件base_path = /opt/fastdfs/tracker#修改fastdfs的负载均衡策略#0为轮询组 1为指定组(若为1 则还要配置store_group来指定哪个组) 2为选择剩余空间最大的组(默认值)store_lookup=0#创建上述目录mkdir -p /opt/fastdfs/tracker#修改storage.conf文件#X修改成具体的值group_name=groupXbase_path = /opt/fastdfs/storagestore_path0 = /opt/fastdfs/storage/filestracker_server = 192.168.190.132:22122tracker_server = 192.168.190.133:22122#创建上述目录mkdir -p /opt/fastdfs/storage/files#修改mod_fastdfs.conf文件#tracker不需要 storage才需要base_path=/opt/fastdfs/fastdfs-nginxtracker_server=192.168.190.132:22122tracker_server=192.168.190.133:22122#X修改成具体的值group_name=groupXurl_have_group_name = truestore_path0=/opt/fastdfs/storage/filesgroup_count=2#在末尾添加[group1]group_name=group1storage_server_port=23000store_path_count=1store_path0=/opt/fastdfs/storage/files[group2]group_name=group2storage_server_port=23000store_path_count=1store_path0=/opt/fastdfs/storage/files#创建上述目录mkdir -p /opt/fastdfs/fastdfs-nginx
配置nginx
#对tracker的配置location ~ /group[1-9]/M0[0-9] {proxy_pass http://fastdfs_server;}upstream fastdfs_server {server 192.168.190.134:80;server 192.168.190.135:80;server 192.168.190.136:80;server 192.168.190.137:80;}#对storage的配置location ~ /group[1-9]/M0[0-9] {ngx_fastdfs_module;}#对入口的配置location ~ /group[1-9]/M0[0-9] {proxy_pass http://fastdfs_server;}upstream fastdfs_server {server 192.168.190.132:80;server 192.168.190.133:80;}
启动fastdfs与nginx
#永久关闭防火墙systemctl stop firewalldsystemctl disable firewalld#启动fastdfs#对trackerfdfs_trackerd /etc/fdfs/tracker.conf#对storagefdfs_storaged /etc/fdfs/storage.conf#启动nginxcd /opt/nginx/sbin./nginx -c /opt/nginx/conf/nginx.conf -t./nginx -c /opt/nginx/conf/nginx.conf
测试文件上传、下载、删除
- 使用之前的java程序测试文件上传、下载、删除操作
- 为了保证高可用 通常会在入口nginx处再添加一个备用的nginx 并使用keepalive(通常由运维人员使用 作用为当主nginx出现故障后会自动切换到备用nginx)连接两者
来源地址:https://blog.csdn.net/dddddd_hdysj/article/details/127298755