搜索
系统检测到您的用户名不符合规范:

千万级图片资源存储方案分享

浏览:5068 发布日期:2016年05月01日 分类:技术分享 关键字: 图片存储 图片服务器
本文节选自
H5应用必须掌握的技能点-图片篇
http://www.imwinlion.com/archives/158
1、怎么存储图片
这个问题的实质是如何设计上节 的$dstPath问题。是为什么会有这个问题呢?笔者在日常开发种发现很多图片存储无设计, 所以的到的图片大概是这样的

http://shang.qq.com/wpa/qunwpa?idkey=7322d7b39a8564d24b48b5e7d83fcde645f4c0e9ad84f1f7ddc7baff47574d7d

http://www.imwinlion.com/wp-content/uploads×ばつ300.png

像这种图片结构,在应用根目录下新建一个upload 文件夹,然后下面分日期/uploads/2016/04/ 在小型的应用中,还能将就着用的,但是一旦图片数目多起来,并且要存储的是图片的id时,我们该怎么做呢?笔者研读阿里的 fastfs,并经过大量的应用实践,积累了一套实用好操作的图片命名策略,如下

[hostid][level][dirstr][filename][suffix]

这种名称策略怎么理解呢?

hostid:图片服务器资源ID.这个涉及到我们自身的服务器资源规划问题。自定义的,比如我们应用占用了俩台服务器资源,一台是应用服务器,我们编号为0,一台是资源服务器,我们将这个服务器资源编号为1,这个数据就是hostid
level:相对于图片服务根目录来说,图片存储的文件夹目录深度,一般为俩层。比如我们存储的根目录为 /mnt/h5app/,那么这下面 的 目录 a/b/c,level就是3
dirstr:目录字符串,如上,目录字符串就是abc
filename: md5 策略或者uuid 策略生成 的文件名,如md5(microtime() . mt_rand(1000,9999));
suffix:文件的后缀,如.jpg,.png
举个列子。假设我们的应用服务器服务器,编号是0,根目录是/alidata/www/www.imwinlion.com/ ,对应的域名是www.imwinlion.com

我们的图片服务器有三台,一台编号是1,目录是/mnt/www.imwinlion.com/ ,对应的域名是res1.imwinlion.com

另一台编号是2,根目录是/mnt/www.imwinlion.cn/,对应的域名是res2.imwinlion.com

现在,我们根据我们设计的文件存储策略,假设名称是13abc01f9c76ce5c45aeec2e6f816c95b854b.jpg,那么根据问价夹的第1位数字,知道这个文件hostid 是1,

应该存放在编号为1的服务器,也就是/mnt/www.imwinlion.com/ 下

根据第二个参数level 为3,我们知道这个文件有3个父级子目录,那么接下来的三个字母abc 就是dirstr , 接下来的01f9c76ce5c45aeec2e6f816c95b854b 是md5 生成的随机字符串

最后.jpg 是文件格式,那么这个文件的存储路径应该是这样

/mnt/www.imwinlion.com/a/b/c/13abc01f9c76ce5c45aeec2e6f816c95b854b.jpg

对应访问地址是这样 http://res1.imwinlion.com/a/b/c/13abc01f9c76ce5c45aeec2e6f816c95b854b.jpg,文件id 就是文件名称 13abc01f9c76ce5c45aeec2e6f816c95b854b.jpg

我们数据库存这个id ,前端只要根据策略和这个ID就能够获得 图片路径

这种策略的核心在于先根据业务逻辑规划出图片存放路径。是先知道了文件路径,然后再存储。但是我们常用的框架,把文件的命名策略封闭起来了,我们只能先存起来,再获得文件名。这需要改造!!
2、给个实例

此列子相关的详细场景 见
http://www.imwinlion.com/archives/158 <?php //cfgupload.php 配置文件
return array (
'UPLOAD' =>
array (
'maxSize' => 2097152,
'exts' =>
array (
0 => 'jpg',
1 => 'gif',
2 => 'png',
3 => 'jpeg',
4=>"mp3",
),
'rootPath' => '/mnt/img.imwinlion.com/',
'savePath' => '',
'driver' => 'Local',
'subType' => 'hash',
'hashLevel' => 1,
'domain' => 'res1.imwinlion.com',
'scheme' => 'http',
'subDir' => 'upload',
),
);

/*该函数处理前端上传过来的base64场景*/
function uploadb64(){
$uploadcfg=C('UPLOAD');

$hashLevel = intval($uploadcfg["hashLevel"]);
$rootPath = $uploadcfg["rootPath"];
$savePath = $uploadcfg["savePath"];
$subDir = $uploadcfg["subDir"];
$scheme = $uploadcfg["scheme"];
$domain = $uploadcfg["domain"];
$dir = "";
$filename = md5(microtime()).".jpg";

$str = "0123456789abcdef";
$a1 = "";
$a2 = "";
if($hashLevel!=2 && $hashLevel!=1){
$$hashLevel = 1;
}
if($hashLevel==1){
$a1 = $str[mt_rand(0,strlen($str))];
$savePath = $a1;
$filename = $hashLevel. $a1 .$a2. $filename;
}
if($hashLevel==2){
$a1 = $str[mt_rand(0,strlen($str))];
$a2 = $str[mt_rand(0,strlen($str))];
$savePath = $a1 ."/" .$a2 ;
$filename = $hashLevel . $a1 .$a2. $filename;
}

//根据策略获得hostid
$filename .= ($this->gethostid(0) . $filename);

$this->base64toimage($this->request["data"],$rootPath . "/" . $subDir ."/". $savePath ."/". $filename );



$resp = array();




$url = $scheme. "://" . $domain . "/". $subDir ."/".$savePath ."/". $filename ;
$resp["url"] = $url;
$resp["error"] = 0;
$resp["state"]="SUCCESS";


if($this->request["callback"]) {
echo '<script>'.$callback.'('.json_encode($resp).')</script>';
} else {
echo json_encode($resp);
}

}


function base64toimage($strBase64, $outputFile ) {

$ifp = fopen( $outputFile, "wb" );
fwrite( $ifp, base64_decode( $strBase64) );
fclose( $ifp );
return( $outputFile );
}


/*这里有个技巧,我们根据入参业务频繁程度获取if*/
function gethostid($type=0){
//存那一台服务器逻辑需要我们自己编写
//我们这里演示 默认定死了 为1
return 1;

}
最佳答案
评论() 相关
后面还有条评论,
评论支持使用[code][/code]标签添加代码
您需要登录后才可以评论 登录 | 立即注册
收藏
winlion
积分:574 等级:LV2
热点推荐
(追記) (追記ここまで)
最新更新

我们

合作

网站

信息

ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。

AltStyle によって変換されたページ (->オリジナル) /