八月, 2010 的所有文章
中等规模相册的上传存储机制初探
这里对中等的定义是:图片文件所占空间在1TB–99TB。 这个机制是研究了人人网等一些UGC网站所得出的方案。 以4台服务器为模型:相册所属的主站服务器A、主站所用的Mysql服务器M、接收并处理上传文件的服务器B、最终存储图片文件并提供http下载的服务器C。实际应用中C应为多台服务器分布式存储。 首先,上传图片的入口在A上。那么,上传表单所属的html文件应该存储在A还是B呢?第一感觉应该是在A上,然后表单的action指向B,这样就可以直接把文件数据提交到B。但是事实上,我们通常会在相册中使用ajax提交表单,如果表单在A上,而数据提交到B,就会造成跨域的问题。所以,我们把这个表单部署在B上,通过同一个根域的cookie和存储在M上的session数据来验证用户身份。 B的基本任务是:验证,去重,处理,存储。 验证:B接收到数据以后,先判断文件大小和Content-Type、扩展名等是否符合要求。 去重:去重基本被大多数人忽略,我想是因为对很多网站来说短期内可以承受,但是实际的经验是,重复图片会占到50%以上的惊人比例,一些流行的图片会被不断地上传。而且这里还关系到一个审核的问题,比如一些流行的黄图或者不和谐的政治图片会被频繁上传,如果没有去重机制,会加大审核的工作量。所以,有必要对上传的每个文件取得一个二进制的MD5值,存储到数据库里。这里存入的不是M上的数据库,而是B自带的数据库。上传来的文件,如果MD5重复,就直接返回已经存在的图片路径;如果不重复,就插入新的数据,返回新的路径;如果该图片已经被判定违规,就返回一个错误信号。 处理:生成缩略图,可能是不同分辨率的缩略图。如果有需要,还得添加水印。 存储:存储分三部分:M上的数据库有相册图片相关的信息需要存入;B上的数据库也有文件信息需要存入;最后还得把文件存到C上,才能提供http下载。第一第二步不再叙述,第三步初步决定使用ftp(直接把上传的流写入ftp,B、C通信速度应该很快),也可使用专门的分布式存储系统来实现。路径可设计为 http://域名/分布式目录/20100730(年月日)/1355(时分)/large(不同大小)_(随机码).jpg,把这个路径分解以后存储到M即可。
下载权限控制机制
要对下载的权限进行精确的控制(防止盗链,防止迅雷吸血,下载扣除积分等虚拟货币),以前接触的方法有几种: 1、通过rewrite不断地更改下载文件的url,并插入很多无意义的字符; 2、验证下载链接的来路,或者cookie; 3、通过服务器端程序(例如一个php文件),open文件,读取内容然后返回给客户端。 第一种方法很笨,而且吃力不讨好; 第二种方法很容易破解,因为referer和cookie都是客户端发出的,能够方便地伪造,而且迅雷对此已经是轻车熟路; 第三种方法是可行的有效的,所有的文件都经过一个程序读取并发送,在读取之前可以有效的验证权限,但是下载过程中始终要占用一个cgi线程,而且一般cgi语言的IO性能都不好,速度很慢,占用了服务器的大量资源,导致总体效率极其低下,难以大规模运用。 为此我研究了一下csdn下载频道的实现机制。 csdn下载频道能够有效的验证权限,扣除积分,而且不排斥迅雷等下载客户端,同一个用户下载同一个文件也不会重复扣除积分,而且下载时始终没有暴露文件的真实地址,同一个下载URL到了别的地方也完全不可用,可以说是实现得比较理想的。 我选择了一个文件进行测试,下载的url是: http://dldx.csdn.net/fd.php?i=573624740728082&s=4fc2353ca769a0ebd9237b6f98791679 这个url向文件存储服务器上的fd.php文件发送了两个经过加密的参数,里面应该包含有用户登录信息(用户ID和sid)和目标文件的ID号。 用迅雷下载这个文件,截获返回的头信息: Host: dldx.csdn.net Pragma: no-cache Range: bytes=0- Referer: http://d.download.csdn.net/down/2474072/waf9898 User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; ) HTTP/1.1 206 Partial Content Server: nginx/0.7.65 Date: Tue, 22 Jun 2010 07:08:21 GMT Content-Type: “application/octet-stream; charset=utf-8″ Content-Length: 667747 Last-Modified: Mon, 21 Jun 2010 23:45:02 GMT [...]