第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

在 init 或處理程序函數(shù)中讀取模板?

在 init 或處理程序函數(shù)中讀取模板?

Go
忽然笑 2021-11-08 15:47:10
我正在為一個(gè)網(wǎng)站編寫一個(gè)基本的服務(wù)器?,F(xiàn)在我面臨一個(gè)(對(duì)我來(lái)說(shuō))困難的性能問(wèn)題。讀取init()函數(shù)中的模板文件是否更好?// Initialize all pages of websitefunc init(){ indexPageData, err := ioutil.ReadFile("./tpl/index.tpl") check(err)}還是在http.HandlerFunc?func index(w http.ResponseWriter, req *http.Request){  indexPageData, err := ioutil.ReadFile("./tpl/index.tpl")  check(err)  indexPageTpl := template.Must(template.New("index").Parse(string(indexPageData)))  indexPageTpl.Execute(w, "test")}我認(rèn)為在第一個(gè)示例中,服務(wù)器啟動(dòng)后您無(wú)需訪問(wèn)磁盤并提高請(qǐng)求的性能。但是在開(kāi)發(fā)過(guò)程中我想刷新瀏覽器并查看新內(nèi)容。這可以通過(guò)第二個(gè)例子來(lái)完成。有人有最先進(jìn)的解決方案嗎?或者從性能的角度來(lái)看什么是正確的?
查看完整描述

2 回答

?
當(dāng)年話下

TA貢獻(xiàn)1890條經(jīng)驗(yàn) 獲得超9個(gè)贊

我們來(lái)分析一下性能:

我們將您的第一個(gè)解決方案(略有變化,見(jiàn)下文)命名為a和您的第二個(gè)解決方案b。

一個(gè)請(qǐng)求:
a:一個(gè)磁盤訪問(wèn)
b:一個(gè)磁盤訪問(wèn)

十次請(qǐng)求:
a:一次磁盤訪問(wèn)
b:十次磁盤訪問(wèn)

10 000 000 次請(qǐng)求:
a:一次磁盤訪問(wèn)
b:10 000 000 次磁盤訪問(wèn)(這很慢)

因此,第一個(gè)解決方案的性能更好。但是您對(duì)最新數(shù)據(jù)的擔(dān)憂呢?從文檔func (t *Template) Execute(wr io.Writer, data interface{}) error

Execute 將解析的模板應(yīng)用于指定的數(shù)據(jù)對(duì)象,將輸出寫入 wr。如果在執(zhí)行模板或?qū)懭肫漭敵鰰r(shí)發(fā)生錯(cuò)誤,則執(zhí)行將停止,但部分結(jié)果可能已寫入輸出寫入器。模板可以安全地并行執(zhí)行。

所以,發(fā)生的事情是這樣的:

  1. 您從磁盤讀取模板

  2. 您將文件解析為模板

  3. 您選擇的數(shù)據(jù)填補(bǔ)空白

  4. Execute使用具有該數(shù)據(jù)的模板,結(jié)果將寫入io.Writer

您選擇的數(shù)據(jù)是最新的。這與從磁盤重新讀取模板,甚至重新解析它無(wú)關(guān)。這是模板背后的整個(gè)想法:一次磁盤訪問(wèn),一次解析,多個(gè)動(dòng)態(tài)最終結(jié)果。

上面引用的文檔告訴我們另一件事:

模板可以安全地并行執(zhí)行。

這非常有用,因?yàn)槟?code>http.HandlerFuncs 是并行運(yùn)行的,如果您有多個(gè)并行請(qǐng)求。

那么,現(xiàn)在該怎么辦?
Read模板文件一次,
Parse模板一次,每個(gè)請(qǐng)求
Execute的模板。

我不確定您是否應(yīng)該在init()函數(shù)中讀取和解析,因?yàn)橹辽?code>Must可以恐慌(并且不要在那里使用一些相對(duì)的硬編碼路徑?。?- 我會(huì)嘗試在更受控的環(huán)境中這樣做,例如,提供一個(gè)函數(shù)(如New())來(lái)創(chuàng)建服務(wù)器的新實(shí)例并在其中執(zhí)行這些操作。

編輯:我重新閱讀了你的問(wèn)題,我可能誤解了你:

如果模板本身仍在開(kāi)發(fā)中,那么是的,您必須在每個(gè)請(qǐng)求中閱讀它才能獲得最新的結(jié)果。這比每次更改模板時(shí)都重新啟動(dòng)服務(wù)器更方便。對(duì)于生產(chǎn),模板應(yīng)該是固定的,只有數(shù)據(jù)應(yīng)該改變。

對(duì)不起,如果我在那里弄錯(cuò)了。


查看完整回答
反對(duì) 回復(fù) 2021-11-08
?
蠱毒傳說(shuō)

TA貢獻(xiàn)1895條經(jīng)驗(yàn) 獲得超3個(gè)贊

永遠(yuǎn)不要在生產(chǎn)中的請(qǐng)求處理程序中讀取和解析模板文件,這是最糟糕的(你應(yīng)該總是避免這種情況)。在開(kāi)發(fā)過(guò)程中當(dāng)然是可以的。


閱讀此問(wèn)題了解更多詳情:


golang中使用“模板”包生成動(dòng)態(tài)網(wǎng)頁(yè)給客戶端的時(shí)間太長(zhǎng)了


你可以通過(guò)多種方式來(lái)解決這個(gè)問(wèn)題。在這里,我列出了 4 個(gè)示例實(shí)現(xiàn)。


1.帶有“開(kāi)發(fā)模式”設(shè)置

如果您在開(kāi)發(fā)模式下運(yùn)行,您可以有一個(gè)常量或變量告訴您,這意味著模板不會(huì)被緩存。


這是一個(gè)例子:


const dev = true


var indexTmpl *template.Template


func init() {

    if !dev { // Prod mode, read and cache template

        indexTmpl = template.Must(template.New("index").ParseFiles(".tpl/index.tpl"))

    }

}


func getIndexTmpl() *template.Template {

    if dev { // Dev mode, always read fresh template

        return template.Must(template.New("index").ParseFiles(".tpl/index.tpl"))

    } else { // Prod mode, return cached template

        return indexTmpl

    }

}


func indexHandler(w http.ResponseWriter, r *http.Request) {

    getIndexTmpl().Execute(w, "test")

}

2. 在請(qǐng)求中指定(作為參數(shù))是否需要新模板

開(kāi)發(fā)時(shí),您可以指定一個(gè)額外的 URL 參數(shù),指示讀取新模板而不使用緩存的模板,例如 http://localhost:8080/index?dev=true


示例實(shí)現(xiàn):


var indexTmpl *template.Template


func init() {

    indexTmpl = getIndexTmpl()

}


func getIndexTmpl() *template.Template {

    return template.Must(template.New("index").ParseFiles(".tpl/index.tpl"))

}


func indexHandler(w http.ResponseWriter, r *http.Request) {

    t := indexTmpl

    if r.FormValue("dev") != nil {

        t = getIndexTmpl()

    }

    t.Execute(w, "test")

}

3.根據(jù)主機(jī)決定

您還可以檢查請(qǐng)求 URL 的主機(jī)名,如果是"localhost",則可以省略緩存并使用新模板。這需要最少的額外代碼和努力。請(qǐng)注意,您可能還想接受其他主機(jī),例如"127.0.0.1"(取決于您想要包含的內(nèi)容)。


示例實(shí)現(xiàn):


var indexTmpl *template.Template


func init() {

    indexTmpl = getIndexTmpl()

}


func getIndexTmpl() *template.Template {

    return template.Must(template.New("index").ParseFiles(".tpl/index.tpl"))

}


func indexHandler(w http.ResponseWriter, r *http.Request) {

    t := indexTmpl

    if r.URL.Host == "localhost" || strings.HasPrefix(r.URL.Host, "localhost:") {

        t = getIndexTmpl()

    }

    t.Execute(w, "test")

}

4.檢查模板文件最后修改

您還可以存儲(chǔ)模板文件加載時(shí)的最后修改時(shí)間。每當(dāng)請(qǐng)求模板時(shí),您可以檢查源模板文件的最后修改時(shí)間。如果它已更改,您可以在執(zhí)行之前重新加載它。


示例實(shí)現(xiàn):


type mytempl struct {

    t       *template.Template

    lastmod time.Time

    mutex   sync.Mutex

}


var indexTmpl mytempl


func init() {

    // You may want to call this in init so first request won't be slow

    checkIndexTempl()

}


func checkIndexTempl() {

    nm := ".tpl/index.tpl"

    fi, err := os.Stat(nm)

    if err != nil {

        panic(err)

    }

    if indexTmpl.lastmod != fi.ModTime() {

        // Changed, reload. Don't forget the locking!

        indexTmpl.mutex.Lock()

        defer indexTmpl.mutex.Unlock()

        indexTmpl.t = template.Must(template.New("index").ParseFiles(nm))

        indexTmpl.lastmod = fi.ModTime()

    }

}


func indexHandler(w http.ResponseWriter, r *http.Request) {

    checkIndexTempl()

    indexTmpl.t.Execute(w, "test")

}


查看完整回答
反對(duì) 回復(fù) 2021-11-08
  • 2 回答
  • 0 關(guān)注
  • 191 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)