基于S2SH的电子商务网站系统性能优化

对于经常逛网页的人来说最受不了的事情就是访问的网页加载太慢,除去网络的原因网站的系统性能对加载的快慢非常重要,

网上有个统计:

        每慢500ms  Google访问量降低20%

        每慢400ms Yahoo 访问量降低5-9%

         每慢100ms Amazon销售额降低1%

对于商务网站来说用户的多少就表示着网站的命运 所以对网站的系统性能的优化格外重要;

假如当网站在一段时间内有10w个用户访问网站的一个商品时, 网站就会和数据库交互10w次  数据库也只是一个应用而已 它存在数据库瓶颈问题 数据库每次只能同时保持大概2000个连接数 所以对于这些访问者来说只有20%的人能很快访问到网页,50%的人在较慢的一段时间内还是能访问到网页的,但剩下的30%的访问者就会收到连接超时的异常

对于这种由于访问数据库的次数太多的解决方案有:

A.页面情态化成html

页面情态化就是将原来的本应该每次都要访问数据库再生成情态html文件返回,而现在就是只生成一次html下次再访问服务器只要访问该html文件就行不用再访问数据库了,对于这个技术对系统的性能提升很大,但是这个技术只能用于不怎么变化的模块:例如像商品的详细介绍页面:

像这种的页面的信息一周甚至一个月都不会变化,将类似这种模块情态化最合适;

实现这个技术的方法是使用模版技术:Velocity 或 freemarket 

    这两种技术都出现了10多年了freemarket比velocity出现的晚几年 声称比velocity功能强大  现在的struts2也使用了freemarket 但是velocity扩展性更好 我这使用的是velocity

基本语法:

1、"#"用来标识Velocity的脚本语句,包括#set、#if 、#else、#end、#foreach、#end、#iinclude、#parse、#macro等;
如:
#if($info.imgs)
<img src="$info.imgs" border=0>
#else
<img src="noPhoto.jpg">
#end

2、"$"用来标识一个对象(或理解为变量);
如:$i、$msg、$TagUtil.options(...)等。

3、"{}"用来明确标识Velocity变量;
比如在页面中,页面中有一个$someonename,此时,Velocity将把someonename作为变量名,若我们程序是想在someone这个变量的后面紧接着显示name字符,则上面的标签应该改成${someone}name。

4、"!"用来强制把不存在的变量显示为空白。
如当页面中包含$msg,如果msg对象有值,将显示msg的值,如果不存在msg对象同,则在页面中将显示$msg字符。这是我们不希望的,为了把不存在的变量或变量值为null的对象显示为空白,则只需要在变量名前加一个“!”号即可。
如:$!msg

使用方法:

1.在http://velocity.apache.com下载velocity-*.rar 解压

可以将velocity-*-dep.jar放带WEB-INF的lib目录下即可 也可以使用velocity-*.jar但是这时要将co'm'mons-connections-*.jar和commons-lang-*.jar和oro-*.jar也加入lib目录下

2.配置velocity的一些属性:

我使用的是在filter中加入相应的配置如:

 1 try{
 2             Properties prop = new Properties();
 3             prop.put("runtime.log", config.getServletContext().getRealPath("/WEB-INF/log/velocity.log"));
 4             prop.put("file.resource.loader.path", config.getServletContext().getRealPath("/WEB-INF/vm"));
 5             prop.put("input.encoding", "GB18030");
 6             prop.put("output.encoding", "GB18030");
 7             Velocity.init(prop);
 8         }catch( Exception e ){
 9             e.printStackTrace();
10         }

file.resource.loader.path   配置的是模版所在的位置 input.encoding ,output.encoding 配置的是相应的输入输出的编码要跟你模版中的编码一样 

3.编写模版生成的代码:我使用的是在商品添加或修改时就生成该商品的html情态文件

这样就能完成向/WEB-INF/vm/product/productview.html这个模版中写入数据
现在来看下模版文件怎么接受数据的吧:
 1 <form action="/shopping/cart" method="post" name="cart">
 2 <INPUT TYPE="hidden" NAME="productid" value="${product.id}" />
 3 <div id="browse_left">
 4  
 5                          <div class="right_left">
 6                          <div class="right_right">                                    
 7                                     <div class="right_title"><b>${product.name}</b></div>
 8                                     <div class="right_desc">
 9                                             <ul>
10                                                 <li class="li2">商品编号:${product.id}<font color="#CC0000">(电话订购专用)</font></li>
11                                                 #if($!{product.brand}) <li>品牌:$product.brand.name</li> #end                                                                                                                                        </ul>
12                                     </div>
13                                     <div class="right_desc">
14                                             #if($product.productStyles.size()==1)
15                                             <INPUT TYPE="hidden" NAME="styleid" value="$product.productStyles.iterator().next().id" />
16                                             <li>颜色:红色</li>
17                                             #else
18                                              <li>颜色:<SELECT name="styleid">#foreach($color in $product.productStyles)
19                                                 <option value="$color.id">$color.name</option>
20                                               #end </SELECT></li>
21                                             #end                                          
22                                     </div>
23                                     <ul>
24                                         <li>市场价:<s>${product.marketprice}</s><font color='#ff6f02'>本站价:<b>${product.sellprice} 元</b></font> 节省:<font color='#ff6f02'>${product.savedPrice}</font></li>
25                                           
26                                     </ul>                                    
27                             </div>
28 </div>
29                             <div id="browse_right"><div id="sy_biankuang">
30                                         <div class="sy_xinpintuijian_font">本站尚未开张</div>
31                                         <div class="sy_dianhua" style="line-height:150%"><font color="#FF0000">
32                                             全国:010-6466 3070</font><br/>MSN在线客服:*****@sohu.com<br/>    
33                                         <font color="#3A8FAF">QQ在线客服:895957140</font></div>
34                             </div></div>
35 </form>

 

${product.name}这样的标签就是显示传过来的product对象的name属性值
重启tomcat服务器后添加一个商品这样关于product的一个情态html文件就生成在根目录下的/WEB-INF/html/product/product的类别id/下面
B.缓存技术
对于页面情态化它只适用于不怎么变化的模块 而像

这样
这样的商品检索页面由于分类不同排序不同所生成的页面用统计就知道太多了不适合使用页面情态化,那么就可以使用缓存技术了
缓存技术有两种:页面缓存和二级缓存
页面缓存的缺点就是不能实时更新,但是性能比二级缓存要好
页面缓存的实现:使用oscache
1.下载相应的包

2.将oscache.proprities文件拷贝到项目的src目录下:里面有一些属性可以配置一下

2.如果你只是缓存一部分网页那么只要使用部分缓存:

部分缓存只要像用标签一样
3.全局缓存:就是将整个页面都缓存起来
使用方法:只要在web.xml中加入一个filter即可
<filter><filter-name>CacheFilter</filter-name><filter-class>com.opensymphony.oscache.web.filter.CacheFilter</filter-class><init-param><param-name>time</param-name><param-value>7200</param-value></init-param><init-param><param-name>scope</param-name><param-value>application</param-value></init-param></filter><filter-mapping><filter-name>CacheFilter</filter-name><url-pattern>/product/list/*</url-pattern></filter-mapping>

 

加人这个filter后所有url中以/product/list/开头的连接即所有的商品列表都将放入缓存中它的key就是相应的URL默认的缓存时间是7200s即2小时 默认的存在范围是Application范围
4.注意的是当添加或修改商品时由于有缓存那么更新信息并不能马上更新在页面上  那么我们应该在更新了的时候更新缓存只要使用上面提到的flush属性就行

B.二级缓存:重点是它能实时更新 

由于我没使用二级缓存使用也不知道效果怎样
C.数据源 :在spring的beans.xm的连接池里面放一些连接对象
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"><property name="driverClass" value="${driverClass}"/><property name="jdbcUrl" value="${jdbcUrl}"/><property name="user" value="${user}"/><property name="password" value="${password}"/><!-- 初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3  --><property name="initialPoolSize" value="1"/><!-- 连接池中保留的最小连接数。 --><property name="minPoolSize" value="1"/>    <!-- 连接池中保留的最大连接数。Default: 15  --><property name="maxPoolSize" value="300"/><!-- 最大空闲时间,60秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0  --><property name="maxIdleTime" value="60"/>    <!-- 当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3  --><property name="acquireIncrement" value="5"/>    <!-- 每60秒检查所有连接池中的空闲连接。Default: 0  --><property name="idleConnectionTestPeriod" value="60"/></bean>

 

这里用的是c3p0作为数据源 要加入c3p0的jar包
D.SSI
经过上面的优化性能上就能提高很多 SSI只能提高一点点 因为SSI指令执行Tomcat外部的JVM能释放Tomcat自己的JVM的压力

配置过程:

1). 先保证 Tomcat 可以运行,即能够正常启动

2). ( 5.x 版本)服务器根目录下边 $TOMCAT_HOME( 或者 $CATALINA_HOME)/server/lib/ 目录下边有一个文件:

servlets-ssi.renametojar ,将这个文件名更名为一个 jar 后缀,当然最方便的方法是直接改掉文件后缀,按照 Tomcat 扫描jar 路径类的原理来讲,直接更名为 jar 应该也是可以的,不过我没尝试过,一般网上最常用的方法是改成: servlets-ssi.jar。( 6.x 版本)服务器不需要去寻找 jar 文件了,直接进入下一步操作都可以。

3). 找到文件: $TOMCAT_HOME( 或者 $CATALINA_HOME)/conf/web.xml ,这里面不需要我们自己写入 SSI Servlet 和SSI Filter 的配置,首先我们要选择使用哪种方式来配置:

Servlet 配置:

  在这个文件里面,找到以下注释代码段,将注释代码段去掉:

Servlet 配置——

<!--<servlet><servlet-name>ssi</servlet-name><servlet-class>org.apache.catalina.ssi.SSIServlet</servlet-class><init-param><param-name>buffered</param-name><param-value>1</param-value></init-param><init-param><param-name>debug</param-name><param-value>0</param-value></init-param><init-param><param-name>expires</param-name><param-value>666</param-value></init-param><init-param><param-name>isVirtualWebappRelative</param-name><param-value>0</param-value></init-param><load-on-startup>4</load-on-startup></servlet>-->

 

ServletMapping 配置——

<!--<servlet-mapping><servlet-name>ssi</servlet-name><url-pattern>*.shtml</url-pattern></servlet-mapping>-->

 

Filter 配置:

Filter 的相关配置——

<!--<filter><filter-name>ssi</filter-name><filter-class>org.apache.catalina.ssi.SSIFilter</filter-class><init-param><param-name>contentType</param-name><param-value>text/x-server-parsed-html(;.*)?</param-value></init-param><init-param><param-name>debug</param-name><param-value>0</param-value></init-param><init-param><param-name>expires</param-name><param-value>666</param-value></init-param><init-param><param-name>isVirtualWebappRelative</param-name><param-value>0</param-value></init-param></filter>-->

 

FilterMapping 相关配置——

<!--<filter-mapping><filter-name>ssi</filter-name><url-pattern>*.shtml</url-pattern></filter-mapping>-->

 

只是 Filter 配置里面还需要取消另外一个注释,下边的 MIME TYPE 的服务器支持相关注释

<!--<mime-mapping><extension>shtml</extension><mime-type>text/x-server-parsed-html</mime-type></mime-mapping>-->

 

   上边的注释取消过后,配置就基本好了,在 Tomcat 5.x 的版本中配置的时候,到这个地步就结束了,但是在 Tomcat 6.x 版本中可能还会出现下边的异常:

   java.lang.SecurityException: Filter of class org.apache.catalina.ssi. SSIFilter (SSIServlet) is privileged and cannot be loaded by this web application

4). 所以正对这点 6.x 还有一个步骤,在 $TOMCAT_HOME( 或者 $CATALINA_HOME)/conf/context.xml 文件中在<Context> 结点添加一个属性 privileged="true" ,然后再启动就不会抛出上边的异常了。

5). 若要解决乱码问题,根据上边文档需要修改 SSI 中的启动参数:添加如下代码:

<init-param><param-name> inputEncoding </param-name><param-value> utf-8 </param-value></init-param><init-param><param-name> outputEncoding </param-name><param-value> utf-8 </param-value></init-param>

 

6)使用方式:
在html文件中就可以加入<!--#include virtual="/WEB-INF/page/share/Head.jsp" -->这样的标签了
转载请注明出处:http://www.cnblogs.com/yixiwenwen/articles/2729079.html

转载于:https://www.cnblogs.com/yixiwenwen/archive/2012/10/18/2729079.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361199.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

玩Java并发

最近&#xff0c;我需要将一些文件&#xff08;每个文件都有JSON格式的对象列表&#xff08;数组&#xff09;&#xff09;转换为每个文件都具有相同数据&#xff08;对象&#xff09;的分隔行的文件。 这是一次性的任务&#xff0c;很简单。 我使用Java nio的某些功能进行了读…

ExtJs的Reader

ExtJs的Reader Reader : 主要用于将proxy数据代理读取的数据按照不同的规则进行解析,讲解析好的数据保存到Modle中 结构图 Ext.data.reader.Reader 读取器的根类 Ext.data.reader.Json JSON格式的读取器 Ext.data.reader.Array 扩展JSON的Array读取器 Ext.data.reader.Xml XML格…

sound

sound类在 flash3.0中算是很常见的功能&#xff0c;也是很常用的&#xff0c;下面 简单的运用了 sound类&#xff0c;加载了一首歌&#xff0c;控制 播放 暂停 停止&#xff0c;和控制音量大小&#xff1b; package {import flash.display.MovieClip;import fl.controls.*;imp…

Java Lambdas和低延迟

总览 有关在Java和低延迟中使用Lambda的主要问题是&#xff1a; 它们会产生垃圾吗&#xff0c;您能做些什么吗&#xff1f; 背景 我正在开发一个支持不同有线协议的库。 这样的想法是&#xff0c;您可以描述要写入/读取的数据&#xff0c;并且有线协议确定它是否使用带有JSon或…

HTTP协议/RTSP协议/RTMP协议的区别

RTSP、 RTMP、HTTP的共同点、区别 共同点&#xff1a; 1&#xff1a;RTSP RTMP HTTP都是在应用应用层。 2&#xff1a; 理论上RTSP RTMP HTTP都可以做直播和点播&#xff0c;但一般做直播用RTSP RTMP&#xff0c;做点播用HTTP。做视频会议的时候原来用SIP协议&#xff0c;现…

2013搜狗校园招聘笔试题

研习了Linux公社发布的2013搜狗校园招聘笔试题&#xff0c;还是有些收获的。 //第一题&#xff1a;以下程序的输出是___________________ class Base { public:Base(int j):i(j){}virtual ~Base(){}void func1(){i * 10; func2();}int getValue(){return i;} protected:virtual…

Java中的线程本地存储

开发人员中鲜为人知的功能之一是线程本地存储。 这个想法很简单&#xff0c;并且在需要数据的情况下很有用。 如果我们有两个线程&#xff0c;则它们引用相同的全局变量&#xff0c;但我们希望它们具有彼此独立初始化的单独值。 大多数主要的编程语言都有该概念的实现。 例如&…

jsp中@import导入外部样式表与link链入外部样式表的区别

昨天碰到同事问了一个问题&#xff0c;impor导入外部样式与link链入外部样式的优先级是怎样的&#xff0c;为什么实验的结果是按照样式表导入后的位置来决定优先级。今天就这个问题具体总结如下&#xff1a; 先解释一下网页添加css样式的方法&#xff0c;一共有四种&#xff0c…

EBS调试

一、在请求中的调试&#xff1a; 1、用系统函数fnd_file.PUT_LINE()&#xff0c;然后在请求的查看日志中就可以看到 例如&#xff1a; fnd_file.PUT_LINE(fnd_file.log, l_customer_type); 其中l_customer_type就是要查看的变量。 2、先建一张表&#xff0c;然后在程序中执行…

Acision推出“ forgeathon” –第一个WebRTC应用挑战

Acision推出了“ forgeathon”&#xff0c;这是 面向全球开发人员的 首个在线丰富网络通信&#xff08;WebRTC&#xff09;应用挑战 加入Forgeathon&#xff0c;让Acision帮助您将应用程序或服务推向全球&#xff01; 英国雷丁– 2015年1月6 日 &#xff1a;安全&#xff0c;…

SQL Server 中的ROWID

在SQL Server中没有像Orcal中的rowid&#xff0c;但是可以运用一定的变通达到这个效果。1、建立临时表&#xff0c;其中包含rowid&#xff0c;2、重命名原表后删除临时表USE TianzxSELECT identity(int,1,1) as rowid,flow.* into temptable from flow--建立临时表&#xff0c;…

jsp中四种传递参数的方法

jsp中四种传递参数的方法如下&#xff1a; 1、form表单 2、request.setAttribute();和request.getAttribute(); 3、超链接&#xff1a;<a herf"index.jsp"?aa&bb&cc>name</a> 4、<jsp:param> 下面一一举例说明&#xff1a; 1、form表…

多个退货单

我曾经听说过&#xff0c;过去人们为使方法具有单个出口点而奋斗。 我知道这是一种过时的方法&#xff0c;从未认为它特别值得注意。 但是最近&#xff0c;我与一些仍坚持该想法的开发人员进行了联系&#xff08;最后一次是在这里 &#xff09;&#xff0c;这让我开始思考。 因…

GO 语言编程 windows 环境搭建

参考 : http://blog.csdn.net/love_se/article/details/7754274 首先是安装Go&#xff0c;这里有很详细的安装说明&#xff0c;http://code.google.com/p/golang-china/wiki/Install 或者http://golang.org/doc/install 下面我们在window下面安装&#xff0c;google有提供win安…

建立代理,而不是框架

自从引入Java注释以来&#xff0c;它已成为大型应用程序框架API的组成部分。 此类API的良好示例是Spring或Hibernate的示例&#xff0c;其中添加了几行注释代码可实现非常复杂的程序逻辑。 尽管人们可以争论这些特定API的缺点&#xff0c;但大多数开发人员都会同意&#xff0c;…

HttpServletRequest.getContextPath()取得的路径

如果项目名称为test,你在浏览器中输入请求路径&#xff1a;http://localhost:8080/test/pc/list.jsp 执行下面向行代码后打印出如下结果&#xff1a; 1、 System.out.println(request.getContextPath()); 打印结果&#xff1a;/test 2、System.out.println(request.getSer…

合理的嵌入式开发学习路线

最近网上好多新手问我&#xff0c;怎么样学习嵌入式开发&#xff1f;其实这个问题很复杂&#xff0c;因为嵌入式开发是个非常复杂的领域&#xff0c;既有深度&#xff0c;也有广度&#xff0c;是个软硬结合的领域。。。我研究的时间也不长&#xff0c;不过以后可能会研究RTOS这…

重点保护

在“ Java的一些句子 ”一文中&#xff0c;我写道&#xff1a; “受保护的方法和字段可以在同一包中的类中使用&#xff08;到目前为止与私有包相同&#xff09;&#xff0c;此外&#xff0c;还可以从其他类中使用受保护的方法和字段&#xff0c;这些类扩展了包含受保护的字段或…

机打发票打印管理

最近公司也从手写发票换成了机打发票&#xff0c;便应财务的要求做了这么一个简单的发票管理及打印系统&#xff0c;程序并不复杂。 使用C#&#xff08;2.0&#xff09; Access&#xff08;97-2003版&#xff09;/WinForm形式 系统菜单中有企业基本信息设置&#xff0c;见图4…

程序员需要了解的一点组织行为学知识

程序员由于天天和逻辑打交道&#xff0c;所以在世故的人眼里往往显得过于简单。 近来看组织行为学&#xff0c;发现其中一节列了很多特别的技能。 考虑到也许他们对程序员群体很有启示意义&#xff0c;就追加了一点说明&#xff0c;把它放在博客里。 相信这对想成为管理者的程序…