前提
- どっかにminioが立ち上がってる前提です
- なるべく安く定額でS3互換ストレージを立ち上げたいの続編?です
- キャッシュのみ
- アドレスのIDをほぼ再利用しないmisskeyとかで使えるかも
- 今回もさくらのレンタルサーバー スタンダードを使います
解決案
CGIでminioのデータをキャッシュして使おうぜ!
そもそものきっかけ
- なるべく安く定額でS3互換ストレージを立ち上げたいの方法だと、ネットワーク使いすぎでは?
- CGIでminioのデータ吐きたい
- minio-clientってのがあるらしい ← New!!
前準備
minio-client (mc) 入れなきゃ
- さくらのレンタルサーバーはLinuxではなくFreeBSD!
- pkgもってきてバイナリだけ使う方向で(笑)
mkdir src
cd src
wget https://pkg.freebsd.org/FreeBSD:13:amd64/latest/All/minio-client-2024.01.31.08.59.40_1.pkg
tar xvf minio-client-2024.01.31.08.59.40_1.pkg
cd ..
mkdir bin
cp src/usr/local/bin/minio-client bin/mc
- これでbin/mcできた!
mc初期設定
- 適当なalias名(今回は
media
を採用)で設定
bin/mc alias set media https://エンドポイント アクセスキー トークン
CGI登録
-
www/
で作業
.htaccess
Options +ExecCGI
<Files "media">
SetHandler cgi-script
</Files>
media
#!/usr/local/bin/ruby
ROOT="/home/アカウント名/キャッシュを置くディレクトリ名"
require 'cgi'
@cgi= CGI.new
path = @cgi.path_info
def error
puts "Status: 403 Forbidden"
puts ""
puts "Forbidden"
exit 1
end
error if path.nil? or path == ""
path = "/media" + path
if path =~ /^(\/[A-Za-z0-9_-]+)+\.[A-Za-z0-9_-]+$/
# do nothing
else
error
end
file = ROOT + path
dir = File.dirname(file)
if not File.file?(file)
`mkdir -p '#{dir}' > /dev/null 2> /dev/null`
l=0
while (l < 3) do
`/home/アカウント名/bin/mc --quiet cp 'media/#{path}' '#{file}' 2> /dev/null`
l += 1
break if File.file?(file) and not File.zero?(file)
sleep 0.1
end
end
if File.zero?(file)
File.delete(file)
end
error if not File.file?(file)
print "Content-Type: "
print `file -i '#{file}' | cut -d ' ' -f 2`
puts ""
print `cat '#{file}'`
-
mediaファイルに拡張子は付けないこと
-
media以外のバケット名を使うときは、.htaccessのファイル名、
path = "/media" + path
のmedia
文字列とファイル名を置き換えること -
以下のコマンドでCGI有効化
chmod 700 media
- これで、
https://さくらのレンタルサーバーのアドレス/media/ほげほげ
が、元のエンドポイントのコピーを指すようになる
定期的に削除
crontab -e
に、例えば以下のように書いておく
0 5 * * * find /home/アカウント名/キャッシュを置くディレクトリ名 -type f -atime +30 -exec rm -f {} \;
- これで、30日間アクセスされていないファイルは削除される(はず)
misskeyに反映
-
コントロールパネル → オブジェクトストレージから、Base URLを
https://さくらのレンタルサーバーのアドレス/media/
に設定 -
これ以降のファイルはさくらのレンタルサーバー経由に
ちなみに
見てわかるとおり、削除・更新やIDのコンフリクトには対応していません
がまぁ、misskeyのオブジェクトストレージとしてなら良いんじゃないかな。
結果
2回目以降のアクセスが早くなったよー!
おまけ
さらなる高速化を目指した結果、こうなった!
- mediaという名前のファイルをmedia.loadにリネーム
- 新たなmediaという名前のファイルを以下の内容で記述
media
<?php
//ob_start();
//ini_set('display_errors', "On");
function error(){
header("HTTP/1.1 503 Service Unavailable");
header("Content-Type: text/plain; charset=utf-8");
header("Cache-control: no-store");
header("Pragma: no-cache");
header("Expires: -1");
echo "Service Unavailable";
exit;
}
$ROOT="/home/アカウント名/キャッシュを置くディレクトリ名";
$path = $_SERVER['PATH_INFO'];
if (preg_match('/^(\\/[A-Za-z0-9_-]+)+(\\.[A-Za-z0-9_-]+)?$/',$path) == 1){
// OK
}else{
error();
}
$file = $ROOT . "/media" . $path;
if (file_exists($file)){
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime_type = $finfo->file($file);
if ($mime_type == "") {
$mime_type = "binary/octet-stream";
}
header("Content-Type: " . $mime_type);
header('Content-Length: ' . filesize($file));
readfile($file);
}else{
header("Location: " . $_SERVER['REQUEST_SCHEME'] . "://" . $_SERVER['SERVER_NAME'] . "/media.load" . $path);
}
?>
.htaccessを次のように書き換える
.htaccess
Options +ExecCGI
<Files "media">
ForceType application/x-httpd-php
</Files>
<Files "media.load">
SetHandler cgi-script
</Files>
これでキャッシュがあるときはクソ早いphpを、そうじゃないときはruby-cgiを使って処理するようになりました