電商網站,效能優化
問題:
1)當大型網站系統>10萬人
一個小時內,會跟資料庫互動10萬次(國內有京東,淘寶),這就會出現資料庫瓶頸,每個資料庫最大連線數(socket)2000
在某一段短暫時間內1萬人,會跟資料庫發生1萬次互動,2000-8000【30秒】 5000 3000
2000個使用者很快就可以到頁面
5000個使用者訪問頁面比較慢
還有3000個使用者會提示超時/伺服器出現例外
這是訪問效能的問題,原因是資料庫瓶頸。
解決方案:
1>頁面靜態化
解決方案:使用模板技術(Velocity[9-10年]/Freemarket[5-6年])
2>2>快取技術 (當資料更新比較快,幾秒鐘就更新一次,或者需要實時反映資料變化,或者頁面具有很多種風格,不便於生成靜態頁面。如BBS)
A.頁面快取(view,html程式碼)
缺點:不能做到實時更新,優點:比二級快取效率更高。
在快取的有效期內,顯示的資料是沒有變化的,只有當快取過期以後才會有變化。
頁面快取分為區域性快取和全域性快取,全域性快取是快取整個頁面的html程式碼,頁面快取是快取頁面中的某一塊區域的html程式碼。
快取的範圍:application範圍(所有人都能共享,比如說產品列表顯示)session(只針對某一個訪問者,比如說快取某個使用者的個人資訊)
OSCache預設的範圍是application範圍,可以通過scope屬性來修改。
快取預設的有效時間是3600秒,也就是一小時。可以通過time屬性來修改。
refresh屬性h如果設定為true,則可以強行清楚快取。
key屬性的作用:如果不設定key屬性,就根據使用者輸入的url來做快取,如果使用者輸入的url改變,快取也會改變。oscatche會把所有的值放到一個map中,通過 key value來做判斷。
<body>
<oscache:cache
key= "aaron" scope= "session" time= "15" refresh= "${param.refresh
}" >
<div> <%= new Date()
%>
</div>
</oscache:cache>
<br>
當前時間:<%= new Date()
%>
</body>
人為清除快取<flush/>標籤:
<oscache:flush
scope= "application" />清除application範圍內的所有快取
<oscache:flush
scope= "session" key= "foobar" />清除session範圍內的key為foobar的快取
<oscache:flush
scope= "application" group= "currencyData" />清除application範圍內組名為currencyData的所有快取。
使用oscache實現頁面的全域性快取
<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>
|
快取的key將以請求的uri+查詢字元竄組成,如果你訪問/oscache/index.jsp?name=tt和/oscache/index.jsp?name=ppp將得到兩分快取。
快取在初次訪問頁面時進行,後續的請求將會返回快取中的內容。快取中存放的內容為頁面返回給使用者的html程式碼。
OSCache配置屬性介紹
cache.memory=true指定是否使用記憶體快取,配置預設為true,即使用記憶體快取。
cache.capacity=1000指定快取的容量,預設的容量是無限的,我們可以為他設定快取數量。
如果要使用硬碟快取,我們可以這樣設定:
cache.memory=false
cache.path=d:\\cache(指定快取儲存的路徑,注意:路徑應該採用雙\\符號)
cache.persistence.class=com.opensymphony.oscache.plugins.diskpersistence.DiskPersistenceListener
cache.persistence.class用於設計持久化類
我們既要考慮頁面的數量,也要考慮機器的記憶體,如果記憶體不多的話容易引起記憶體耗盡,系統的效能反而下降。
但是最好還是用記憶體快取,因為速度比較快,一般伺服器的記憶體都大於10g,用於快取產品列表頁面夠了。因為產品列表頁面不會太多,假設我們有幾萬個的話,有一兩個g就夠了。
CacheFilter的實現原理:
1 CacheFilter{
2 doFilter(request,response,chain){
3 String urlpath=req....;
4 if(oscache.contains(urlpath)){
5 String content=OsCache.getKey(urlpath);
6 response.write(content);
7 }else{
8 CacheHttpServletResponseWrapper wrapper=new CacheHttpServletResponseWrapper(response)
9 chain.doFilter(request,wrapper);
10 String content=wrapper.getContent();//獲取伺服器網客戶端輸出的html程式碼
11 OScache.put(urlpath,content);
12 response.write(content);
13 }
14 }
15
16 public CacheHttpServletResponseWrapper entends HttpServletResponseWrapper{
17 private String content;
18 public CacheHttpServletResponseWrapper(HttpServletResponse response){
19 ....
20 }
21 public void write(String content){
22 this.content=content;
23 }
24 public String getContent(){
25 return content;
26 }
27 }
28 }
頁面快取比二級快取快的原因:當請求來之後系統就會交給過濾器,過濾器得到路徑以後就會把快取返回給客戶端。
二級快取要經過action service 和jsp
B.二級快取(model/業務層,domain物件)優點:實時更新
EHCache OSCache jbossCache(分散式快取)
第一步:匯入ehcache的ehcache.jar檔案(hibernate中有)
第二部:在persistence.xml檔案中新增下面配置項:
1 <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
2 <property name="hibernate.cache.use_second_level_cache" value="true"/>
3 <property name="hibernate.cache.use_query_cache" value="false"/>
第三步:在實體類上面標註@Cache(region="cn.aaron.bean.Person",usage=CacheConcurrencyStrategy.READ_WRITE)
第四步:在classpath下面放入ehcache.xml,內容模板如下:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <ehcache>
3
4 <diskStore path="D:\cache" />
5
6 <defaultCache maxElementsInMemory="10000" eternal="false" overflowToDisk="true" 7 timeToIdleSeconds="120" 8 timeToLiveSeconds="180" 9 diskPersistent="false"10 diskExpiryThreadIntervalSeconds="60"/>
11
12 <cache name="cn.aaron.bean.Person" maxElementsInMemory="100"13 eternal="false" overflowToDisk="true"14 timeToIdleSeconds="300"15 timeToLiveSeconds="600" diskPersistent="false" />
16 </ehcache>
注意<cache>節點中的name屬性要和@Cache(region="cn.aaron.bean.Person",usage=CacheConcurrencyStrategy.READ_WRITE)中的region相同
ehcache.xml檔案中各項屬性說明如下:
defaultCache節點為預設的快取策略
maxElementsInMemory 記憶體中最大允許的物件數量
eternal 設定快取中的物件是否永遠不過期
overflowToDisk 把溢位的物件放到硬碟上(對於本例而言,第1001個物件將存放在硬碟上)
timeToIdleSeconds 指定快取物件空閒多長時間會過期,過期的物件會被清除掉
timeToLiveSeconds 指定快取物件總的存活時間
diskPersistent 當jvm結束時是否持久化物件
diskExpiryThreadIntervalSeconds 指定專門用於清除過期物件的監聽執行緒的輪詢時間
3>資料來源 連線池裡面放一些連線物件
每次都能跟資料庫建立連線socket(client)----socket(資料庫)
4>SSI 對效能提升不是那麼明顯(有一點點作用)
Server Side Include, 通常稱為“伺服器端包含”技術。
使用了SSI技術的檔案預設的字尾名為.shtml,SSI技術通過在html檔案中加入SSI指令讓web伺服器在輸出標準HTML程式碼之前先解釋SSI指令,
並把解釋完成後的輸出結果和HTML程式碼一起返回給客戶端。
在大部分專案中,我們主要使用了SSI的包含指令<!-#include virtual="global/foot.jsp"-->,
他的作用類似於JSP中的<jsp:include page="/global/foot.jsp"/>標籤。
使用SSI主要有如下兩點優勢:
1 SSI技術是通用技術,它不受限於執行環境,在java,.net,CGI,ASP,PHP下都可以使用SSI技術
2 解釋SSI指令的效率比解釋JSP的效率快很多,因為Servlet規範提供了太多的功能,這些功能都需要servlet引擎進行解釋,所以效率比較低。
在目前,大部分的入口網站都是用SSI技術,解釋SSI檔案最佳的伺服器是Apache HTTP Server。
大型入口網站基本都使用這個來解釋SSI檔案。
配置實用SSI
目前主流的web伺服器都提供SSI實現,我們只需要開啟SSI功能就可以使用。
tomcat也可以,但是並不會提高效能,因為使用的還是servlet引擎 .