nodejs使用RustFS容器服务搭建对象存储oss

介绍

在后端开发中,对象存储(OSS) 是文件存储、图片 / 视频托管、静态资源分发的核心组件。市面上成熟的 OSS(阿里云 OSS、腾讯云 COS)功能强大但成本较高,小型项目、私有部署场景下,我们更需要轻量、高性能、可自主掌控的私有对象存储。

如果你想搭建一套轻量、高性能、无依赖的私有对象存储(OSS),但不想从零写 Rust 服务,那 RustFS + Node.js 就是完美组合:

  1. RustFS:用 Rust 实现的轻量级对象存储服务,开箱即用,性能拉满
  2. Node.js:快速封装 RESTful API,对接 RustFS,适配业务场景

什么是 RustFS?

RustFS 是一个用 Rust 编写的轻量级对象存储服务,兼容 S3 协议,支持:

  1. 高性能文件读写
  2. 多端口服务(默认 9000 为 API 端口,9001 为控制台 / 管理端口)
  3. 兼容 S3 API,可直接用 S3 SDK 对接
  4. 支持本地文件系统存储,无需额外数据库

整体架构设计

bash 复制代码
前端/客户端
    ↓
Node.js 服务(egg)
    ↓
RustFS 服务(端口 9000)
    ↓
本地文件系统(物理存储)

核心优势:

  1. 快速部署:RustFS 容器一键启动,无需配置
  2. 高性能:Rust 底层 IO,比 Node.js 原生文件操作快数倍
  3. 兼容 S3:可直接用 AWS SDK 或 S3 客户端对接
  4. 易扩展:Node.js 层可轻松封装权限控制、文件处理、元数据管理

安装RustFS容器

这里是用的宝塔面板,先安装docker 在dcoker下面安装 RustFs容器


oss对象存储面板

egg接入OSS对象存储

安装 minio

bash 复制代码
npm i minio

oss配置

bash 复制代码
  config.rustfs = {
    endPoint: '', // 你的服务器IP
    port: 9001, // S3 API 端口(必须是 9001,不是控制台 9000)
    useSSL: false,
    accessKey: '',
    secretKey: '',
    bucket: '', // 你的桶名
    externalUrl: 'http://xxx.xx.xx:9001', // 外网访问地址
  };

上传和删除

在使用的地方就可以调用上传(uploadByStream)和删除(deleteFile)的方法

bash 复制代码
'use strict';

const Service = require('egg').Service;
const { v4: uuidv4 } = require('uuid');
const Minio = require('minio');

class RustfsService extends Service {
  constructor(ctx) {
    super(ctx);
    // 初始化客户端
    const config = this.app.config.rustfs;
    this.minioClient = new Minio.Client({
      endPoint: config.endPoint,
      port: Number(config.port),
      useSSL: config.useSSL,
      accessKey: config.accessKey,
      secretKey: config.secretKey,
    });
    this.bucket = config.bucket;
    this.externalUrl = config.externalUrl;
  }

  /**
   * 流式上传
   * @param {Stream} fileStream - 文件可读流
   * @param {String} fileExt - 文件扩展名
   * @param {String} [contentType='application/octet-stream'] - 文件类型
   * @return {Object} 上传结果
   */
  async uploadByStream(fileStream, fileExt, contentType = 'application/octet-stream') {
    // 生成唯一文件 key
    const fileName = `${uuidv4()}${fileExt}`;
    const fileKey = `upload/${new Date().getFullYear()}_${new Date().getMonth() + 1}_${fileName}`;

    try {
      // 流式上传
      const etag = await this.minioClient.putObject(
        this.bucket,
        fileKey,
        fileStream,
        {
          'Content-Type': contentType,
        }
      );

      return {
        success: true,
        key: fileKey,
        url: `${this.externalUrl}/${this.bucket}/${fileKey}`,
        hash: etag.etag,
        fileKey,
      };

    } catch (error) {
      this.ctx.logger.error('RustFS 流式上传失败:', error);
      return {
        success: false,
        message: error.message,
      };
    }
  }

  /**
   * 删除文件
   * @param {String} fileKey - 文件key
   * @return {Object} 删除结果
   */
  async deleteFile(fileKey) {
    console.log('fileKey', fileKey);
    if (!fileKey) {
      return {
        success: false,
        message: '文件key不能为空',
      };
    }

    try {
      await this.minioClient.removeObject(this.bucket, fileKey);

      return {
        success: true,
        message: '文件删除成功',
        fileKey,
      };

    } catch (error) {
      this.ctx.logger.error('RustFS 文件删除失败:', error);
      return {
        success: false,
        message: `删除失败:${error.message}`,
        fileKey,
      };
    }
  }
}

module.exports = RustfsService;
相关推荐
大貔貅喝啤酒6 小时前
接口测试_Postman(详细版)
javascript·测试工具·node.js·自动化·postman
桜吹雪7 小时前
Langchain.js官方文档:构建具备按需加载技能的 SQL 助手
javascript·人工智能·node.js
拾贰_C13 小时前
【node.js | Ubuntu | update】如何升级旧的nodejs本版至最新;如何升级npm
ubuntu·npm·node.js
湖边看客14 小时前
在 Windows PowerShell 里给 Node.js 设置内存上限
node.js
zhensherlock15 小时前
Protocol Launcher 系列:Beorg 高效任务管理的协议支持
前端·javascript·typescript·node.js·自动化·github·js
shao9185161 天前
第3章(2)——使用Gradio JavaScript Client
javascript·node.js·cdn·gradio·job·events·playcode
Rabbit_QL1 天前
npm 不是“前端的包管理器“—它是 Node.js 的
前端·npm·node.js
是大强1 天前
nvm安装node成功npm失败
前端·npm·node.js
donecoding2 天前
Claude Code (cc) 升级 2.1.121 报错“Native Binary”全记录
node.js·claude