前文里我讲到了网站静态化的关键点是动静分离,动静分离是让动态网站里的动态网页根据必定规则把不变的资源和常常变的资源区分开来,动静资源作好了拆分之后,咱们就能够根据静态资源的特色将其作缓存操做,这就是网站静态化处理的核心思路。因而可知,网站静态化处理的核心就是动静分离和缓存两大方面,上篇我简单讲述了动静整合的基础知识,本篇将会讲述两大核心之一的动静分离策略,只有把动静分离策略作好了,缓存才能发挥出它应有的效果。css
下面咱们要讨论下动静分离的策略了,一个页面什么内容是动态的,什么内容是静态的,这个咱们到底该如何来区分了?这个问题学问很是大,咱们的标准不一样,最后拆分出来的动静资源就会存在很大的不一样。在本系列开篇里,我提到了什么样的页面是静态页面,什么样的页面是动态页面,我是以一个url的角度定义的,每一个独立的页面都会有一个url,这个url就比如这个页面的门牌号,咱们每次访问这个url时候若是获得的响应页面都是同样的那么咱们就认为该页面是静态页面,若是访问某个url,咱们访问的时间不一样,最后展现的页面也不同那么这个页面就是动态页面,动态页面就是咱们要进行动静分离的载体了,咱们能够看到个人定义实际上是和时间相关的,也就是说访问时间不一样,获得的结果会不一致,因此咱们能够根据时间这个维度分析页面里那些内容是静态的,那些是动态,可是这个划分在实际状况里就会变得很是复杂,下面我就讲讲这个复杂度。html
场景一:假如咱们是一个商户,咱们查询本身网店的交易数据,通常这个交易数据咱们会放置在页面的右下部分,这个部分咱们很天然把它当作动态资源,就算咱们的网店交易量很小,咱们也不敢把这个部分当作静态资源处理。nginx
场景二:咱们网站为了给用户一个友好的体验,会在用户登陆网站后在页面某个地方显示欢迎语,例如:上午好,夏天的森林,欢迎使用咱们的网站!,到了下午,这个欢迎语可能就变成了下午好,夏天的森林,欢迎使用咱们的网站!,那么这块内容咱们应该是当作静态内容仍是动态内容呢?这个就须要思考了。web
场景三:网站页面里会有不少图片,有些图片的确是好久好久都不会发生变化,例如网站的图标,可是有的图片却不一样了,例若有一个星期咱们要为某个商户作营销活动,那么营销图片这块更新后就会有一个星期的有效期,复杂点的话,咱们可能会在营销活动期间在页面的某一块专设给这个商户营销活动的内容区,这个内容区使用一个html片断,可是当营销活动结束了,这个营销的图片可能就要发生变化,营销的内容区可能会被去掉,那么这些东西咱们是当作静态内容仍是动态内容处理了?apache
由上面的场景咱们能够知道,这个动静分离是要讲究策略的,若是策略设计的很差,可能咱们把网站静态化处理后,效果并无达到咱们的预期。其实,我认为动静分离除了以时间维度考虑外,还应该有个维度,就是被拆分的资源是否须要服务端应用加以配合,例如像交易查询这样的动态内容,咱们其实须要服务端程序按照必定的业务逻辑处理请求后从存储层获取数据,那么这种动态资源是无法作静态化处理的,还有一部分资源例如场景三里的图片以及营销的html片断,这些资源写好后在有效时间内是不会发生变化的,那么这块内容虽然时效性可能会有差别,可是它倒是能够在这段时间作静态化处理的,还有种情形就是场景二了,这个场景虽然使用数据须要服务端参入计算,可是计算结果在必定时间范围内是不变的,也就是说结果是能够被缓存的,那么这块的资源也是能够当作静态化资源进行处理的,为何说拆分策略要考虑服务端应用的因素了?由于上面这些场景都是由服务端应用参入的形式所决定,在有效时间里服务端应用不须要参入,或者参入一次后,能够长期保存结果,那么咱们能够把这些资源当作静态资源处理。浏览器
除此以外,服务端应用和结果的密切度也是要当作考虑的因素的。在web开发里,除了须要浏览器处理的,其余技术均可以当作服务端来理解,若是咱们网站使用到了CDN,使用到了静态web服务器例如apache,以及服务端的web容器例如jboss,那么按请求的行进路径,咱们结果处理越早那么网站响应效率也就越高,因此当请求在CDN返回了,那么确定比在apache返回效率高,在apache就返回了确定比jboss返回的效率高,再则服务端的web容器自己由于服务端程序运行要消耗部分系统资源,因此它在处理请求的效率会比CDN和apache差不少,因此当咱们按照动静分离策略拆分出了静态资源后,这个资源能不放在最底层的服务端的web容器处理就不要放在服务端的web容器里处理。缓存
由上所述,咱们再回过头来看看静态web服务器的SSI技术,这个技术使用起来和咱们在服务端使用include相似,可是在SSI使用include必定会比在服务端效率高,由于服务端在整合动静资源时候还会掺杂不少服务端程序处理,所以动静资源的效率就会大打折扣。咱们再看看SSI的include的用法,以下所示:服务器
<!--#include file="info.htm"-->
这个写法是使用页面的注释标签,当静态web容器处理请求时候,它会扫描里面的SSI标签,接着就会处理这个标签的内容,若是找到了资源那么web容器会将资源插入到页面里,若是web没有处理这个SSI标签,那么等结果到了浏览器,这个也就是一个注释而已,不会影响页面的展现,并且SSI标签处理的资源也是很是丰富的,无论这个资源是静态的,仍是动态的,只要获取时候是个完整的资源都能被正常加入到页面里,因此像前面的场景二这种动态的内容也是能够正常处理的。所以场景二,场景三这样的状况均可以使用SSI来解决。SSI的做用固然不只仅只是能够作include操做,它的标签也能够作一些逻辑上的操做,讲述如何使用SSI不是本文的重点,有兴趣的朋友能够去研究下。markdown
不过SSI也有本身的局限性,它的第一个局限就是SSI解析是静态web容器来完成,所以它会消耗web容器的性能,若是SSI使用时候还有必定的逻辑,那么这种性能消耗就会更大,其实我以为更加剧要的是若是静态web容器过渡使用SSI,那么就会把本身变成了一个服务端的web容器,除了会影响到请求处理的效率,它还会下降自身的并发处理能力,因此咱们但愿资源整合策略交给外部服务处理效果会更好些,如是有些大型互联网公司使用ESI技术,ESI技术和缓存关系密切,这个内容我就放到下篇讨论了。并发
本篇最后我要再讲讲CDN的问题,上篇我讲到静态web容器整合动静资源的好处,由此我说若是CDN能够作动静整合,那么就能作到就近处理,这样效果会更高,今天我对这个作法作了一些考证,以为该说法有点不妥,至少我如今的公司没有使用到这样的技术,CDN技术应该由三个步骤组成,首先是解析DNS,找到离用户最近的CDN服务器,接下来CDN要作一下负载均衡,根据负载均衡策略将请求落地到最合适的一个服务器上,若是CDN服务器上就有用户所须要的静态资源,那么这个资源就会直接返回给浏览器,若是没有CDN服务器会请求远端的服务器,拉取资源再把资源返回给浏览器,如此同时拉取的资源也被缓存在CDN服务器上,下次访问就不须要在请求远端的服务器了,CDN存储资源的方式使用的是缓存,这个缓存的载体是和apache,nginx相似的服务器,咱们通常称之为http加速器,之因此成为http加速器是为了和传统静态web服务器区别开来,传统的静态资源服务器通常都是从持久化设备上读取文件,而http加速器则是从内存里读取,不过具体存储的计算模型会根据硬件特色作优化使得资源读取的效率更高,常见的http加速器有varnish,squid。Ngnix加上缓存模块也是能够当作http加速器使用的,无论使用什么技术CDN的服务器基本都是作一个就近的缓存操做,这也就是说CDN是否能够完成SSI操做是值得商榷的,因此前文的说法仍是有点问题的。