
本文旨在解决在aws ec2多实例环境中,一个ec2实例如何安全、高效地访问并展示另一个ec2实例上文件列表的问题。传统的直接http路径或本地文件系统操作无法满足需求。通过引入s3fs工具,将aws s3存储桶挂载为本地文件系统,我们可以在多个ec2实例间实现文件内容的同步访问与展示,从而构建分布式且易于管理的应用程序架构。
在分布式应用架构中,尤其是在AWS EC2环境下,经常会遇到一个EC2实例(例如管理界面)需要访问并展示另一个EC2实例(例如文件存储服务器)上特定目录文件列表的需求。直接通过HTTP路径访问远程实例上的文件目录,或者尝试将远程路径视为本地文件系统路径进行操作,通常会导致失败,因为这不符合文件系统访问的机制。
考虑以下场景: 一个管理界面EC2实例(实例A)需要显示另一个文件存储EC2实例(实例B)上 /upload_directory/ 目录中的文件列表。 如果实例A尝试使用PHP的 scandir() 函数并指定一个本地路径,例如 upload_directory/,它只能访问实例A自身的文件。 如果实例A尝试将路径更改为实例B的HTTP地址,例如 http://xx.xxx.xxx.xx/upload_directory/,scandir() 函数将无法解析此URL作为一个可扫描的文件系统路径,因为它是一个网络资源而非本地目录。
// 在本地测试时,此脚本可以工作
$path = "upload_directory/";
$files = scandir($path);
foreach($files as $file) {
if ($file[0] != '.') {
$nothidden[] = $file;
}
}
for ($x=0;$x<count($nothidden);$x++){
// ${'file'.$x} = $nothidden[$x]; // 原始代码中的变量赋值可能不是最佳实践
echo $nothidden[$x] . "<br>";
}
// 当尝试访问远程HTTP路径时,此方法无效
// $path = "http://xx.xxx.xxx.xx/upload_directory/";
// $files = scandir($path); // 会失败这种情况下,仅仅调整安全组出站规则是不足以解决文件系统层面的访问问题的。我们需要一个能够将远程存储“本地化”的解决方案。
最有效且推荐的方法是利用AWS S3存储桶作为共享存储介质,并结合S3FS-FUSE工具将其挂载到EC2实例的本地文件系统。这样,两个EC2实例都可以将同一个S3存储桶视为本地目录进行读写操作,从而实现文件列表的共享与展示。
首先,您需要在AWS中创建一个S3存储桶。这个存储桶将用于存储您的文件,并且两个EC2实例都将访问它。
为了安全地访问S3存储桶,您应该为EC2实例配置适当的IAM角色。此IAM角色应至少包含对目标S3存储桶的读写权限(例如 s3:GetObject, s3:ListBucket, s3:PutObject, s3:DeleteObject 等)。将此IAM角色附加到您的EC2实例上,这比直接在实例上配置AWS访问密钥更安全。
如果您选择不使用IAM角色,则需要配置AWS访问密钥和秘密访问密钥,但这通常不推荐用于生产环境。
S3FS-FUSE是一个开源工具,允许您将S3存储桶挂载为本地文件系统。在每个需要访问S3存储桶的EC2实例(即实例A和实例B)上,都需要安装S3FS。
请参照S3FS-FUSE的官方GitHub仓库获取最新的安装指南: https://www.php.cn/link/523d6984fa5aa355c0f4b63b564ce892
通常,在Ubuntu等基于Debian的系统上,安装过程可能涉及安装依赖、编译和安装:
# 安装依赖 sudo apt-get update sudo apt-get install automake autotools-dev fuse g++ git libcurl4-gnutls-dev libfuse-dev libssl-dev libxml2-dev make pkg-config # 克隆s3fs仓库 git clone https://www.php.cn/link/523d6984fa5aa355c0f4b63b564ce892.git cd s3fs-fuse # 编译和安装 ./autogen.sh ./configure make sudo make install
安装S3FS后,您可以在两个EC2实例上将S3存储桶挂载到指定的本地目录。
使用IAM角色挂载(推荐):
如果您的EC2实例已附加具有S3读写权限的IAM角色,则可以使用以下命令进行挂载:
sudo /usr/local/bin/s3fs -o allow_other -o iam_role='您的IAM角色名称' 您的S3桶名称 /mnt/s3fs/pathlocal
使用AWS访问密钥挂载(不推荐用于生产环境):
如果您没有使用IAM角色,或者出于特定测试目的,您可以在 /etc/passwd-s3fs 文件中存储AWS访问密钥和秘密访问密钥,并设置文件权限为 600。
echo "您的AWS访问密钥ID:您的AWS秘密访问密钥" > /etc/passwd-s3fs sudo chmod 600 /etc/passwd-s3fs sudo /usr/local/bin/s3fs -o allow_other 您的S3桶名称 /mnt/s3fs/pathlocal
重要提示: 上述挂载操作需要在两个EC2实例上都执行。这意味着实例A和实例B都将把同一个S3存储桶挂载到它们各自的 /mnt/s3fs/pathlocal 目录。
为了确保EC2实例重启后S3存储桶能自动挂载,您可以将挂载命令添加到 /etc/rc.local 文件中。
编辑 /etc/rc.local 文件(如果不存在可能需要创建并赋予执行权限 sudo chmod +x /etc/rc.local):
sudo nano /etc/rc.local
在 exit 0 行之前添加您的挂载命令,例如:
#!/bin/sh -e # # rc.local # # This script is executed at the end of each multiuser runlevel. # Make sure that the script will "exit 0" on success or any other # value on error. # # In order to enable or disable this script just change the execution # bits. # # By default this script does nothing. # 确保挂载点存在 mkdir -p /mnt/s3fs/pathlocal # 使用IAM角色自动挂载S3桶 /usr/local/bin/s3fs -o allow_other -o iam_role='您的IAM角色名称' 您的S3桶名称 /mnt/s3fs/pathlocal exit 0
保存并退出。
一旦S3存储桶在两个EC2实例上都成功挂载到 /mnt/s3fs/pathlocal 路径,并且您将文件上传到S3存储桶(通过实例B,或者直接通过AWS控制台),实例A上的PHP脚本就可以像访问本地文件一样访问这些文件了。
如果您的文件在S3存储桶中是直接位于根目录,或者位于 /upload_directory/ 路径下,那么实例A上的PHP脚本可以修改为:
// 假设S3桶挂载在 /mnt/s3fs/pathlocal
// 并且您的文件在S3桶的根目录或子目录
$path = "/mnt/s3fs/pathlocal/upload_directory/"; // 确保此路径与S3桶内的实际文件路径对应
$files = scandir($path);
if ($files !== false) {
foreach($files as $file) {
if ($file[0] != '.') { // 排除隐藏文件
echo $file . "<br>";
}
}
} else {
echo "无法读取目录或目录不存在。";
}现在,当实例A运行此PHP脚本时,它实际上是在访问通过S3FS挂载的S3存储桶中的文件,从而实现了远程文件列表的展示。
通过S3FS-FUSE工具将AWS S3存储桶挂载到EC2实例的本地文件系统,我们成功地解决了在分布式EC2环境中访问和展示远程文件列表的难题。这种方法不仅提供了灵活的文件共享机制,还利用了S3的高可用性和持久性。通过合理配置IAM权限和开机自动挂载,可以构建出健壮且易于管理的文件服务架构。
以上就是通过S3FS在AWS EC2实例间高效共享与展示文件列表的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号