电商项目--分布式文件存储FastDFS搭建

        一、FastDFS环境搭建

我们使用Docker搭建FastDFS的开发环境

(1)拉取镜像

docker pull morunchang/fastdfs

(2)运行tracker

docker run -d --name tracker --net=host morunchang/fastdfs sh tracker.sh

(3)运行storage

docker run -d --name storage --net=host -e TRACKER_IP=<your tracker server address>:22122 -e GROUP_NAME=<group name> morunchang/fastdfs sh storage.sh
  • 使用的网络模式是–net=host, 替换为机器的Ip即可
  • 是组名,即storage的组
  • 如果想要增加新的storage服务器,再次运行该命令,注意更换 新组名

(4)修改nginx的配置

进入storage的容器内部,修改nginx.conf

docker exec -it storage  /bin/bash

进入后

vi /data/nginx/conf/nginx.conf

添加以下内容

location /group1/M00 {proxy_next_upstream http_502 http_504 error timeout invalid_header;proxy_cache http-cache;proxy_cache_valid  200 304 12h;proxy_cache_key $uri$is_args$args;proxy_pass http://fdfs_group1;expires 30d;}

(5)退出容器

exit

(6)重启storage容器

docker restart storage

二、搭建文件存储微服务

创建文件管理微服务shangcheng_service_file,该工程主要用于实现文件上传以及文件删除等功能。

步骤一:修改pom.xml,引入依赖

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>net.oschina.zcx7878</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27.0.0</version></dependency><dependency><groupId>com.changgou</groupId><artifactId>changgou_common</artifactId><version>1.0-SNAPSHOT</version></dependency>
</dependencies>

步骤二:在resources文件夹下创建fasfDFS的配置文件fdfs_client.conf

connect_timeout = 60
network_timeout = 60
charset = UTF-8
http.tracker_http_port = 8080
tracker_server = 192.168.200.128:22122

connect_timeout:连接超时时间,单位为秒。

network_timeout:通信超时时间,单位为秒。发送或接收数据时。假设在超时时间后还不能发送或接收数据,则本次网络通信失败

charset: 字符集

http.tracker_http_port :.tracker的http端口

tracker_server: tracker服务器IP和端口设置

步骤三:在resources文件夹下创建application.yml

spring:servlet:multipart:max-file-size: 10MBmax-request-size: 10MB
server:port: 9008
eureka:client:service-url:defaultZone: http://127.0.0.1:6868/eurekainstance:prefer-ip-address: true
feign:hystrix:enabled: true

max-file-size是单个文件大小,max-request-size是设置总上传的数据大小

步骤四:创建com.changgou.file包,创建启动类FileApplication

@SpringBootApplication
@EnableEurekaClient
public class FileApplication {
​public static void main(String[] args) {SpringApplication.run(FileApplication.class);}
}

        三、实现文件上传

(1)文件信息封装:

        文件上传一般都有文件的名字、文件的内容、文件的扩展名、文件的md5值、文件的作者等相关属性,我们可以创建一个对象封装这些属性,代码如下:

创建com.shangcheng.file.pojo.FastDFSFile

public class FastDFSFile {//文件名字private String name;//文件内容private byte[] content;//文件扩展名private String ext;//文件MD5摘要值private String md5;//文件创建作者private String author;
​public FastDFSFile(String name, byte[] content, String ext, String height,String width, String author) {super();this.name = name;this.content = content;this.ext = ext;this.author = author;}
​public FastDFSFile(String name, byte[] content, String ext) {super();this.name = name;this.content = content;this.ext = ext;}
​// getter and setter ...
}

(2)文件操作:

        创建FastDFSClient类,放在com.shangcheng.file.util下在该类中实现FastDFS信息获取以及文件的相关操作,

代码如下:

public class FastDFSClient {private static org.slf4j.Logger logger = LoggerFactory.getLogger(FastDFSClient.class);
​/**** 初始化加载FastDFS的TrackerServer配置*/static {try {String filePath = new ClassPathResource("fdfs_client.conf").getFile().getAbsolutePath();ClientGlobal.init(filePath);} catch (Exception e) {logger.error("FastDFS Client Init Fail!",e);}}
​/**** 文件上传* @param file* @return*/public static String[] upload(FastDFSFile file) {//获取文件的作者NameValuePair[] meta_list = new NameValuePair[1];meta_list[0] = new NameValuePair("author", file.getAuthor());
​//接收返回数据String[] uploadResults = null;StorageClient storageClient=null;try {//创建StorageClient客户端对象storageClient = getTrackerClient();
​/**** 文件上传* 1)文件字节数组* 2)文件扩展名* 3)文件作者*/uploadResults = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);} catch (Exception e) {logger.error("Exception when uploadind the file:" + file.getName(), e);}
​if (uploadResults == null && storageClient!=null) {logger.error("upload file fail, error code:" + storageClient.getErrorCode());}//获取组名String groupName = uploadResults[0];//获取文件存储路径String remoteFileName = uploadResults[1];return uploadResults;}
​/**** 获取文件信息* @param groupName:组名* @param remoteFileName:文件存储完整名* @return*/public static FileInfo getFile(String groupName, String remoteFileName) {try {StorageClient storageClient = getTrackerClient();return storageClient.get_file_info(groupName, remoteFileName);} catch (Exception e) {logger.error("Exception: Get File from Fast DFS failed", e);}return null;}
​/**** 文件下载* @param groupName* @param remoteFileName* @return*/public static InputStream downFile(String groupName, String remoteFileName) {try {//创建StorageClientStorageClient storageClient = getTrackerClient();
​//下载文件byte[] fileByte = storageClient.download_file(groupName, remoteFileName);InputStream ins = new ByteArrayInputStream(fileByte);return ins;} catch (Exception e) {logger.error("Exception: Get File from Fast DFS failed", e);}return null;}
​/**** 文件删除* @param groupName* @param remoteFileName* @throws Exception*/public static void deleteFile(String groupName, String remoteFileName)throws Exception {//创建StorageClientStorageClient storageClient = getTrackerClient();
​//删除文件int i = storageClient.delete_file(groupName, remoteFileName);}
​/**** 获取Storage组* @param groupName* @return* @throws IOException*/public static StorageServer[] getStoreStorages(String groupName)throws IOException {//创建TrackerClientTrackerClient trackerClient = new TrackerClient();//获取TrackerServerTrackerServer trackerServer = trackerClient.getConnection();//获取Storage组return trackerClient.getStoreStorages(trackerServer, groupName);}
​/**** 获取Storage信息,IP和端口* @param groupName* @param remoteFileName* @return* @throws IOException*/public static ServerInfo[] getFetchStorages(String groupName,String remoteFileName) throws IOException {TrackerClient trackerClient = new TrackerClient();TrackerServer trackerServer = trackerClient.getConnection();return trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);}
​/**** 获取Tracker服务地址* @return* @throws IOException*/public static String getTrackerUrl() throws IOException {return "http://"+getTrackerServer().getInetSocketAddress().getHostString()+":"+ClientGlobal.getG_tracker_http_port()+"/";}
​/**** 获取Storage客户端* @return* @throws IOException*/private static StorageClient getTrackerClient() throws IOException {TrackerServer trackerServer = getTrackerServer();StorageClient storageClient = new StorageClient(trackerServer, null);return  storageClient;}
​/**** 获取Tracker* @return* @throws IOException*/private static TrackerServer getTrackerServer() throws IOException {TrackerClient trackerClient = new TrackerClient();TrackerServer trackerServer = trackerClient.getConnection();return  trackerServer;}
}

(3)文件上传:

        创建一个FileController,在该控制器中实现文件上传操作,代码如下:

@RestController
@RequestMapping("/file")
public class FileController {
​@PostMapping("/upload")public Result uploadFile(MultipartFile file){try{//判断文件是否存在if (file == null){throw new RuntimeException("文件不存在");}//获取文件的完整名称String originalFilename = file.getOriginalFilename();if (StringUtils.isEmpty(originalFilename)){throw new RuntimeException("文件不存在");}
​//获取文件的扩展名称  abc.jpg   jpgString extName = originalFilename.substring(originalFilename.lastIndexOf(".") + 1);
​//获取文件内容byte[] content = file.getBytes();
​//创建文件上传的封装实体类FastDFSFile fastDFSFile = new FastDFSFile(originalFilename,content,extName);
​//基于工具类进行文件上传,并接受返回参数  String[]String[] uploadResult = FastDFSClient.upload(fastDFSFile);
​//封装返回结果String url = FastDFSClient.getTrackerUrl()+uploadResult[0]+"/"+uploadResult[1];return new Result(true,StatusCode.OK,"文件上传成功",url);}catch (Exception e){e.printStackTrace();}return new Result(false, StatusCode.ERROR,"文件上传失败");}
}

四、使用Postman测试文件上传

 使用Postman测试文件上传 步骤:

1、选择post请求方式,输入请求地址 http://localhost:9008/upload

2、填写Headers

Key:Content-Type
Value:multipart/form-data

3、填写body

选择form-data 然后选择文件file 点击添加文件,最后发送即可。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/62550.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

代理IP与百度在信息时代的交互

目录 一、代理IP的基本概念和工作原理 二、代理IP在百度搜索中的多重作用 解决网络延时问题&#xff0c;提高搜索速度 提高网络安全 隐藏用户的真实IP地址&#xff0c;保护个人隐私 突破访问限制&#xff0c;拓宽网络视野 三、代理IP在百度关键词排名优化中的应用 模拟…

(十一)Python3 接口自动化测试,Pytest-Allure报告的使用

(十一)Python3 接口自动化测试,Pytest-Allure报告的使用 1、安装和使用 1、安装pytest和allure-pytest插件: pip install pytest allure-pytest 2、在你的pytest测试用例中使用allure装饰器或者上下文管理器来生成报告。 例如,你可以使用@allure.feature装饰器来标记特性…

JavaScript中类数组对象及其与数组的关系

JavaScript中类数组对象及其与数组的关系 1. 什么是类数组对象&#xff1f; 类数组对象是指那些具有 length 属性且可以通过非负整数索引访问元素的对象。虽然这些对象看起来像数组&#xff0c;但它们并不具备真正数组的所有特性&#xff0c;例如没有继承 Array.prototype 上…

2024“蜀道山” RE 部分题解

Map_maze 题目描述 真真假假真真,你能够寻找到最后的终点吗? 附件下载 迷宫生成 v5 是一个长度为 105 的数组&#xff0c;被用作 15x15 的二维网格 int __cdecl sub_4010D0(_DWORD *a1, _DWORD *a2) {_DWORD *v2; // eax_DWORD *v3; // eaxint result; // eax_DWORD v5[1…

水库大坝安全监测之量水堰计应用

量水堰计是水库大坝安全监测系统中的一种关键设备&#xff0c;主要用于测量水库水位、流量等水力参数。以下是量水堰计在水库大坝安全监测中的应用及注意事项&#xff1a; 一、量水堰计的工作原理 量水堰计是一种专门用于测量水流流量的仪器&#xff0c;其工作原理主要基于水流…

基于 LlamaFactory 的 LoRA 微调模型支持 vllm 批量推理的实现

背景 LlamaFactory 的 LoRA 微调功能非常便捷&#xff0c;微调后的模型&#xff0c;没有直接支持 vllm 推理&#xff0c;故导致推理速度不够快。 LlamaFactory 目前支持通过 VLLM API 进行部署&#xff0c;调用 API 时的响应速度&#xff0c;仍然没有vllm批量推理的速度快。 …

MySQL 8.0与PostgreSQL 15.8的性能对比

以下是MySQL 8.0与PostgreSQL 15.8的性能对比&#xff1a; MySQL 8.0性能特点&#xff1a; MySQL在处理大量读操作时表现出色&#xff0c;其存储引擎InnoDB提供了行级锁定和高效的事务处理&#xff0c;适用于并发读取的场景。MySQL通过查询缓存来提高读取性能&#xff0c;查询缓…

vue基础之3:模板语法、数据绑定

欢迎来到“雪碧聊技术”CSDN博客&#xff01; 在这里&#xff0c;您将踏入一个专注于Java开发技术的知识殿堂。无论您是Java编程的初学者&#xff0c;还是具有一定经验的开发者&#xff0c;相信我的博客都能为您提供宝贵的学习资源和实用技巧。作为您的技术向导&#xff0c;我将…

【动态规划】股票市场交易策略优化

文章目录 一、问题描述二、解决思路状态转移初始化最终结果 三、代码实现执行流程解析时间和空间复杂度 一、问题描述 我们要解决的是一个关于股票买卖的问题&#xff1a;给定一个股票价格数组 stocks&#xff0c;每一天的价格为数组中的一个元素。我们可以通过买入和卖出的操…

SVL-Adapter: Self-Supervised Adapter for Vision-Language Pretrained Models

当前的问题 CLIP和CLIP-Adapter等方法的一个主要局限性是&#xff0c;它们没有对视觉编码器所编码的底层表示进行显著的修改。原因很简单&#xff1a;微调大型模型需要大量的监督&#xff0c;这在低监督学习设置中是很难获得的。如果下游分类任务的图像来自与互联网常见图像相…

Rust SQLx CLI 同步迁移数据库

上文我们介绍了SQLx及SQLite&#xff0c;并介绍了如何使用代码同步迁移数据库。本文介绍Sqlx cli 命令行工具&#xff0c;介绍如何安装、使用&#xff0c;利用其提供的命令实现数据表同步迁移。Java生态中有flyway, sqlx cli 功能类似&#xff0c;利用命令行工具可以和其他语言…

丹摩|丹摩智算平台使用教学指南

本指南旨在为新用户提供一个详细的操作步骤和实用的入门指导&#xff0c;帮助大家快速上手丹摩智算平台。 一、平台简介 丹摩智算平台是一款强大的数据分析和计算平台&#xff0c;支持多种编程语言&#xff0c;提供丰富的数据处理和机器学习工具。无论您是数据分析师、开发者…

代码美学:MATLAB制作渐变色

输入颜色个数n&#xff0c;颜色类型&#xff1a; n 2; % 输入颜色个数 colors {[1, 0, 0], [0, 0, 1]}; createGradientHeatmap(n, colors); 调用函数&#xff1a; function createGradientHeatmap(n, colors)% 输入检查if length(colors) ~ nerror(输入的颜色数量与n不一…

【大数据学习 | Spark调优篇】常用的shuffle优化

shuffle是一个涉及到CPU&#xff08;序列化反序列化&#xff09;、网络IO&#xff08;跨节点数据传输&#xff09;以及磁盘IO&#xff08;shuffle中间结果落盘&#xff09;的操作。 优化思路&#xff1a; 减少shuffle的数据量&#xff0c;减少shuffle的次数。 具体方式&…

Spring中每次访问数据库都要创建SqlSession吗?

一、SqlSession是什么二、源码分析1&#xff09;mybatis获取Mapper流程2&#xff09;Spring创建Mapper接口的代理对象流程3&#xff09;MapperFactoryBean#getObject调用时机4&#xff09;SqlSessionTemplate创建流程5&#xff09;SqlSessionInterceptor拦截逻辑6&#xff09;开…

【Leetcode 每日一题 - 补卡】3259. 超级饮料的最大强化能量

问题背景 来自未来的体育科学家给你两个整数数组 e n e r g y D r i n k A energyDrinkA energyDrinkA 和 e n e r g y D r i n k B energyDrinkB energyDrinkB&#xff0c;数组长度都等于 n n n。这两个数组分别代表 A A A、 B B B 两种不同能量饮料每小时所能提供的强化…

SOC(网络安全管理平台)

SOC平台&#xff0c;网络安全管理平台。 提供集中、统一、可视化的安全信息管理&#xff0c;通过实时采集各种安全信息&#xff0c;动态进行安全信息关联分析与风险评估&#xff0c;实现安全事件的快速跟踪、定位和应急响应。 从监控、审计、风险和运维四个维度建立起来的一套…

自动化电气行业的优势和劣势是什么

优势 市场需求广泛&#xff1a; 自动化电气技术广泛应用于电力系统、制造业、交通、农业等多个领域&#xff0c;随着智能化、数字化趋势的加强&#xff0c;其市场需求持续增长。在智能制造、智能电网等领域&#xff0c;自动化电气技术更是发挥着关键作用&#xff0c;推动了行业…

3.10 内核 BUG_ON() at xfs_vm_writepage() -> page_buffers()

目录 前言 问题分析 page buffers创建 page buffers丢失 Write-Protect Dirty Page w/o Buffers 问题解决 前言 这个问题发生在3.10.0-514.el7上&#xff0c;并且在RHEL的知识库中快速找到了对应的案例以及解决方案&#xff0c;但是&#xff0c;理解问题如何发生和解决…

娱乐API:快速生成藏头诗、藏尾诗和藏中诗

引言 诗歌是中国传统文化的重要组成部分&#xff0c;其中藏头诗、藏尾诗和藏中诗因其独特的形式而备受喜爱。为了满足广大文学爱好者的需求&#xff0c;我们推出了一款娱乐API&#xff0c;支持快速生成藏头诗、藏尾诗和藏中诗。本文将详细介绍该API的功能、使用方法以及如何将…