存档

文章标签 ‘网站优化’

各司其职-WebSphere的动静分离

2009年6月5日 hashei 5 条评论

前一篇文章说到了前端优化对响应时间的提升效果,不过要用到这种好处,首先要做的就是让WebSphere个组件各司其职——IBM Http Server处理静态文件,WebSphere Application Server处理动态内容——所谓的“动静分离”。

先了解一下WAS是如何处理静态内容的:

静态内容被返回到用户的方式至少有三种。它们是:

  1. 静态内容通过 WebSphere Application Server 中的 File Serving 功能从 WAR 文件返回(缺省情况)
  2. 静态内容从 Web 服务器返回
  3. 静态内容从 Caching Proxy Server 返回,如从 WebSphere Edge Server(以下称为 Edge Server)产品中的 Caching Proxy Server 返回。

我们来看一个例子,下图中的应用程序是默认安装的BusinessObjects的Crystal Reports Explorer组件:

web speed before Optimization

简洁的页面,却也有415K的内容,本地打开速度为2.3S。接下来我们把静态页面转移到IHS上,看看结果如何。

打开位于 WAR 文件下的 WEB-INF 扩展中的 ibm-web-ext.xmi 文件,编辑或者添加fileServingEnabled=”false”来禁用Application Server 的文件服务功能。同样修改config目录下的ibm-web-ext.xmi 文件(注:应该是在程序打包时就禁用fileServingEnabled功能,修改文件的话注意各个地方的统一)。重启应用。

再次刷新程序首页,发现已无法访问。我们重新生成、传播插件,比较前后的差别,发现

<Uri AffinityCookie=”JSESSIONID” AffinityURLIdentifier=”jsessionid” Name=”/adhoc/*”/>

变为了

<Uri AffinityCookie=”JSESSIONID” AffinityURLIdentifier=”jsessionid” Name=”/adhoc/updatehandler.jsp”/>
<Uri AffinityCookie=”JSESSIONID” AffinityURLIdentifier=”jsessionid” Name=”/adhoc/updatehandler.csp”/>
<Uri AffinityCookie=”JSESSIONID” AffinityURLIdentifier=”jsessionid” Name=”/adhoc/updatehandler2.csp”/>
<Uri AffinityCookie=”JSESSIONID” AffinityURLIdentifier=”jsessionid” Name=”/adhoc/*.jsp”/>
<Uri AffinityCookie=”JSESSIONID” AffinityURLIdentifier=”jsessionid” Name=”/adhoc/*.jsv”/>
<Uri AffinityCookie=”JSESSIONID” AffinityURLIdentifier=”jsessionid” Name=”/adhoc/*.jsw”/>
<Uri AffinityCookie=”JSESSIONID” AffinityURLIdentifier=”jsessionid” Name=”/adhoc/j_security_check”/>
<Uri AffinityCookie=”JSESSIONID” AffinityURLIdentifier=”jsessionid” Name=”/adhoc/ibm_security_logout”/>

原先不管三七二十一的转发,现在Application Server 已经智能地重新生成了插件文件,以便让 Web 服务器服务静态内容。插件文件将 servlet 和 JSP 的动态 URL 传递回到Application Server。现在要做的就是配置Web服务器来对静态的URL加以识别。我把adhoc.war中的静态内容拷贝到了HTTPServer\htdocs下,同时修改httpd.conf文件,添加

Alias /adhoc/ “e:/IBM/HTTPServer/htdocs/adhoc/”

重启Apache,再次访问,首页又出现了,而停止IHS服务器,你会发现页面有开“天窗”,说明访问的静态资源是在Apache上的。于是我开启了IHS的deflate压缩功能,同时加上Expires头部,那么那些经常处理业务的人员,就不用每次都下载重复的图片,重复的CSS了,而且发请求得到304 Not Modified的动作,都会被省略(刷新的时候不会,但点击页面的时候就会少很多request)。

web speed after Optimization

大小从415K缩小到106K,时间减少到1.48S,提升的空间还是很大的。

当然好技术不能滥用,过度的优化也是万恶之源——简单如动静分离也会带来应用发布更新上的不便,在行动前要了解自己现有的性能情况,明确自己的目的,分析自己的网络拓扑,然后规划好详细的优化步骤,确保这些动作都是可以回滚的。在 WebSphere Application Server 中处理静态内容 这篇文章是你动手前所需要好好阅读的。

摘录总结性的一段

在什么情况下您会选择每一个先前所描述的选项呢?您如何权衡每一个解决方案的利弊呢?下面一组指导原则可以帮助您对静态内容作出决定:

  • 如果您在 WebSphere 的安装中性能不成什么问题,那么请不要想那些更复杂的设置。将您的静态内容保存在 WAR 文件中然后让 file serving servlet 服务它们会比较容易且更加节省成本。
  • 如果在 WebSphere 的安装中性能是个问题,那么就请将文件解压缩,这样会提高您站点的整体性能。但是,解除打包与替换静态内容可能影响效率,除非这个过程可以通过使用上面提到的技术来重复。
  • 如果您有性能需要,并且有能力支付这项花费,那么从长远看最好的解决方案是使用高速缓存代理服务器。像 WebSphere Edge Server 这样的产品(包括执行诸如负载平衡、动态(JSP/servlet)高速缓存以及内容管理这样任务的组件)可以提供额外的性能帮助。

http://www.redbooks.ibm.com/Redbooks.nsf/RedbookAbstracts/tips0223.html?Open 这篇tip是说明如何在WebSphere上实施动静分离的。

优化你的前端-《高性能网站建设指南》读后感

2009年6月3日 hashei 没有评论

之前的几篇文章,都是从中间件的角度来思考程序该如何优化。可是我们知道,一个应用的响应时间,除了从中间件接受请求到返回请求之间的处理时间,还包括在网络上传输的时间、浏览器展现的时间。如果你的应用是对Internet提供服务的,就不得不考虑这一层情况,否则中间件、数据库做了大量优化,能承担很大的并发量,却因为前端没有做过优化导致响应时间过长、用户体验变差,那么是相当郁闷的一件事。

我自己也亲身经历过这样的情况。一个OA项目开发完成后需要做性能测试,发现登录的响应速度很慢,loadrunner显示的吞吐率很高,完成的事务数却不多。用TPV查看WebSphere的使用率,发现JVM回收很正常,于是以为瓶颈在数据库查询上,但是数据库查询SQL执行的很快。最后用Firefox启用Firebug插件,不看不要紧,一看吓一跳:首页有8M大。虽然是内网,但也禁不住这么折腾啊。原来是客户上传了一张照片,程序没有做任何处理就在首页作为新闻放出了缩略图,所以网络流量很高,但是完成的登录数寥寥无几。

于是花了两天时间,在路上和中午阅读了一下《 高性能网站建设指南》。本书是由原Yahoo的Chief Performance撰写。书很薄,2个小时就能看完,但是内容却很丰富,15章章章有精彩。除了要修改代码的“减少HTTP请求”、“使用外部和CSS”、“避免CSS表达式”、“使Ajax可缓存”,更多的是不用修改任何代码,只要做一些配置就能享受到的性能提升——“添加Expires头”、“将样式表放在顶部”、“将脚本放在底部”、“精简JavaScript”、“配置Etag”。虽然这些内容似乎网上随处可见,但是原理解释到位,又结合实验数据说明,外加完整的示例代码的文章却不多见。看完这本书,可以让你不仅知其然,更知其所以然。

我的博“聚沙成塔-小哈的记事簿”也根据这些原则做了优化,把图片和CSS的Expires头都设置为了“增加10年”,这样第二次访问我的网页会迅速很多。同时启用了WordPress2.7默认关闭的gzip功能,同时使用了smartoptimizer工具来压缩CSS和JS,这样整个页面的传输量小了近1/3。由此我也能停用了SuperCache插件(其实就俺这些访问量用不着supercache,当时启用也是为了访问速度的考虑),启用Postviews来记录文章访问的情况。就这么简简单单的一些配置,让我的Yslow标准成绩从D提升到了C(还有些优化牵涉到CSS的修改,本人不是很擅长,还有些方面因为是个人博客不能避免的会引用到其它的服务),Small Site or Blog成绩为B。

怎么样,有没有兴趣买来读一读。如果只想具体了解一些的话,可以先看看Yahoo的这篇文章《Best Practices for Speeding Up Your Web Site》,和大牛Fenng《高性能网站建设指南》读后随感

最后附上简单有效的配置,在.htaccess文件中,新加入

<IfModule mod_expires.c>
<FilesMatch “\.(gif|jpg|jpeg|png|swf|css|js|htm?|xml|txt)$”>
ExpiresActive On
ExpiresDefault “access plus 10 years”
</FilesMatch>
</IfModule>
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*\.(js|css))$ smartoptimizer/?$1
<IfModule mod_expires.c>
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*\.(js|css|htm?|xml|txt))$ smartoptimizer/?$1
</IfModule>
<IfModule !mod_expires.c>
RewriteCond %{REQUEST_FILENAME} -f
RewriteRule ^(.*\.(gif|jpg|jpeg|png|swf|css|js|htm?|xml|txt))$ smartoptimizer/?$1
</IfModule>
</IfModule>
<FilesMatch “\.(gif|jpg|jpeg|png|swf|css|js|htm?|xml|txt)$”>
FileETag none
</FilesMatch>

即可添加长期的Expires头,转发js、css被smartoptimizer压缩,关闭Etag。

在根目录的index.php中define(‘WP_USE_THEMES’, true);后添加

if(ereg(‘gzip’,$_SERVER['HTTP_ACCEPT_ENCODING'])){
if(substr($_SERVER['REQUEST_URI'],0,10)!=’/wp-content/uploads/’)
ob_start(‘ob_gzhandler’);
}

wordpress的gzip压缩功能。