lbnnbs


比如文件原来都存储在网站的upload目录,云存储网址是file.xxxx.com

首先配置nginx重写原图片地址到云存储地址,做302跳转
location ^~ /uploads/ {
    if (!-e $request_filename) {
        rewrite ^(/uploads/.*)$ https://file.xxx.com$1 permanent;
        break;
    }
}

 

然后使用同步工具,或者自己写个同步进程,在同步完后删除本地服务器图片

比如用WorkerMan+七牛SDK

use Workerman\Worker;
use Workerman\Timer;
use Qiniu\Storage\UploadManager;
use Qiniu\Auth;

define(\'ROOT_PATH\', realpath(__DIR__)); // 系统根目录
define(\'PUBLIC_PATH\', ROOT_PATH . \'/Public\'); // 网站根目录
define(\'UPLOAD_PATH\', ROOT_PATH . \'/Public/uploads/\'); // 上传文件磁盘目录
define(\'UPLOAD_URL\', \'/uploads/\'); // 上传文件网址路径

$accessKey = \'\'; // 七牛accessKey
$secretKey = \'\'; // 七牛secretKey
$bucket = \'xxx\'; // 存储空间

$worker1 = new Worker();
$worker1->count = 1;
$worker1->onWorkerStart = function ($worker) use ($accessKey, $secretKey, $bucket) {

    $workerId = $worker->id;

    // 毫秒级别
    Timer::add(60, function () use ($workerId, $accessKey, $secretKey, $bucket) {

        $uploadMgr = new UploadManager();

        $auth = new Auth($accessKey, $secretKey);

        $token = $auth->uploadToken($bucket);

        $files = dirTree(UPLOAD_PATH, true, true);

        $uploaded_count = 0;
        
        $count = count($files);

        foreach ($files as $file) {

            $url = str_replace(PUBLIC_PATH . \'/\', \'\', $file);
            
            if(strpos($url, \'qrcode\')) {
                $count--;
                continue;
            }

            list($ret, $error) = $uploadMgr->putFile($token, str_replace(PUBLIC_PATH . \'/\', \'\', $file), $file);

            if ($ret && $ret[\'hash\'] && $ret[\'key\'] && $ret[\'key\'] == $url) {
                $uploaded_count++;
                eol(\'文件已上传:\' . $file);
                if (!unlink($file)) { // 删除本地文件
                    eol(\'清理本地文件失败:\' . $file);
                }
            } else {
                if ($error instanceof Qiniu\Http\Error && $error->code() == 614) {
                    $uploaded_count++;
                    eol($error->message() . PHP_EOL . $file);
                    if (!unlink($file)) { // 删除本地文件
                        eol(\'清理本地文件失败:\' . $file);
                    }
                }
                eol(\'文件上传失败:\' . $file);
                eol($error);
            }
        }

        eol("总计文件:{$count},已上传:{$uploaded_count}");
    });
};

 



七牛同步和nginx防瞬时文件丢失原理:
后台端上传文件时,需要立马看到上传的文件,以便确认文件上传成功,且显示效果良好
而文件上传后的60s还在内本地服务器,所以nginx重写301跳转前判断文件存在,不会引发重写,返回给后台端的还是本地服务器上的文件
60s后,七牛同步Worker把文件同步到七牛,并删除本地文件,此时前台端读取文件,因为文件不存在,被nginx重写301到七牛

注意的时必须使用permanent(301跳转),否则rewrite结果是302临时跳转
302会导致浏览缓存之前的网址,百度也会缓存之前的网址,并于缓存过期后重新请求之前的网址
加重服务器和用户端浏览器负担,百度也对302跳转有惩罚措施

分类:

技术点:

相关文章:

  • 2021-09-12
  • 2021-06-15
  • 2021-12-16
  • 2021-10-30
  • 2021-06-06
  • 2021-09-01
  • 2021-11-18
猜你喜欢
  • 2021-11-04
  • 2021-05-25
  • 2021-12-30
  • 2021-12-03
  • 2021-12-29
  • 2021-12-28
  • 2022-12-23
相关资源
相似解决方案