Welcome 微信登录

首页 / 软件开发 / JAVA / Java Web前端的高性能

Java Web前端的高性能2013-09-17 魏 强, 王 芹华 引言

在前端优化的第一部分中,主要讲解了对静态资源的一些优化措施,包括图片压缩、CSS Sprites 技术、 GZIP 压缩等。这一部分,本文将讲解前端优化里重要的 Flush 机制、动静分离、HTTP 持久连接、HTTP 协议灵活应用、 CDN 等。结合这些技术或思想,相信会使 Java Web 应用程序的性能更上一层楼。

Flush 机制的使用

实际上 在 Web 技术中,Flush 机制并不新鲜,它的思想是无需等到网页内容全部加载完毕,一次性写回客户端,而是可以部分逐 次的返回。如果网页很大的话,一次性写回全部内容显然是个不明智的选择,因为这会造成网页的长时间空白。Flush 机制 允许开发人员将网页的内容按文档流顺序逐步返回给客户端,这样可以使得用户知道我们的系统正在工作,只是等待的时间 稍长而已,这样用户也会“心甘情愿”的等下去。Flush 机制是一个经典的提高用户体验的方法,至今也一直在用。如果网 页很大,这个机制也是建议使用的。在 Java Web 技术中,实现 Flush 非常简单,只要调用 HttpServletResponse.getWriter 输出流的 flush 方法,就可以将已经完成加载的内容写回给客户端。

但是是否每 个网页都要使用该技术呢?笔者当然不这么建议。将网页内容加载完毕后再一次性返回客户端也有它的好处。我们知道网络 传输也有最大的传输单元,内容加载完毕后一次性输出就可以最大程度的利用传输的带宽,减少分块,减少传输次数,也就 是说实际上 Flush 机制会增加用户等待时间、增加浏览器渲染时间,但是对于大网页来说,降低这点效率来增强用户体验 ,是值得的。

动静分离

所谓的动静分离,就是将 Web 应用程序中静态和动态的内容分别放在不同的 Web 服 务器上,有针对性的处理动态和静态内容,从而达到性能的提升。本文基于 Java Web 来讲解 Web 优化,而 Java Web 的 主流服务器软件是 Tomcat。让人遗憾的是,Tomcat 在并发和静态资源处理的能力上较弱,这也是 Tomcat 为人诟病的地方 。但是瑕不掩瑜,既然我们选择了 Java Web,那么就应该发挥我们程序员的头脑去想方设法的提高性能。而动静分离就是 其中一种方法,既然 Tomcat 处理静态资源的能力较弱,那就将静态资源的处理任务交给适合的软件,而让 Tomcat 专注于 处理 JSP/Servlet 的请求。

对于静态资源处理的服务器软件,我们可以选择 Nginx,它是一款俄罗斯人开发的软件 ,似乎比 Apache 更加优秀。它支持高并发,对静态资源处理的能力较强,这正是我们想要的不是吗?事实上,动静分离的 方案很多,有人采用 Apache+Tomcat 的组合;也有人使用 Tomcat+Tomcat 的组合,不过两个 Tomcat 分别被放置于不同的 主机,不同的域名。其中 Apache+Tomcat 的方案与 Nginx 的方案原理上是一样的,它们都是基于反向代理,相对于使用 Nginx 配置动静分离,Apache 的配置就显得略微复杂一些。在 Apache 里,mod_proxy 模块负责反向代理的实现。其中核 心配置内容如清单 1 所示,该配置属于本人参与某项目的其中一部分。

清单 1. 动静分离的 Apache 核心配置

<Proxy balancer://proxy>BalancerMember http://192.168.1.178:8080 loadfactor=1BalancerMember http://192.168.1.145:8080 loadfactor=1 </Proxy> NameVirtualHost *:80<VirtualHost *:80>ServerAdmin service@xuanli365.comServerName www.xuanli365.comDocumentRoot /wwwDirectoryIndex index.shtml<Directory /www>AllowOverride AllAddType text/html .shtmlAddType application/x-rar .rarAddHandler server-parsed .shtmlOptions +IncludesNOEXEC</Directory> RewriteEngine on ProxyRequests Off ProxyPass /static/! ProxyPass / balancer://proxy/ ProxyPassReverse / balancer://proxy/ ProxyPreserveHost on</VirtualHost>
从 Apache 官方对 mod_proxy 模块的介绍,我们可以知道 ProxyPass 属性可以将一个远 端服务器映射到本地服务器的 URL 空间中,也就是说这是一个地址映射功能。在清单 1 的配置中,当访问的路径不在 /static/ 下时(!表示非),就转发给后端的服务器(也就是 Tomcat);否则如果是 /static/ 路径就访问本机。例如, 当访问 www.xuanli365.com/static/css/index.css 时,实际处理请求的是 Apache 服务器,而访问 www.xuanli365.com/index.jsp,那么 Apache 会将请求转发到后端的 Tomcat 服务器,实际访问的页面是 http:// 192.168.1.178( 或 145):8080/index.jsp,这就实现了动静分离。在清单 1 的配置中实际也包含了简单的负载均衡 (loadfactor 因子)。

事实上,我们可以随便打开一个大型门户网站来看一下,我打开的是腾讯网站,任意查看其 中两张图片的地址,我发现一个是:http://mat1.gtimg.com/www/iskin960/qqcomlogo.png,而另一个则是: http://img1.gtimg.com/v/pics/hv1/95/225/832/54158270.jpg。可见该网站存放图片资源使用了多个的域名,我们再用 Linux 的 host 命令查看两个域名的 IP 地址,结果如图 1 所示。

图 1. 某网站的动静分离

可以看到,通过查看 IP 地址 ,我们发现这些图片很可能存放在不同的主机上(为什么是很可能?因为一个主机可以拥有多个 IP),而图片内容和网页 的动态内容并不在同一 IP 下,也很可能是动静分离。多个域名在前面也已经提到,可以增加浏览器的并发下载数,提高下 载效率。

本文采用另一种策略对动静分离进行演示,它的大致结构如图 2 所示。

图 2. 本文设计的动静分 离结构