電商網站,性能優化


問題:

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文件中添加下面配置項: 

View Code
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,內容模板如下: 

 

View Code
 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引擎 .

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM