利用IIS管理器模拟CDN
CDN(Content Delivery Network,内容分发网络)。其含义,在百度百科上是这么写的:CDN 是构建在数据网络上的一种分布式的内容分发网。CDN 的作用是采用流媒体服务器集群技术,克服单机系统输出带宽及并发能力不足的缺点,可极大提升系统支持的并发流数目,减少或避免单点失效带来的不良影响。。。后面一大堆。
至于它到底写的是什么。我也解释不清楚。其作用简单粗暴地理解就是:加速。举例说明:
使用Chrome上一个网站(在这之前调出开发者工具(F12)):http://www.codeproject.com/
并且在开发者工具中选中“Network”。
然后按下回车进入网站。等待网站加载完毕。然后看到这个Network里面的内容。
有一条极其可耻的红色请求。请求的文件名为:jquery.min.js,类型为Get,状态为(faild),还花费了10.93S。最下面的信息显示总共花费了12.84秒,而这个jquery的请求就花费了10.93s,还失败了。
现在再单击这条红色的请求,来查看详情。
如下图:
看到这个Request URL,发现这条请求是发送到googleapis.com主机的。问题就在这里。谷歌在中国,基本上是被防火墙轰杀至渣的。这条请求根本不能完成正常的响应,导致了花了10.93s还没有响应,最后还请求失败了。
发生这类情况,一般都是在我们访问国外的网站的时候发生的,国内开发者都知道国情,所以要么已经把脚本放在自己的网站下了,或者直接把请求发送到某个CDN服务器上来加载。但是向Codeproject、Stackoverflow等国外网站都直接用googleapis,
所以有这问题。
那么这个问题该如何解决。这时候,CDN技术就可以派上用场了。我这个所谓的CDN,只是一个测验而已,摆不上台面的。自己玩玩就可以了。
那么如何来操作。
下面分两大块来测试。1、不写一行代码;2、用少量的代码控制(.net mvc4)
首先来说第一种:不写一行代码如何来做。
(1)需要的设备:一台服务器(windows),一台客户机(windows)。注意:如果没有服务器,那么只有一台客户机也是可以的,就是一台计算机又当服务器,又当客户机。
(2)服务器(或者客户机)需要去控制面板打开IIS管理,这个不说了。
(3)下载一个jQuery文件。这里有个微软CDN服务器可以下载,打开链接之后,Ctrl+S就行了——http://ajax.aspnetcdn.com/ajax/jQuery/jquery-2.1.4.min.js
(4)原理简介:我们在浏览器输入一个域名(网址),按下回车之后,计算机(windows)做的事情,就是先在本地的一个名叫hosts的文件中查找映射关系。
这个hosts文件的作用就是解析域名,把请求的域名转换成IP。来看一下hosts文件中内容(可以直接用记事本打开,此处使用Notepad++,强烈推荐啊)。如下图:
看到这个文件有很多的注释,这些信息非常有用,建议仔细研读,这里稍作解释。这些注释说的大意就一句话:
本文件用于域名解析,用法:一行只能写一个映射关系,语法是:IP 空格 域名。
也就是说,我们只要像他那样写,在最后追加一行,并保存,比如
127.0.0.1 www.baidu.com
然后去浏访问百度,发现并没有访问到百度。因为域名解析被指向了本地127.0.0.1。
由此可以想到,如果能把这个ajax.googleapis.com域名解析成我们可以访问到的IP不就可以了嘛。于是先确定服务器(或者客户机)的IP地址。我这里的IP地址是局域网IP地址:192.168.1.108。
如果是客户机,比如是自己的计算机,那么可以写127.0.0.1。于是追加到hosts中去:
192.168.1.108 ajax.googleapis.com
接下来,看到光是域名解析做完了是不够的,因为那一段请求非常的长,后面有很多级目录:http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js
那么这时候IIS的功能就要用起来了。首先到服务器中创建好本地目录,注意这个目录的结构要做成:/ajax/libs/jquery/1.6.2/jquery.min.js。如下图:
然后在IIS中添加网站,怎么添加这里不说,添加之后如图:
然后注意,在访问codeproject之前最好做一件事情,就是清空浏览器缓存,否则可能会从缓存中读取,看不到效果。接着来访问网站。
看到这结果,完美加载状态码为200,成功了。然后单击这条查看详情:
我们看到这里多了一个Remote Address,就是我们想要解析到的IP地址,后面的80是默认端口。简直完美运行啊。
这里不得不说明一下,hosts文件应该是不支持端口映射的,我试了很多,像什么冒号+端口,逗号+端口,都不行,去查好像也是说不行,
也就是说我们解析的时候只能使用80端口。而80端口是默认的,所以在hosts文件中不用指明。
那么再来考虑一种情况,不同的网站jquery文件请求版本可能不同。codeproject是1.6.2,stackoverflow的是1.7.1,jquery.com的请求是1.11.2。而我们刚才只有一个1.6.2。
既然这样,那我们会想,我在刚才的文件夹/ajax/libs/jquery/下,多加几个版本文件夹不就行了吗。比如再加一个1.7.1,再加一个1.11.2,然后在这两个文件夹下再各放一个
jquery.min.js。不错,这的确是可以的。这个jquery.min.js文件的实际版本,你可以不跟文件夹对应,你可以全部都是1.6.2,只要外面的文件夹版本写对就行了,但是这样不是很好,
因为有些网站用的1.11.2版本里的特性,而你给他解析加载的实际上是1.6.2,这样就会报错了。所以最好还是对应起来。
接下来说第二种方法,用少量的.net mvc手段来控制。
可以让jquery的实际版本和文件夹写出来的版本号完美对应。
首先用visial studio 2012 update5来创建一个mvc4项目。
如下:
创建完了之后没用的东西全部删除,其中这个script文件夹中放了很多的jquery版本,如图:
好了。然后我们来创建一个控制器,取名为HomeController,写一个Action,取名为Index,如下代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; namespace CDN.Controllers { public class HomeController : Controller { public void Index(object id) { var js = String.Format(@"/Script/jquery-{0}.min.js", id); var temp = Server.MapPath("~" + js); Response.WriteFile(temp); } } }
然后根据http://ajax.googleapis.com/ajax/libs/jquery/1.6.2/jquery.min.js这个请求的特性,来配置一下路由参数。如下代码:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; namespace CDN { public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( name: "Default", url: "ajax/libs/jquery/{id}/jquery.min.js", defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } } }
懂MVC4的人一眼就知道了,如果不懂的,建议先看看mvc4的路由规则,这里不再赘述。这个url,就是根据那条请求特性写的,把版本号用{id}来代替,把请求指向/Home/Index?id=版本号。
于是HomeController中的Index顺利的接收到了请求,再根据id中传过来的版本号找到服务器中相关文件,然后response出去,就可以了。最后发布出来,部署到IIS中。详细过程不赘述。如图:
然后去访问一下,结果跟上面一模一样,这里不截图了。
个人感觉第二种方法好一点,用程序控制版本。不过第一种方法简单粗暴,也是可以的。
模拟CDN就完成了。这里用googleapis来举例,因为用到的还是挺多,所以就用这个了。这种方法自己随便玩玩就行了。毕竟要改hosts,不宜做什么用处。