高并發(fā)解決方案之采用FreeMarker實(shí)現(xiàn)網(wǎng)頁靜態(tài)化

摘要

眾所周知,隨著網(wǎng)站的訪問量增加,如何給用戶以良好的訪問體驗(yàn)就顯得尤為重要。如何提高并發(fā)數(shù)便成為一個(gè)難題,像hao123這樣的導(dǎo)航網(wǎng)站要解決高并發(fā)的問題只要部署的web服務(wù)器數(shù)量足夠就可以承載超大規(guī)模的并發(fā)訪問量,如果是一個(gè)動(dòng)態(tài)的網(wǎng)站呢?例如像鳳凰新聞、網(wǎng)易新聞這樣的CMS系統(tǒng),淘寶、京東這樣的大型購物網(wǎng)站由于這些網(wǎng)站都使用到了數(shù)據(jù)庫這也就很難做到單純的通過增加web服務(wù)器數(shù)量的方式來有效的增加網(wǎng)站并發(fā)訪問能力了,但是這些高并發(fā)的網(wǎng)站并沒有出現(xiàn)或者說極少出現(xiàn)因?yàn)樵L問量大而造成頁面響應(yīng)緩慢的問題。這其中有什么樣的技術(shù)手段使得這些大型的動(dòng)態(tài)網(wǎng)站能夠支撐起高并發(fā)的場(chǎng)景了?目前高并發(fā)的解決方案通常有HTML靜態(tài)化、圖片服務(wù)器分離、數(shù)據(jù)庫集群、負(fù)載均衡等幾個(gè)方案。本文將通過具體案例講解如何采用FreeMarker將動(dòng)態(tài)網(wǎng)頁靜態(tài)化從而達(dá)到大型網(wǎng)站解決高并發(fā)的問題。

關(guān)鍵字:FreeMarker、高并發(fā)、靜態(tài)化。

文章組織結(jié)構(gòu)

一.動(dòng)態(tài)網(wǎng)頁與靜態(tài)網(wǎng)頁差異

二.FreeMarker簡(jiǎn)介

1.FreeMarker表達(dá)式

2.FreeMarker常用指令

三.FreeMarker與SpringMVC整合

四.FreeMarker實(shí)現(xiàn)網(wǎng)頁靜態(tài)化

總結(jié)

一、動(dòng)態(tài)網(wǎng)頁和靜態(tài)網(wǎng)頁差異

在進(jìn)入主題之前我先介紹一下什么是動(dòng)態(tài)網(wǎng)頁,動(dòng)態(tài)網(wǎng)頁是指跟靜態(tài)網(wǎng)頁相對(duì)應(yīng)的一種網(wǎng)頁編程技術(shù)。靜態(tài)網(wǎng)頁,隨著HTML代碼的生成,頁面的內(nèi)容和顯示效果就不會(huì)再發(fā)生變化(除非你修改頁面代碼)。而動(dòng)態(tài)網(wǎng)頁則不然,頁面代碼雖然沒有發(fā)生變化,但是顯示的內(nèi)容卻是可以隨著時(shí)間、環(huán)境或者數(shù)據(jù)庫操作的結(jié)果而發(fā)生相應(yīng)的變化。簡(jiǎn)而言之,動(dòng)態(tài)網(wǎng)頁是基本的HTML語法規(guī)范與java、VB、VC等高級(jí)程序設(shè)計(jì)語言、數(shù)據(jù)庫編程等多種技術(shù)的融合,以實(shí)現(xiàn)對(duì)網(wǎng)站內(nèi)容和風(fēng)格的高效、動(dòng)態(tài)和交互式的管理。

通過前面的介紹我們可以得出動(dòng)態(tài)網(wǎng)頁和靜態(tài)網(wǎng)頁的優(yōu)缺點(diǎn)(這里我們只考慮并發(fā)性相關(guān)問題,信息安全等多方面問題不做贅述):

1、靜態(tài)網(wǎng)頁:

a、靜態(tài)網(wǎng)頁的內(nèi)容穩(wěn)定,頁面加載速度快。

b、靜態(tài)網(wǎng)頁的沒有數(shù)據(jù)庫支持,在網(wǎng)站制作和維護(hù)方面的工作量較大。

c、靜態(tài)網(wǎng)頁的交互性差,有很大的局限性。

2、動(dòng)態(tài)網(wǎng)頁:

a、交互性好。

b、動(dòng)態(tài)網(wǎng)頁的信息都需要從數(shù)據(jù)庫中讀取,每打開一個(gè)一面就需要去獲取一次數(shù)據(jù)庫,如果訪問人數(shù)很多,也就會(huì)對(duì)服務(wù)器增加很大的荷載,從而影響這個(gè)網(wǎng)站的運(yùn)行速度。

通過上面的比較我們不難看出,要解決高并發(fā)問題,我們只需要把動(dòng)態(tài)網(wǎng)頁做成靜態(tài)網(wǎng)頁就可以了,但是問題出來了,如果將所有頁面都做成靜態(tài)頁面顯然是不切實(shí)際的。有什么辦法能讓我們的網(wǎng)站即能有動(dòng)態(tài)網(wǎng)頁的交互性,又有靜態(tài)網(wǎng)頁的加載速度呢?FreeMarker便能實(shí)現(xiàn)這樣的需求:實(shí)現(xiàn)動(dòng)態(tài)網(wǎng)頁靜態(tài)化。

二、FreeMarker簡(jiǎn)介

FreeMarker是一個(gè)基于Java的開發(fā)包和類庫的一種將模板和數(shù)據(jù)進(jìn)行整合并輸出文本的通用工具,其工作原理如圖2-1所示。

圖2-1FreeMarker工作原理圖

1、FreeMarker表達(dá)式

表達(dá)式可以說是FreeMarker的核心功能,表達(dá)式放置在插值語法“${...}”之中時(shí),表面需要輸出表達(dá)式的值,表達(dá)式語法也可以與FreeMarker標(biāo)簽結(jié)合,用于控制輸出。

1)直接指定值

例如:${“zhangsan”}

2)輸出變量值

FreeMarker的表達(dá)式輸出變量時(shí),這些變量可以是頂層變量,也可以是Map對(duì)象中的變量,還可以是集合中的變量,并可以使用點(diǎn)(.)語法來訪問Java對(duì)象的屬性,例如:${user.name}。

3)字符串操作

a、字符串的連接,字符串的連接可以直接使用云算符“+”來連接字符串也可以使用${..}(或#{..})在字符串常量部分插入表達(dá)式的值,從而完成字符串連接。

b、字符串的截取,${book[1..4]}

4)集合連接運(yùn)算符,這里所說的集合連接運(yùn)算是將兩個(gè)集合連接成一個(gè)新的集合,連接集合的運(yùn)算符是“+”,例如:

5)Map連接運(yùn)算符,Map對(duì)象的連接運(yùn)算也是將兩個(gè)Map對(duì)象連接成一個(gè)新的Map對(duì)象,Map對(duì)象的連接運(yùn)算符是+。如果兩個(gè)Map對(duì)象具有相同的key,則后加入Map里的key所對(duì)應(yīng)的value替代原來key所對(duì)應(yīng)的value

6)算術(shù)運(yùn)算符,F(xiàn)reeMarker表達(dá)式中完全支持算術(shù)運(yùn)算。FreeMarker支持的算術(shù)運(yùn)算符包括:+,-,*,/,%

7)比較運(yùn)算符,F(xiàn)reeMarker表達(dá)式中支持的比較運(yùn)算符有如下幾個(gè)

a、=(或者==):判斷兩個(gè)值是否相等.

b、!=:判斷兩個(gè)值是否不相等

c、>(或者gt):判斷坐標(biāo)值是否大于右邊值

d、>=(或者gte):判斷坐標(biāo)值是否大于等于右邊值

e、<(或者lt):判斷左邊值是否小于右邊值

f、<=(或者lte):判斷左邊值是否小于等于右邊值

8)邏輯運(yùn)算符,F(xiàn)reeMarker中的邏輯運(yùn)算符有如下幾個(gè):

a、邏輯與:&&

b、邏輯或:||

c、邏輯非:!

9)內(nèi)建函數(shù)

FreeMarker提供了一些內(nèi)建函數(shù)用來轉(zhuǎn)換輸出,可以在任何變量后緊跟?,?后緊跟內(nèi)建函數(shù),就可以通過內(nèi)建函數(shù)來轉(zhuǎn)換輸出變量,例如:${test?upper_case?html}這里就是將test字符串轉(zhuǎn)換為大寫并進(jìn)行HTML編碼。

10)空值處理運(yùn)算符

FreeMarker對(duì)空值的處理非常嚴(yán)格,F(xiàn)reeMarker的變量必須有值,如果存在沒有賦值的變量就會(huì)拋出異常,為了處理缺失變量FreeMarker提供了兩個(gè)運(yùn)算符:“!”和“??”,其中“!”用于指定缺失變量的默認(rèn)值,“??”用來判斷某個(gè)變量是否存在。

2、FreeMarker的常用指令

1)if指令

使用if指令可以有條件的跳過模板的一部分,和程序語言中的if相似,例如你想顯示某個(gè)用戶是否成年可以這樣寫:

2)switchcasedefaultbreak指令

FreeMarker中使用switch、case、default、break指令和常用的程序設(shè)計(jì)語言中的一樣。例如:

雖然FreeMarker提供了switch指令,但它并不推薦使用switch指令來控制也輸出,而是推薦使用FreeMarker的if..elseif..else指令來替代它。

3)list指令

當(dāng)在HTML中需要用列表遍歷集合的內(nèi)容時(shí),list就顯得尤為重要,例如當(dāng)我們需要遍歷一個(gè)用戶集合時(shí)可以這樣寫:

4)include指令

include指令的作用類似于JSP的包含指令,用于包含指定頁,include指令的語法格式如下:

<#include filename [options]>

在上面的語法格式中,兩個(gè)參數(shù)的解釋如下

a)filename:該參數(shù)指定被包含的模板文件

b)options:該參數(shù)可以省略,指定包含時(shí)的選項(xiàng),包含encoding和parse兩個(gè)選項(xiàng),encoding指定包含頁面時(shí)所使用的解碼集,而parse指定被包含是否作為FTL文件來解析。如果省略了parse選項(xiàng)值,則該選項(xiàng)值默認(rèn)是true。

5)assign指令

通過assign指令可以創(chuàng)建一個(gè)變量,或替換一個(gè)已存在的變量,例如:

<#assign name=”zhangsan”>

四、FreeMarker實(shí)現(xiàn)網(wǎng)頁靜態(tài)化

上面我簡(jiǎn)單介紹了FreeMarker的基本用法,下面我將以具體例子采用Freemarker實(shí)現(xiàn)網(wǎng)頁靜態(tài)化的功能。

1)新建一個(gè)Maven項(xiàng)目,在pom.xml文件中新增FreeMarker的jar包,

2)新建FreemarkerUtil工具類,其中包含了通過標(biāo)準(zhǔn)輸出流輸出模板的結(jié)果的方法和輸出到文件中的方法。Freemarker是通過template.Configuration這個(gè)對(duì)象對(duì)模板進(jìn)行加載的(它也處理創(chuàng)建和緩存預(yù)解析模板的工作),然后我們通過getTemplate方法獲得你想要的模板,有一點(diǎn)要記住template.Configuration在你整個(gè)應(yīng)用必須保證唯一實(shí)例。

3)新建User實(shí)體類,用戶屬性包含用戶主鍵、用戶年齡、郵箱,該實(shí)體類用于

模擬從數(shù)據(jù)庫中查詢出數(shù)據(jù)。

4)新建模板文件01.ftl,通過上面的介紹知道FreeMarker是一種基于模板的、用來生成輸出文本的通用工具,所以我們必須要定制符合自己業(yè)務(wù)的模板出來,然后將需要?jiǎng)討B(tài)加載的數(shù)據(jù)通過FreeMarker的語法規(guī)范書寫生成靜態(tài)HTML的模板文件,具體的語法規(guī)范在上前面已經(jīng)詳細(xì)介紹。

5)新建Junit測(cè)試類TestFreemarker,用假數(shù)據(jù)模擬從數(shù)據(jù)庫中查詢數(shù)據(jù)并通過FreeMarker將模板文件和數(shù)據(jù)結(jié)合生成靜態(tài)的HTML文件。

6)通過以上步驟便成功的完成了一個(gè)通過FreeMarker生成靜態(tài)HTML文件,生成的HTML文件內(nèi)容如圖3-1所示。

圖3-1

通過以上步驟便成功的實(shí)現(xiàn)了對(duì)一個(gè)需要從數(shù)據(jù)庫中查詢數(shù)據(jù)的動(dòng)態(tài)頁面的靜態(tài)化處理,當(dāng)我們每次更新了數(shù)據(jù)庫中的相應(yīng)信息以后,我們便可以重新執(zhí)行這個(gè)方法,將這個(gè)頁面重新靜態(tài)化。

四、FreeMarker與SpringMVC整合實(shí)例

本節(jié)我將講解FreeMarker如何與SpringMVC的整合過程

1)首先創(chuàng)建一個(gè)Maven項(xiàng)目,并添加Spring和FreeMarker相應(yīng)的依賴包:

2)完成依賴包的添加后,需要在web.xml中添加相關(guān)的配置:

3)springMVC-servlet.xml文件的配置,DispatcherServlet會(huì)根據(jù)web.xml中的配置去查找對(duì)應(yīng)的-servlet.xml的文件來加載spring的一些配置信息。所以我這里的配置文件名稱叫springMVC-servlet.xml。具體配置信息如下所示,需要注意的是如果使用Freemarker和jsp兩個(gè)視圖一定要分配好文件夾,如果兩者出現(xiàn)沖突會(huì)默認(rèn)去找FreeMarker。

4)通過以上步驟我們便完成了FreeMarker與springMVC的整合。通過以下一個(gè)測(cè)試Controller便可以測(cè)試整合是否成功.

5)編寫welcome.ftl模板文件

6)運(yùn)行結(jié)果如圖4-1所示

圖4-1

總結(jié)

一個(gè)大型的網(wǎng)站,比如門戶網(wǎng)站,在面對(duì)大量用戶訪問、高并發(fā)請(qǐng)求方面,基本的解決方案都是將HTML靜態(tài)化、圖片服務(wù)器分離、數(shù)據(jù)庫集群、負(fù)載均衡等幾個(gè)方案。其中HTML靜態(tài)化大大降低了大量的數(shù)據(jù)庫訪問請(qǐng)求,在面對(duì)高并發(fā)請(qǐng)求時(shí)有很明顯的作用,大家都知道,效率最高、消耗最小的就是純靜態(tài)化的HTML頁面,所以我們盡可能使我們的網(wǎng)站上的頁面采用靜態(tài)頁面來實(shí)現(xiàn),這個(gè)最簡(jiǎn)單的方法其實(shí)也是最有效的解決方法。但是對(duì)于大量?jī)?nèi)容并且更新頻繁的網(wǎng)站,我們無法全部手動(dòng)的去一個(gè)一個(gè)實(shí)現(xiàn),于是便出現(xiàn)了像FreeMarker這樣的一些技術(shù),在所有采用網(wǎng)頁靜態(tài)化手段的網(wǎng)站中,F(xiàn)reeMarker使用的比例大大的超過了其他的一些技術(shù),由此可見FreeMarker在這方面的一些顯著優(yōu)勢(shì)。

除了一些門戶和信息發(fā)布類型的網(wǎng)站,對(duì)于交互性要求很高的一些網(wǎng)站來說,盡可能的靜態(tài)化也是提高性能的必要手段,將系統(tǒng)的首頁、文章、社區(qū)帖子進(jìn)行實(shí)時(shí)的靜態(tài)化、有更新的時(shí)候再重新靜態(tài)化也是大量使用的策略,像Mop大雜燴、網(wǎng)易新聞、鳳凰新聞等大型網(wǎng)站都使用了這樣的策略。

同時(shí),HTML靜態(tài)化也是某些緩存策略使用的手段,對(duì)于系統(tǒng)中頻繁使用數(shù)據(jù)庫查詢但是內(nèi)容更新很小的應(yīng)用,可以考慮使用FreeMarker將HTML靜態(tài)化。比如一些網(wǎng)站的公用設(shè)置信息,這些信息基本都是可以通過后臺(tái)來管理并存儲(chǔ)在數(shù)據(jù)庫中,這些信息其實(shí)會(huì)大量的被前臺(tái)程序調(diào)用,每一次調(diào)用都會(huì)去查詢一次數(shù)據(jù)庫,但是這些信息的更新頻率又會(huì)很小,因此也可以考慮將這部分內(nèi)容進(jìn)行后臺(tái)更新的時(shí)候進(jìn)行靜態(tài)化,這樣就避免了大量的數(shù)據(jù)庫訪問請(qǐng)求。

個(gè)人簡(jiǎn)介:

劉小兵

軟件開發(fā)工程師

任職于某大型IT外資企業(yè),主要從事JavaEE開發(fā)。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,619評(píng)論 6 539
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,155評(píng)論 3 425
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,635評(píng)論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我,道長(zhǎng),這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,539評(píng)論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 72,255評(píng)論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,646評(píng)論 1 326
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,655評(píng)論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,838評(píng)論 0 289
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,399評(píng)論 1 335
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 41,146評(píng)論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 43,338評(píng)論 1 372
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,893評(píng)論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 44,565評(píng)論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,983評(píng)論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,257評(píng)論 1 292
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 52,059評(píng)論 3 397
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 48,296評(píng)論 2 376

推薦閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,330評(píng)論 11 349
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 31,731評(píng)論 18 399