本文将手把手带你实现 Webman 微服务与国产高性能分布式对象存储系统 RustFS 的集成,构建安全可靠的文件存储解决方案。
目录
一、技术选型背景
作为长期关注微服务和存储技术的开发者,我在构建Web应用时经常需要处理文件存储需求。传统的本地存储方案存在单点故障风险,而云存储服务又可能带来高昂成本和数据隐私顾虑。RustFS 作为一款国产开源分布式对象存储系统,完美地解决了这些痛点。
RustFS 完全兼容 S3 协议,采用 Apache 2.0 开源协议,使用 Rust 语言编写,具有高性能、内存安全和轻量级的特点。其读写速度比同类工具快 92% 以上,数据读写成功率达到 99.99%,二进制包仅 100MB,对 ARM 架构设备原生支持。
Webman 是一款基于 Workerman 开发的高性能 PHP 微服务框架,支持常驻内存,非常适合构建高并发应用。本文将介绍如何在 Webman 微服务中集成 RustFS,实现高效可靠的文件存储方案。
二、环境准备
2.1 RustFS 部署
首先使用 Docker 部署 RustFS 服务:
# docker-compose.yml
version: '3.8'
services:
rustfs:
image: rustfs/rustfs:latest
container_name: rustfs
ports:
- "9000:9000" # API端口
- "9001:9001" # 控制台端口
volumes:
- ./data:/data
environment:
- RUSTFS_ACCESS_KEY=admin
- RUSTFS_SECRET_KEY=admin123
restart: unless-stopped
运行以下命令启动服务:
docker-compose up -d
服务启动后,访问 http://localhost:9001使用 admin/admin123 登录管理控制台,创建一个名为 "webman-bucket" 的存储桶。
2.2 Webman 项目准备
确保你已经有一个 Webman 项目。如果没有,可以通过以下命令创建:
composer create-project workerman/webman webman-app
cd webman-app
三、集成 RustFS
3.1 安装依赖包
在 Webman 项目中安装 AWS S3 SDK(因为 RustFS 完全兼容 S3 协议):
composer require league/flysystem-aws-s3-v3
3.2 配置 RustFS 连接
创建配置文件 config/rustfs.php:
<?php
return [
'endpoint' => 'http://localhost:9000',
'access_key' => 'admin',
'secret_key' => 'admin123',
'bucket' => 'webman-bucket',
'region' => 'us-east-1',
'use_path_style_endpoint' => true,
];
3.3 创建 RustFS 服务类
在 app/service目录下创建 RustFSService.php:
<?php
namespace app\service;
use Aws\S3\S3Client;
use Aws\S3\Exception\S3Exception;
use support\Log;
class RustFSService
{
protected $s3Client;
protected $bucket;
public function __construct()
{
$config = config('rustfs');
$this->bucket = $config['bucket'];
$this->s3Client = new S3Client([
'version' => 'latest',
'region' => $config['region'],
'endpoint' => $config['endpoint'],
'use_path_style_endpoint' => $config['use_path_style_endpoint'],
'credentials' => [
'key' => $config['access_key'],
'secret' => $config['secret_key'],
],
'http' => [
'connect_timeout' => 5,
'timeout' => 10,
],
]);
}
/**
* 上传文件到 RustFS
* @param string $localPath 本地文件路径
* @param string $key 存储路径
* @return string|bool 文件 URL 或 false
*/
public function uploadFile($localPath, $key)
{
try {
$result = $this->s3Client->putObject([
'Bucket' => $this->bucket,
'Key' => $key,
'Body' => fopen($localPath, 'r'),
'ACL' => 'public-read',
]);
return $result['ObjectURL'];
} catch (S3Exception $e) {
Log::error('RustFS 上传失败: ' . $e->getMessage());
return false;
}
}
/**
* 获取文件预签名 URL
* @param string $key 文件路径
* @param int $expires 有效期(秒)
* @return string|bool 预签名 URL 或 false
*/
public function getPresignedUrl($key, $expires = 3600)
{
try {
$cmd = $this->s3Client->getCommand('GetObject', [
'Bucket' => $this->bucket,
'Key' => $key,
]);
$request = $this->s3Client->createPresignedRequest($cmd, "+{$expires} seconds");
return (string)$request->getUri();
} catch (S3Exception $e) {
Log::error('获取预签名 URL 失败: ' . $e->getM

最低0.47元/天 解锁文章
2047

被折叠的 条评论
为什么被折叠?



