近段时间,公司的一个网站因为是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存数据库中。方案四,等待网友的精彩答案,或者我们可以相互探讨一下在实现这一方案存在的一些难点和缺陷,并且在实施这一方案中需要注意的东西。

解决方案 »

  1.   

    其实我也觉得方案三的效率比较高,毕竟图片只转移一次就够了。
    也想过使用web service上传图片,怕服务器承受不了。呵呵。
      

  2.   

    你这个问题很具有代表性,其实这个关系到正个网站的架构问题.一个好的架构就是在于能够通过增加硬件服务器的方式来解决站点的资源空间. 
    我提下我的经验,大概也是比较流行的趋势把。 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地址和物理地址了. 不知道你能否看明白,其实一个好的站点架构有很多的经验积累.慢慢积累把. 希望对你有帮助.
      

  3.   

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

  4.   

    "数据库中设置一个图片URL+图片文件名"
    你这样的话,其实只是记录了URL地址,以后,如果你的业务改变,需要程序对物理文件做处理时,就会有问题.因为你没有准确的物理地址,只能是替换URL部分内容.
    包括对垃圾资源清理都不是很人性化.而且,假设现在某个用户上传的图片被放到image01上,过2年,用户对这个图片做修改覆盖等操作时,恰好image01早就满了,已经开始用image02了,那就会出现一些不必要的问题.具体,你根据业务确定,我也只是一个建议.
      

  5.   

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

  6.   

    或者可以将图片的PATH路径也写入数据库,只是这样一来,有点数据冗余了。
      

  7.   

    检测D盘已经不能写任何东西?
    这个问题,我忘记在上面说了,其实在XML文件里多一个配置就好了
    如:<ImgIndex nodelevel="const" key="ImgIndex " value="0" prefix="" isprefixtag="0" datatype="int" />
    这个就是用来记录当前实际存储时,用到那个存储器了.当image01满了的话,把value改成1就变成image02开始存储了,以后所有的用户上传都保存在image02里.具体使用:
      string ImgDir=m_ArrayImgDir[ImgIndex];
    就可以了.
      

  8.   

    恩,是的,你的这种方案效率应该很高,而且在图片读取上,我还做了图片客户端缓存的处理,现在打开网站的速度有了明显的提高,毕竟入库的是整型数字,而不是一串字符串。因为,对于先前的ASP网站,到处都是like查询,我是怕了。毕竟这些网站都不是出自我手。
      

  9.   

    ASP.NET 3.5(1)第一群47448683 ,创群三年,刚刚清理,留上的都算得上是高手,现招人!
    群里肯定有人能解决您的问题!
      

  10.   

    如果以后不再增加图片了,可以用方案三,如果以后还要继续上传图片,建议单独在img.abc.com上面做一个专门的图片上传页面来负责图片的上传。