自昨日提出图片数据与WEB程序的分离一文之后,已经慢慢的知道了如何去操作了。

=======================================================

原文:  

近段时间,公司的一个网站因为是ASP做的,数据又暴增,一时之间IIS总是阻塞。这又影响到另一个网站,简称网站A(.net做的)的正常运营,访问页总是很慢。而且又要制作另外的一个网站,这些网站全都挂在一台web服务器上,数据库在另外一台服务器上。看了下远程数据库服务器,sqlserver的CPU使用率一直是居高不下。于是,我要对网站A在架构上做一下调整。首先想到的是图片和WEB程序分离,现在网站A的图片都存储在A的根目录下。我想另外在开一个二级图片域名网站,比如http://img.abc.com/,当用户上传图片的时候上传至http://img.abc.com/的目录下,在该目录下按照业务的不同在分别设置新的目录存储图片。

现在提供集中解决方案:

方案一,首先上传至网站A的临时目录中,并且修改图片文件名,然后在利用.NET的IO类将其移动到http://img.abc.com/的相应目录中,并且生成图片路径http://img.abc.com/aaa/aaaaa.jpg存数据库中。

方案二,首先上传至网站A的临时目录中,并且修改图片文件名,然后在利用FTP传至相应目录中,并且生成图片路径http://img.abc.com/aaa/aaaaa.jpg存数据库中。

方案三,直接通过FTP上传至http://img.abc.com/相应目录下,修改文件名,并且生成图片路径http://img.abc.com/aaa/aaaaa.jpg存数据库中。

方案四,等待网友的精彩答案,或者我们可以相互探讨一下在实现这一方案存在的一些难点和缺陷,并且在实施这一方案中需要注意的东西。

==========================================================

网友讨论:

===========================================================

2009-04-15 20:43 | 谢小漫

方案四:
应该是分开
web服务器
img服务器(开放webservices上传接口,提供上传)

用webservices来上传也是可以的,也可以考虑用ftp,搜索一下ftp操作类。

其实楼主的情况应该综合来分析一下。看楼主的文字,好像没有做综合的具体分析。

访问慢,不一定就是img占用了过多的带宽的。
要么就是楼主的公司做图片类相关服务。

最好通过日志分析,图片访问多而占用了过多带宽才考虑分离吧。

考虑一下是不是页面访问也超级多:考虑静态
系统数据极增,web程序的分页等有问题等等。

 

========================================

2009-04-15 23:52 | 谢小漫

ASP网站不是一定要即时的结果的,常用的数据库里边取出来的东西用application做缓存。
不过,asp的程序应该也不是你写的啦。

webservices上传图片的,同时操作者应该也不是太多吧。
如果也考虑的话,remoting吧,并发和速度应该更好一点。
=========================================
你这个问题很具有代表性,其实这个关系到正个网站的架构问题.一个好的架构就是在于能够通过增加硬件服务器的方式来解决站点的资源空间.
我提下我的经验,大概也是比较流行的趋势把。

1)服务器设置:首先应该把放程序的Web服务器和存放动态增加的资源Image服务器单独分开,有条件的话应该是DB Server也是单独的服务器.这样对以后的分流也是一个好的奠基.(所以应该至少是3台服务器: Web+Image+DataBase)
2)在程序中做配置,所有用户上传的资源全部存储在Image存储服务器上.这样在访问时,可以通过http://imag01.*.com/*方式访问,以后如果一台Image存储器容量满了的话,只要再增加一个存储器就好了,再重新增加一个http://image02.*.com/方式访问就好了.
3)程序的实现思想: 你应该要写个配置(XML或直接写数据库),这个配置主要是要记录2个对称的路径,分别是image服务器上的URL路径和Path物理路径.
  我用XML配置为例如(然后在HttpModule时先通过程序把如下XML内容读到事先定义好的2个数组中,假设数组名分别为m_ArrayImgURL[],m_ArrayImgDir[]):
  <ImgWebServer nodelevel="array" key="ImgWebServer" prefix="" datatype="string">
        <Item value="http://image01.*.com/" />
<Item value="http://image02.*.com/" />
  </ImgWebServer>
  <ImgFileServer nodelevel="array" key="ImgFileServer" prefix="" datatype="string">
        <Item value="\\192.168.1.101\e$\image01\" />
<Item value="\\192.168.1.102\d$\image02\" />
  </ImgFileServer>
这样的话,以后如果增加存储器,直接增加XML内容就好了
4)其次,很重要的是,所有被存放到image存储器中的资源(如:图片,视频,音频等)都要在数据库表中用一个字段记录下,是被存储在哪个image服务器上的.假设某个图片上传以后是被存放在\\192.168.1.101\e$\image01\上的话,那就可以把对应的字段用0记录,这样的话在要读的时候直接读m_ArrayImgURL[0]和m_ArrayImgDir[0]就可以了,就能读出URL地址和物理地址了.

不知道你能否看明白,其实一个好的站点架构有很多的经验积累.慢慢积累把.

希望对你有帮助.

===============================================================

是涉及到架构问题的。
其实目前网站的图片存储是放在网站的根目录/UpImg/目录下的,而且,不同业务的上图图片都存在该目录中。这样,随着时间的推移,很不利于以后不同业务的发展。而且,现在想要把不同业务的图片分开,的确是有点困难了。要么就是将远程数据库附加到本地,然后通过数据库里相关的图片字段将网站的图片采集到本地分开,然后在上传至图片服务器中。
其实我的思路是,可以在数据库中设置一个图片URL+图片文件名,当一台图片服务器(http://img1.abc.com)容量不够时候,增加另一台图片服务器(http://img2.abc.com)。程序中可以设置当前图片上传的服务器是哪一台。当WEB中要显示图片的时候直接读取图片的URL。并且图片服务器加入防盗链等功能。
至于图片上传的功能,程序中已经做好指定用户上传的服务器。可以通过FTP上传或者web service或者Remoting上传。在这功能中也要做好安全的措施。
谢谢 为生活忙碌  的解答。

================================================================

"数据库中设置一个图片URL+图片文件名"
你这样的话,其实只是记录了URL地址,以后,如果你的业务改变,需要程序对物理文件做处理时,就会有问题.因为你没有准确的物理地址,只能是替换URL部分内容.
包括对垃圾资源清理都不是很人性化.

而且,假设现在某个用户上传的图片被放到image01上,过2年,用户对这个图片做修改覆盖等操作时,恰好image01早就满了,已经开始用image02了,那就会出现一些不必要的问题.

具体,你根据业务确定,我也只是一个建议.

=================================================================

可是,你刚提的那个意见,虽然物理路径存在。假设他这个图片最先是存在D盘的。然后过了一段时间,D盘空间剩余1个G,不想再往里面写任何数据了。所以现在已经往E盘写入图片数据了。2年之后,用户对这个图片做修改覆盖等操作时,发现,这是上传的这张图片很大,好像也默认传到了D盘吧,可是D盘已经不能往里面传数据了。是否可以在程序里设置,检测D盘已经不能写任何东西了,转移至E盘,然后把对应的字段修改成1.或者可以将图片的PATH路径也写入数据库,只是这样一来,有点数据冗余了。

=================================================================

=================================================================

我不仅在博客园上探讨,而且也去了csdn上。呵呵,这两个站我都喜欢。

其实,当初接手网站的时候,考虑的以后业务的扩展,是想到用web service上传图片的,但是,这样一来在服务器上要部署,不是很方便,所以用了FTP上传。但是发现,现在真的很不行,因为频道太多,不能把所有的图片都归类在网站A的根目录下。只能重新架构图片服务。