将动态内容静态化
在动态内容缓存技术的实现机制中,虽然避免了可观的重复计算,但是每次还都需要调用动态脚本解释器来判断缓存是否过期以及读取缓存,这似乎有些多余,而且关键是消耗了不少时间。直接让浏览器访问这些动态内容的缓存不是更好吗?在这种情况下缓存成为直接暴露给前端的HTML网页,而整个缓存控制机制也发生了根本的变化,我们普遍称它为静态化,静态网页独立了,当家做主了,再也不用被脚本解释器呼来唤去。
独立意味着要承担更多的责任,原本动态内容缓存涉及的那些问题,在静态化实践中是否也会出现呢?让我们在后续章节中详细探讨。
优化数据库
对于使用数据库的Web站点来说,你是否在性能优化时或多或少地忽视了数据库的存在?往往一些性能问题可能都发生在表现不佳的数据访问层面,这来源于不合理的应用程序数据访问组件设计、不合理的数据库表结构设计以及对于数据库内部构造缺乏深入的了解。毫不夸张地说,也许你之前的优化全都白干了。
Web服务器与数据库服务器的数据通信一般基于标准的TCP,即便它们位于同一台物理主机也是如此。其通信连接的建立和释放涉及代表一段内核高速缓冲区的文件描述符的创建和销毁,这需要不少的时间开销,包括系统调用导致的内核态切换以及某些异步阻塞I/O模型采用的文件描述符队列扫描机制。所以,频繁的数据库连接和释放无疑将导致数据访问等待时间的加长,这段时间浪费得毫无意义。
使用数据库持久连接有效地解决了这一难题,它包括不同程度上的持久化,本质的区别在于持久连接的应用范围和生命周期,比如某个进程内部的全局数据库连接,供进程内所有计算任务共享,在这个进程终止后便被释放;或者在某个动态内容的执行周期内,代码层面的持久连接对象,在动态内容计算结束后便不复存在;还有跨进程的数据库连接池,保存多个持久连接供应用程序重复使用。在这些采用数据库持久连接的应用设计中,同时还要注意保证数据访问的线程安全性。
与此同时,在设计关系数据库的表结构时,你是否合理使用了各种类型的索引呢?要做到这一点,你必须了解索引的有关知识,然而更重要的是如何根据Web站点变幻莫测的数据访问特点来有针对性地设计每个表的索引,这往往也是最有难度的,索引的合理使用对于依赖数据库访问的Web应用至关重要。
另外,你了解数据库存储引擎的特性吗?其实这并不困难,因为所有的主流数据库文档中都有详细介绍,但是究竟你的Web站点应该选择什么存储引擎呢?当然,没有绝对完美的方案,我们在这个世界上要做的唯一的事情就是不断进行取舍,像考虑索引一样去弄清楚存储引擎的本质,是绝对不会让你失望的。
随着时间的推移,你的Web站点可能逐渐被数据库绑架,单台数据库服务器再也无法应付整个站点的需要,这包括存储空间以及查询时间,人们开始抱怨数据库模型的不良设计制约了横向扩展以及负载均衡,这不是我们希望看到的结果。为此,我们将数据散列在多台主机,包括必要的冗余数据,以此来合理地分散数据库的密集访问,数据库扩展便成为我们考虑的方案。
减少视觉等待
实在不行就给用户一些提示吧!最后我只能这么说了,事实上,这不是什么大不了的事情,即使认识到架构的瓶颈并投入大量人力来改善,也不是一天两天就可以完成的,要意识到用户也许只是希望你不要不理他而已。
这部分显然已经超出了本书的讨论范围,它涉及人机交互的相关知识,并且充满着人文情怀,要真正做好它,恐怕要比本书中所有的问题都更有难度和挑战性,这毫不夸张,我们要承认这个现实,因为世界上最难的学问就是研究人,你觉得呢?
页面组件分离
从某种角度看,中学校园里的快慢分班似乎合乎逻辑,虽然不一定合乎情理。快班的学生学习能力强,理解知识快,那么课程安排的节奏可以加快一些;慢班的学生则可以放缓课程安排的节奏,这样既互不影响,学校的升学率又可以得到保证,当然假设的前提是学生之间互相帮助效果不大。
在Web站点中,网页和各种各样的组件是否也需要"分班"呢?显然它们的下载量和对服务器的能力要求不尽相同,如果由同一台物理服务器或者同一种并发策略的Web服务器软件来统一提供服务,那势必造成计算资源的浪费以及并发策略的低效。所以,分离带来的好处是显而易见的,那就是可以根据不同组件的需求,比如下载量、文件大小、对服务器各种资源的需求等,有针对性地采用不同的并发策略,并且提供最佳的物理资源。
当然,如果你的站点基本无人问津,而且服务器的各种资源大量闲置,那么自然不存在什么性能问题,也不需要什么组件分离。但是如果你的站点负载已经让你意识到组件分离是大势所趋,那还是趁早动手。
那么,什么组件需要分离?如何分离?幸运的是,这些并不困难,但是其涉及的知识绝对不仅仅是组件分离本身,在后续章节中我们将会详细探讨。
|