在项目开发中,文件存储是绕不开的环节。目前流行的解决方案包括OSS、MinIO 等。最近有开发者反馈,MinIO的控制台屏蔽了不少原有功能。今天为大家介绍一款新近开源、功能强大的分布式文件系统——RustFS,它不仅兼容S3协议,还自带完善的可视化管理控制台。
简介
RustFS是一个基于 Rust 语言开发的高性能分布式对象存储软件,开源不到一个月便在GitHub上收获了 6k+star。它与MinIO类似,具备使用简单、完全兼容AWS S3协议、开源等优点,并采用更为宽松的Apache 2.0开源协议。
RustFS的主要特性如下:
- 高性能:基于Rust构建,拥有出色的性能与响应速度。
- 分布式架构:采用可扩展且容错的设计,适合大规模部署。
- AWS S3 兼容性:可使用标准的AWS S3 SDK进行管理操作。
- 数据湖支持:针对大数据和AI工作负载进行了优化。
- 开源:采用Apache 2.0许可证,鼓励社区贡献。
- 用户友好:自带功能丰富的可视化管理控制台,易于操作。
下面是RustFS管理控制台的界面效果图,可以看到其功能相当完善。

安装
使用Docker安装RustFS是最便捷的方式。
docker pull rustfs/rustfs
- 镜像下载完成后,运行以下命令启动RustFS容器:
docker run -p 9000:9000 --name rustfs \
-e RUSTFS_ACCESS_KEY=rustfsadmin \
-e RUSTFS_SECRET_KEY=rustfsadmin \
-v /mydata/rustfs/data:/data \
-v /etc/localtime:/etc/localtime \
-d rustfs/rustfs
- 容器启动成功后,即可访问RustFS的管理控制台。默认的访问地址为
http://你的服务器IP:9000,初始账号密码均为 rustfsadmin。

控制台使用
RustFS的控制台界面设计直观,接下来我们看看其主要功能。
- 在左侧菜单选择
文件浏览器,点击右上角的 创建存储桶 按钮即可创建新的存储桶。

- 点击存储桶列表操作栏的
配置 按钮,可以对该存储桶进行详细设置,例如修改访问策略。

- 进入某个存储桶后,点击右上角
上传文件 按钮,即可上传文件,支持多选和文件夹上传。

- 点击文件列表中的文件名,选择
预览,即可在线预览已上传的文件(如图片、PDF等)。

- 选择
访问密钥 功能,可以创建具有过期时间的访问密钥,并为其分配精细的文件访问策略。

- 选择
用户 功能,可以进行用户管理,并为用户分配不同的访问策略组。

- 选择
性能 功能,可以查看当前RustFS集群的服务状态、存储空间使用情况等监控信息。

结合SpringBoot实现文件上传
下面我们创建一个 SpringBoot 应用,来演示如何集成RustFS,实现文件上传和删除功能。
- 首先,在项目的
pom.xml 文件中添加AWS S3 Java SDK的依赖。
<!--AWS S3 Java SDK相关依赖-->
<dependency>
<groupId>software.amazon.awssdk</groupId>
<artifactId>s3</artifactId>
<version>${aws-s3-sdk.version}</version>
</dependency>
- 接着,在
application.yml 配置文件中添加RustFS的连接信息。
rustfs:
endpoint: http://192.168.3.101:9000
bucketName: simple
accessKey: rustfsadmin
secretKey: rustfsadmin
- 然后,创建一个RustFS的Java配置类,用于读取配置并初始化S3客户端。
/**
* RustFS配置类
*/
@Configuration
public class RustFSConfig {
@Value("${rustfs.endpoint}")
private String ENDPOINT;
@Value("${rustfs.accessKey}")
private String ACCESS_KEY;
@Value("${rustfs.secretKey}")
private String SECRET_KEY;
@Bean
public S3Client s3Client(){
// 初始化 S3 客户端
return S3Client.builder()
.endpointOverride(URI.create(ENDPOINT)) // RustFS 地址
.region(Region.US_EAST_1) // 可写死,RustFS 不校验 region
.credentialsProvider(StaticCredentialsProvider.create(AwsBasicCredentials.create(ACCESS_KEY, SECRET_KEY)))
.forcePathStyle(true) // 关键配置!RustFS 需启用 Path-Style
.build();
}
}
- 最后,创建控制器
RustFSController,实现文件上传和删除的接口逻辑。代码会自动判断存储桶是否存在,若不存在则创建并设置其为公开只读权限。
@Slf4j
@Controller
@Tag(name = "RustFSController", description = "RustFS对象存储管理")
@RequestMapping("/rustfs")
public class RustFSController {
@Autowired
private S3Client s3Client;
@Value("${rustfs.bucketName}")
private String BUCKET_NAME;
@Value("${rustfs.endpoint}")
private String ENDPOINT;
@Operation(summary = "文件上传")
@RequestMapping(value = "/upload", method = RequestMethod.POST,consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
@ResponseBody
public CommonResult upload(@RequestPart("file") MultipartFile file) {
// 判断Bucket是否存在
if(!bucketExists(BUCKET_NAME)){
// 创建Bucket
s3Client.createBucket(CreateBucketRequest.builder()
.bucket(BUCKET_NAME)
.build());
log.info("Bucket created: {}",BUCKET_NAME);
// 添加Bucket的访问策略
String policy = JSONUtil.toJsonStr(createBucketPolicyConfigDto(BUCKET_NAME));
log.info(policy);
PutBucketPolicyRequest policyReq = PutBucketPolicyRequest.builder()
.bucket(BUCKET_NAME)
.policy(policy)
.build();
s3Client.putBucketPolicy(policyReq);
}else{
log.info("Bucket already exists.");
}
// 上传文件
try {
s3Client.putObject(PutObjectRequest.builder()
.bucket(BUCKET_NAME)
.key(file.getOriginalFilename())
.contentType(file.getContentType())
.build(), RequestBody.fromInputStream(file.getInputStream(),file.getSize()));
RustFSUploadResult uploadResult = new RustFSUploadResult();
uploadResult.setName(file.getOriginalFilename());
uploadResult.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + file.getOriginalFilename());
return CommonResult.success(uploadResult);
} catch (IOException e) {
e.printStackTrace();
}
return CommonResult.failed();
}
@Operation(summary = "文件删除")
@RequestMapping(value = "/delete", method = RequestMethod.POST)
@ResponseBody
public CommonResult delete(@RequestParam("objectName") String objectName) {
// 删除对象
s3Client.deleteObject(DeleteObjectRequest.builder()
.bucket(BUCKET_NAME)
.key(objectName)
.build());
return CommonResult.success(null);
}
/**
* 判断Bucket是否存在
*/
private boolean bucketExists(String bucketName){
try {
s3Client.headBucket(request -> request.bucket(bucketName));
return true;
}
catch (NoSuchBucketException exception) {
return false;
}
}
/**
* 创建存储桶的访问策略,设置为只读权限
*/
private BucketPolicyConfigDto createBucketPolicyConfigDto(String bucketName){
BucketPolicyConfigDto.Statement statement = BucketPolicyConfigDto.Statement.builder()
.Effect("Allow")
.Principal(BucketPolicyConfigDto.Principal.builder().AWS(new String[]{"*"}).build())
.Action(new String[]{"s3:GetObject"})
.Resource(new String[]{"arn:aws:s3:::"+bucketName+"/*"}).build();
return BucketPolicyConfigDto.builder()
.Version("2012-10-17")
.Statement(CollUtil.toList(statement))
.build();
}
}
- 上面代码中
添加Bucket的访问策略 部分,通过 BucketPolicyConfigDto 实体类生成了对应的JSON策略配置,内容如下:
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"AWS": [
"*"
]
},
"Action": [
"s3:GetObject"
],
"Resource": [
"arn:aws:s3:::simple/*"
]
}
]
}
- 项目集成了Swagger,启动后可通过接口文档进行测试。访问
http://localhost:8088/swagger-ui.html,调用文件上传接口。


总结
本文介绍了新兴的 RustFS分布式文件系统 的基本特性,并通过Docker部署演示了其功能强大的管理控制台。同时,我们完成了与SpringBoot项目的整合,实现了文件的上传与删除功能。与MinIO相比,RustFS的控制台功能目前看来更为全面和开放。对于正在选型或对高性能存储方案感兴趣的开发者而言,RustFS是一个值得尝试和关注的新选择。
项目地址
RustFS的开源仓库地址:https://github.com/rustfs/rustfs
希望这篇实战指南能帮助你快速上手RustFS。如果你在部署或整合过程中遇到任何问题,欢迎到 云栈社区 的后端技术板块与其他开发者交流讨论。