前端lvs+haproxy,分布走4,7层代理,之后是各个节点的squid,然后图片存储到DFS,前边有apache做图片热点缩略图(估计会放到SSD上),相当于squid前边的一个cache。大致如下
client
|
lvs
|
haproxy
|
squid----------->网站首页
|
apache(image server) ---upload
|
DFS系统
其中dfs肯定要做冗余,放在2个以上的IDC里面,同时用户按照智能dns上传到upload,同时在前端db记录(表结构可能是用户的id和该图片所在的位置),之后通过复制(单独讲)逐步同步到各个DFS里,然后image server一个单独的域名,当用户访问网站首页的时候,假如cache层的squid miss了,会查询店铺的用户ID,找出对应的图片,然后组合成图片的url,此时squid配置了dns,查询该url对应的ip,找到对应的image server,假如它没热图缓存,直接问dfs要,实际上这个过程也是访问一个url,然后把图片显示给用户。
关于dfs各个IDC之间的复制问题,假如DFS放在BJ,SH,那么upload只能按照区域来分配规定用户上传图片到某个城市的IDC,此时会有几个问题如下:
1.假如北方用户(姑且认为上传upload分在bj)传了图片,而此时不可能瞬间同步到sh去,而此时某个南方的用户刚好要看这个图片,此时squid肯定没缓存,会问sh的image server要,图片没复制过来,肯定显示不了,此时怎么处理?
2.各个城市IDC怎么复制数据?
补充一个:快速删squid cache,基于pub/sub模型的scatter,在IDC里admin上purge,然后它会自动发消息到其他IDC,删除速度很快。关于pub/sub,一个pub和若干个sub, pubcrash或出现network partition时其它sub选举出一个新pub来failover。详细说,IDC里每个机器都是pub,sub,然后zookeeper选出pub(为什么不指定某个Pub?防止出现故障),每个IDC之间由grossip来负责通信,当配置某个client,就确定了某个view,同一个view之间订阅topic,然后在admin来下达删除命令的时候,能快速同步到各个IDC的机器上。
通俗点讲:每个IDC算一个部门,每个部门里通过paxos算法选出一个人来充当pub(当然他挂掉,姑且这说,会再选举一个pub),其他部门也如此,然后部门之间通过grossip来联络,每个部门的某几个人都能组成一个群体view(通过sub)实现,当公司老总admin说周五下午看电影(topic)你们要做什么准备的时候,某个部门的pub会通告其他部门pub,这个是个p2p的过程。然后部门里的sub获取该topic,来做某个动作。当然admin发布的topic很多,某个部门的sub可能订阅了多个,同理会做这些。
还有流量动态调度,缓存的主动推送,快速删除缓存......一说东西太多了。
补充:看下边代码吧,简单的功能实现:
表单提交部分:
2.upload.php
- <?php
- if ((($_FILES["file"]["type"] == "image/gif")
- || ($_FILES["file"]["type"] == "image/jpeg")
- || ($_FILES["file"]["type"] == "image/pjpeg"))
- && ($_FILES["file"]["size"] < 20000) && (is_uploaded_file($_FILES["file"]["tmp_name"])))
- {
- if ($_FILES["file"]["error"] > 0)
- {
- echo "Return Code: " . $_FILES["file"]["error"] . "
";
- }
- else
- {
- echo "Upload: " . $_FILES["file"]["name"] . "
";
- echo "Type: " . $_FILES["file"]["type"] . "
";
- echo "Size: " . ($_FILES["file"]["size"] / 1024) . " Kb
";
- echo "Temp file: " . $_FILES["file"]["tmp_name"] . "
";
- if (file_exists("/var/www/html/" . $_FILES["file"]["name"]))
- {
- echo $_FILES["file"]["name"] . " already exists. ";
- }
- else
- {
- move_uploaded_file($_FILES["file"]["tmp_name"],
- "/var/www/html/" . $_FILES["file"]["name"]);
- $name=$_FILES["file"]["name"];
- $type="image/pjpeg";
- $image="/var/www/html/".$name;
- require "conn.php";
- mysql_select_db("test",$conn) or die ("connect failed :". mysql_error());
- $sql= "insert into image(name,type,image) values('".$name."','".$type."','".$image."')";
- if(mysql_query($sql))
- echo "ok,display pic click here to display";
- else
- echo "failed".mysql_error()."";
- mysql_close();}
- }
- }
- else
- {
- echo "Invalid file";
- }
- ?>
3.disimage.php
<?php
require "conn.php";
mysql_select_db("test");
//显示最新插入的那张图片
$result=mysql_query("select image from images where id=(select max(id) from images)");
$row=mysql_fetch_object($result);
header("Content-Type:image/pjpeg");
echo $row->image;
mysql_close();
?>
4.数据库为test.image中设置id int(10) auto_increment,name varchar(50),type varchar(20),varchar(50),
这样图片就插入到数据库中了。
这里把localhost换为mysql db所在的机器,做个master/slave,图片服务器可以和它在同一个机器上,也可以单独拿出一台,只需要改动这里图片上传上来到临时文件的路径,换成image server的域名即可。
显示的时候,直接嵌入在html,查询DB,然后显示出来。
我之前的疑问:电子商务网站某个页面某个地方显示商品图片和描述,是怎么实现的?
注意这个商品图片和描述会被更新,成熟的做法是?也就是如何让某个页面里某个位置显示一个图片,而且该图片可能放在另外一个机器上。
之前asp页面的时候,images目录直接放图片,只需要在html或asp里需要显示的位置添加:
阅读(1740) | 评论(0) | 转发(0) |