找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1059

积分

0

好友

139

主题
发表于 17 小时前 | 查看: 0| 回复: 0

在项目开发中,文件存储是绕不开的环节。目前流行的解决方案包括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管理控制台的界面效果图,可以看到其功能相当完善。

RustFS文件浏览器管理界面截图

安装

使用Docker安装RustFS是最便捷的方式。

  • 首先,使用以下命令拉取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控制台登录界面

控制台使用

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,调用文件上传接口。

Swagger界面文件上传测试

  • 上传成功后,接口会返回文件的访问URL。由于我们设置的桶策略为 公开只读 ,该URL可直接在浏览器中访问。

  • 调用文件删除接口,传入对应的 objectName 参数,即可删除指定文件。

Swagger界面文件删除测试

总结

本文介绍了新兴的 RustFS分布式文件系统 的基本特性,并通过Docker部署演示了其功能强大的管理控制台。同时,我们完成了与SpringBoot项目的整合,实现了文件的上传与删除功能。与MinIO相比,RustFS的控制台功能目前看来更为全面和开放。对于正在选型或对高性能存储方案感兴趣的开发者而言,RustFS是一个值得尝试和关注的新选择。

项目地址

RustFS的开源仓库地址:https://github.com/rustfs/rustfs

希望这篇实战指南能帮助你快速上手RustFS。如果你在部署或整合过程中遇到任何问题,欢迎到 云栈社区 的后端技术板块与其他开发者交流讨论。




上一篇:从浏览器到服务器:一文讲透HTTP请求在网络中的完整旅程
下一篇:AutoPentestX工具怎么用?一键自动化Linux渗透测试与报告生成
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-2-2 21:45 , Processed in 0.275790 second(s), 43 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表