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

1757

积分

0

好友

257

主题
发表于 7 天前 | 查看: 21| 回复: 0

在项目开发中,文件存储是一个常见的需求。除了主流的OSS服务,MinIO等自建方案也备受青睐。近期,一款名为RustFS的全新开源分布式对象存储软件进入了开发者视野。它自带功能完善的管理控制台,并提供与AWS S3协议的兼容性,为开发者提供了又一个强大的存储选择。

简介

RustFS是一个基于Rust语言开发的高性能分布式对象存储软件。它采用Apache 2.0开源协议,在开源后短时间内就获得了广泛的关注。与MinIO类似,它具有部署简单、性能高、兼容S3等优点。

RustFS的主要特性如下:

  • 高性能:基于Rust构建,具有较高的性能和响应速度。
  • 分布式架构:可扩展且容错的设计,适用于大规模部署。
  • AWS S3 兼容性:可使用AWS S3 SDK来管理它。
  • 数据湖支持:针对大数据和AI工作负载进行了优化。
  • 开源:采用Apache 2.0许可证,鼓励社区贡献。
  • 用户友好:具有可视化管理控制台,方便管理。

以下是RustFS管理控制台的界面效果图:
RustFS控制台概览

安装

使用Docker是部署RustFS最便捷的方式。

  1. 拉取镜像
    首先,使用以下命令拉取RustFS的Docker镜像:

    docker pull rustfs/rustfs
  2. 运行容器
    镜像拉取完成后,通过以下命令启动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

    命令说明:

    • -p 9000:9000: 将容器的9000端口映射到宿主机。
    • -e: 设置环境变量,此处指定了默认的管理员账号和密码。
    • -v: 挂载数据卷和时区文件。
  3. 访问控制台
    容器启动成功后,即可通过浏览器访问管理控制台。默认访问地址为 http://<你的服务器IP>:9000,默认账号密码为 rustfsadmin / rustfsadmin
    登录界面

控制台使用

RustFS的控制台界面直观,功能清晰。

  • 创建存储桶(Bucket)
    在“文件浏览器”页面,点击右上角的“创建存储桶”按钮即可创建新的存储空间。
    创建存储桶

  • 配置存储桶
    点击存储桶对应的“配置”按钮,可以修改其访问策略等设置。
    配置存储桶

  • 上传与预览文件
    进入存储桶后,点击“上传文件”可上传单个或多个文件。上传完成后,点击文件即可选择“预览”功能。
    上传文件
    预览文件

  • 访问密钥与用户管理
    在“访问密钥”功能中,可以创建具有过期时间和特定策略的临时密钥。
    在“用户”功能中,可以管理用户并为其分配访问策略。
    访问密钥
    用户管理

  • 系统监控
    “性能”页面提供了服务器的基本运行信息概览。
    性能监控

结合SpringBoot实现文件上传

下面演示如何在一个SpringBoot应用中集成RustFS,实现文件的上传与删除功能。

  1. 添加依赖
    在项目的 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>
  2. 配置连接信息
    application.yml 配置文件中添加RustFS的连接信息。

    rustfs:
      endpoint: http://192.168.3.101:9000
      bucketName: springboot-bucket
      accessKey: rustfsadmin
      secretKey: rustfsadmin
  3. 配置S3客户端
    创建一个配置类,读取配置并初始化S3客户端。

    @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() {
            return S3Client.builder()
                    .endpointOverride(URI.create(ENDPOINT))
                    .region(Region.US_EAST_1) // RustFS不校验region,可写死
                    .credentialsProvider(StaticCredentialsProvider.create(
                            AwsBasicCredentials.create(ACCESS_KEY, SECRET_KEY)))
                    .forcePathStyle(true) // 关键配置!RustFS需启用Path-Style访问
                    .build();
        }
    }
  4. 实现文件上传与删除Controller
    创建控制器,实现文件上传(自动创建Bucket并设置公开读策略)和删除功能。

    @Slf4j
    @RestController
    @RequestMapping("/rustfs")
    public class RustFSController {
        @Autowired
        private S3Client s3Client;
        @Value("${rustfs.bucketName}")
        private String BUCKET_NAME;
        @Value("${rustfs.endpoint}")
        private String ENDPOINT;
    
        @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
        public CommonResult upload(@RequestPart("file") MultipartFile file) {
            // 判断并创建Bucket
            if (!bucketExists(BUCKET_NAME)) {
                s3Client.createBucket(CreateBucketRequest.builder().bucket(BUCKET_NAME).build());
                log.info("Bucket created: {}", BUCKET_NAME);
                // 设置Bucket策略为公开只读
                String policy = JSONUtil.toJsonStr(createBucketPolicyConfigDto(BUCKET_NAME));
                PutBucketPolicyRequest policyReq = PutBucketPolicyRequest.builder()
                        .bucket(BUCKET_NAME)
                        .policy(policy)
                        .build();
                s3Client.putBucketPolicy(policyReq);
            }
            // 上传文件
            try {
                s3Client.putObject(PutObjectRequest.builder()
                                .bucket(BUCKET_NAME)
                                .key(file.getOriginalFilename())
                                .contentType(file.getContentType())
                                .build(),
                        RequestBody.fromInputStream(file.getInputStream(), file.getSize()));
                RustFSUploadResult result = new RustFSUploadResult();
                result.setName(file.getOriginalFilename());
                result.setUrl(ENDPOINT + "/" + BUCKET_NAME + "/" + file.getOriginalFilename());
                return CommonResult.success(result);
            } catch (IOException e) {
                e.printStackTrace();
                return CommonResult.failed("上传失败");
            }
        }
    
        @PostMapping("/delete")
        public CommonResult delete(@RequestParam 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 e) {
                return false;
            }
        }
        // 生成公开只读策略JSON
        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策略JSON配置如下:

    {
      "Version": "2012-10-17",
      "Statement": [
        {
          "Effect": "Allow",
          "Principal": {
            "AWS": ["*"]
          },
          "Action": ["s3:GetObject"],
          "Resource": ["arn:aws:s3:::springboot-bucket/*"]
        }
      ]
    }
  5. 接口测试
    启动应用后,可以通过Swagger UI(或使用Postman等工具)测试接口。

    • 文件上传:调用上传接口,成功后返回文件访问URL。
      上传测试
      由于设置了公开读策略,可以直接通过返回的URL访问文件。
      访问文件
    • 文件删除:调用删除接口,传入文件名即可删除指定文件。
      删除测试

总结

本文介绍了新兴的分布式对象存储系统RustFS,涵盖了其Docker部署、控制台功能详解以及与SpringBoot应用的整合实战。相比MinIO,RustFS提供了一个功能更为丰富的管理界面。对于正在寻找高性能、可扩展且易于管理的自建存储方案的开发者来说,RustFS是一个值得尝试的选择。

项目地址




上一篇:从n-gram到Transformer:统计语言模型工作原理与AI大模型入门
下一篇:C++17透明哈希解析:提升无序容器字符串查找性能的关键优化
您需要登录后才可以回帖 登录 | 立即注册

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

GMT+8, 2025-12-24 20:53 , Processed in 0.267411 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

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