基于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,一经查实,立即删除!

相关文章

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格…

Java Lambdas和低延迟

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

Java中的线程本地存储

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

多个退货单

我曾经听说过&#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安…

机打发票打印管理

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

序列化的概念

讨论了为什么Optional不可序列化以及如何处理&#xff08;即将推出&#xff09;之后&#xff0c;让我们仔细看看序列化。 总览 这篇文章介绍了序列化的一些关键概念。 它尝试精简地执行此操作&#xff0c;而不会涉及太多细节&#xff0c;包括将建议降至最低。 它没有叙述&…

Java飞行记录器(JFR)

JFR是Java分析器&#xff0c;它使您可以研究代码的运行时特征。 通常&#xff0c;您将使用探查器来确定代码的哪些部分导致大量内存分配或导致消耗过多的CPU。 有很多产品在那里。 过去&#xff0c;我使用过YourKit&#xff0c;OptimizeIt&#xff0c;JProfiler&#xff0c;Ne…

图像识别SLIC、Haralick texture features(自备)

SLIC 简单线性迭代聚类(SLIC ),它采用k-means聚类方法来有效地生成超像素。 SLIC超像素分割详解&#xff08;一&#xff09;&#xff08;二&#xff09;&#xff08;三&#xff09;_超像素分割 样本-CSDN博客 超像素分割 & SLIC算法 & 使用示例_slic分割算法matlab-C…

浏览器中的JavaFX

浏览器中的JavaFX屏幕截图 最近&#xff0c;Carl Dea和我启动了一个新项目&#xff0c;将JavaFX 8引入浏览器。 今天&#xff0c;我想介绍我们创建的前两个概念验证&#xff0c;以查看该想法是否完全可行。 对于不耐烦的人&#xff0c;这里是到PoC的链接。 但请注意&#xff0…

MDB!= JMS,反之亦然

基本 消息驱动Bean&#xff08;又称为MDB&#xff09;只是另一个EJB&#xff0c;如无状态&#xff0c;有状态或单例。 使用MessageDriven批注指定。 MDB用于异步消息处理 它们与无状态EJB 相似 &#xff0c;因为它们都是由EJB容器池化的 但是&#xff0c;它们与无状态EJB不同…

周三的工作 张孝祖

今天的任务是主面板master嘿嘿 上头有几个按钮&#xff0c;登录登出&#xff0c;个人信息&#xff0c;注册注销等&#xff0c;他们是根据用户是否等率决定的 具体代码如下 using System; using System.Collections.Generic; using System.Linq; using System.Web; using System…

CSS 垂直居中

1、使用绝对定位垂直居中 绝对对位原理&#xff1a;元素在过度受限情况下&#xff0c;将margin设置为auto&#xff0c;浏览器会重算margin的值&#xff0c;过度受限指的是同时设置top/bottom与height或者left/right与width。 .absolute_center{/*display:none;*/position:absol…

[ExtJs6] 环境搭建及创建项目

1. 环境搭建 sencha cmd 和 extjs6 sdk.sencha cmd: https://www.sencha.com/products/extjs/cmd-download/extjs6: https://www.sencha.com/sencha cmd 安装过程将其加入系统的环境变量path中。export PATH${PATH}:/Users/shuanggai/bin/Sencha/Cmd/6.2.2.36把改语句添加到 ~/…

通过Spring Integration和RabbitMQ获得高可用性的AMQP支持的消息通道

Spring Integration消息通道默认情况下将消息存储在内存中。 这是因为内存速度快&#xff0c;易于实现&#xff0c;并且不会增加网络成本。 但是&#xff0c;在某些情况下&#xff0c;这可能会引起问题&#xff0c;因为如果应用程序崩溃或服务器意外关闭&#xff0c;所有消息都…

vue之node.js的简单介绍

一、什么是node.js&#xff1f; 它是可以运行JavaScript的服务平台&#xff0c;可以吧它当做一门后端程序&#xff0c;只是它的开发语言是JavaScript 二、安装 1、node.js的特性&#xff1a; - 非阻塞IO模型- 时间驱动 2、运用的场景&#xff1a; - 高并发低业务- 实时场景- 聊…

jQuery之jQuery扩展和事件

一、jQuery事件 常用事件 blur([[data],fn]) 失去焦点 focus([[data],fn]) 获取焦点&#xff08; 搜索框例子&#xff09; change([[data],fn]) 当select下拉框中的元素发生改变的时候触发change事件(select例子) click([[data],fn]) 点击 dblclick([[data],fn])…

JavaFX列表示例

这是使用JavaFX构建的示例列表应用程序。 该应用程序是待办事项列表。 此应用程序具有添加&#xff0c;更新和删除列表中项目的功能。 列表数据存储在HSQLDB关系数据库中。 该应用程序使用JDBC&#xff08;Java数据库连接&#xff09;API访问数据库。 该应用程序打包为可执行JA…

flex弹性布局操练2

上一个是练习的1个内元素的&#xff0c;这次练习两个元素的。 ul.box1 {list-style:none;background-color:black;display:flex;justify-content:space-between;/*水平轴的位置,默认是flex-start就是第一种情况*/align-items:center;/*垂直轴的位置*/width:100px;height:100px;…

Selenium1 Selenium2 WebDriver

内容摘要&#xff1a; Selenium 1 原理WebDriver WebDriver 组件WebDriver 协议 Remote End 处理流程Commands & Endpoints & 请求路由错误消息 WebDriver 配置 Selenium 2 1、Selenium 1 原理 (1).测试用例&#xff08;Testcase&#xff09;通过Client Lib的接口向Se…