国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

網(wǎng)頁與網(wǎng)站的關(guān)系互聯(lián)網(wǎng)廣告代理可靠嗎

網(wǎng)頁與網(wǎng)站的關(guān)系,互聯(lián)網(wǎng)廣告代理可靠嗎,網(wǎng)站推廣的基本方法對(duì)于大部分網(wǎng)站來說都是適用的,一個(gè)域名怎么做網(wǎng)站今天繼續(xù)優(yōu)化了bigpipe項(xiàng)目,核心目標(biāo)就是解決重啟程序損失流量的問題。 背景 bigpipe作為一個(gè)消息中間件,其出現(xiàn)是為了給php程序提供方便的異步Http調(diào)用功能。然而php語言并不是常駐進(jìn)程模型,當(dāng)它請(qǐng)求bigpipe失敗后,頂多重試幾次&…

今天繼續(xù)優(yōu)化了bigpipe項(xiàng)目,核心目標(biāo)就是解決重啟程序損失流量的問題。

背景

bigpipe作為一個(gè)消息中間件,其出現(xiàn)是為了給php程序提供方便的異步Http調(diào)用功能。然而php語言并不是常駐進(jìn)程模型,當(dāng)它請(qǐng)求bigpipe失敗后,頂多重試幾次,就必須盡快的向用戶返回應(yīng)答。因此,bigpipe服務(wù)的可用性是非常重要的。

bigpipe使用golang編寫,采用channel逐層緩沖流量和數(shù)據(jù),采用協(xié)程并發(fā)處理數(shù)據(jù)。因?yàn)閎igpipe承接了若干業(yè)務(wù),經(jīng)常會(huì)對(duì)配置文件做一些修改,那么就必須重啟bigpipe。

思考

在最初的版本中,bigpipe提供了優(yōu)雅退出功能,也就是在退出前首先停止對(duì)外的Http服務(wù),然后將進(jìn)程內(nèi)剩余的數(shù)據(jù)處理干凈,最后再退出,這樣不至于損失已經(jīng)接受到的數(shù)據(jù)請(qǐng)求。

優(yōu)雅退出存在一個(gè)問題,就是先要停止對(duì)外http服務(wù),這樣才不會(huì)有新的流量涌入,才有可能把緩沖在內(nèi)存里的剩余流量處理干凈。因?yàn)檫@個(gè)設(shè)計(jì),導(dǎo)致在http停止服務(wù)后的一段時(shí)間內(nèi),客戶端是無法訪問bigpipe的,服務(wù)完全不可用。

最初的想法是,部署多個(gè)bigpipe,前端采用lvs/haproxy等負(fù)載均衡,這樣一旦http端口關(guān)閉,lvs會(huì)自動(dòng)轉(zhuǎn)發(fā)流量。但是,這樣的缺點(diǎn)是要求bigpipe必須多點(diǎn)部署,而且lvs/haproxy并不能保證流量瞬時(shí)切換到正常節(jié)點(diǎn),總要損失一些流量,而這就要求客戶端支持重試邏輯,總之不是一個(gè)完美的方案。

另外一個(gè)想法是,仍舊部署多個(gè)等價(jià)bigpipe組成集群,在bigpipe之前部署一個(gè)自研發(fā)的輕量級(jí)的proxy服務(wù),其支持多個(gè)bigpipe之間轉(zhuǎn)發(fā)重試,然而這樣不僅是帶來了更大的運(yùn)維成本,其實(shí)還是沒有直面問題本質(zhì),在錯(cuò)誤的路上越繞越遠(yuǎn)。

方案

必須讓bigpipe支持配置熱加載,這一點(diǎn)實(shí)現(xiàn)起來并不是很簡(jiǎn)單,下面我來說說難在哪里。

首先,在加載新的配置期間,不能停止http對(duì)外服務(wù),因此我決定Http模塊自身不支持熱加載(http監(jiān)聽地址,讀寫超時(shí)等簡(jiǎn)單配置),它始終保持對(duì)外服務(wù)。

然而,請(qǐng)求的處理模塊等是需要加載新的配置的,在重新加載這些模塊期間,http接收的請(qǐng)求必須要緩沖起來,這樣才能做到流量0損失,因此我重新設(shè)計(jì)了模塊結(jié)構(gòu),在http接口層和業(yè)務(wù)處理層之間增加一個(gè)緩沖層,專門用來支撐熱加載期間的流量緩沖作用。

為了簡(jiǎn)化設(shè)計(jì),無論是否使用熱加載特性,這個(gè)緩沖層總是存在。

另外一個(gè)重要的變更點(diǎn)是,之前配置文件我采用了全局單例的模式,并假設(shè)了一旦加載就不會(huì)再變化。然而在golang這樣一個(gè)多線程并發(fā)的模型下,要支持熱加載配置,就不能讓配置自身成為單例了,否則各個(gè)模塊正在訪問單例的同時(shí)配置內(nèi)容加載成新的,那模塊就會(huì)崩潰。

因此,關(guān)于配置熱加載的正常的設(shè)計(jì)思路是,舊模塊使用舊配置,新模塊使用新配置,配置文件不再保存單例,而是解析成功后將副本傳入到各個(gè)模塊之內(nèi)保存。

一旦配置文件重新加載到內(nèi)存,那么接下來要做的就是和優(yōu)雅退出類似,先讓http模塊暫停向內(nèi)部模塊轉(zhuǎn)發(fā)流量,但是它仍舊接收外部流量,并緩存起來。

接下來,各個(gè)舊模塊開始消耗剩余的流量,最終銷毀自身。

當(dāng)所有舊模塊退出后,將新的配置傳遞給各個(gè)模塊,啟動(dòng)新的模塊實(shí)例,并恢復(fù)http模塊繼續(xù)向內(nèi)部模塊轉(zhuǎn)發(fā)流量,程序恢復(fù)運(yùn)行。

不過,僅僅完成這些設(shè)計(jì)并不能解決整個(gè)問題,最棘手的是log和stats模塊,前者負(fù)責(zé)日志,后者負(fù)責(zé)程序計(jì)數(shù),它們一樣需要熱加載配置,比如:運(yùn)維想把日志的輸出目錄或者日志級(jí)別變更一下。

這兩個(gè)模塊比較特殊,它們被其他各個(gè)模塊調(diào)用,并且是并發(fā)的調(diào)用,相當(dāng)于”給天上的飛機(jī)換發(fā)動(dòng)機(jī)”,非常難。按照設(shè)計(jì),應(yīng)當(dāng)在老模塊全部銷毀后,將log和stats銷毀并重建。但是問題來了,http服務(wù)模塊并沒有銷毀,它仍舊在實(shí)時(shí)的操作log和stats庫,那么又怎么重啟這2個(gè)模塊呢?

這里我使用了atomic庫,log和stats模塊都是單例模式,保存的是對(duì)象的指針。在程序仍舊在持續(xù)訪問2個(gè)模塊的情況下,想要銷毀這個(gè)單例并重建,必須對(duì)指針進(jìn)行原子操作,好在golang提供了指針的atomic操作:

atomic.StorePointer

atomic.LoadPointer

1

2

atomic.StorePointer

atomic.LoadPointer

有了這2個(gè)api,我就可以原子的操作單例指針,完成瞬時(shí)的轉(zhuǎn)換。

當(dāng)然,在銷毀之后到重建之間的這段時(shí)間,http模塊打印的log和stats統(tǒng)計(jì)都會(huì)無效,但是這個(gè)時(shí)間通??梢远痰胶雎?。

以log庫為例,相應(yīng)的日志操作函數(shù)也首先通過atomic獲取log指針,如果存在則進(jìn)行實(shí)際的操作,否則什么也不做:

Go

// 單例

var gLogger unsafe.Pointer = nil

func getLogger() *logger {

return (*logger)(atomic.LoadPointer(&gLogger))

}

func FATAL(format string, v ...interface{}) {

if logger := getLogger(); logger != nil {

userLog := fmt.Sprintf(format, v...)

logger.queueLog(LOG_LEVEL_FATAL, &userLog)

}

}

func ERROR(format string, v ...interface{}) {

if logger := getLogger(); logger != nil {

userLog := fmt.Sprintf(format, v...)

logger.queueLog(LOG_LEVEL_ERROR, &userLog)

}

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

// 單例

vargLoggerunsafe.Pointer=nil

funcgetLogger()*logger{

return(*logger)(atomic.LoadPointer(&gLogger))

}

funcFATAL(formatstring,v...interface{}){

iflogger:=getLogger();logger!=nil{

userLog:=fmt.Sprintf(format,v...)

logger.queueLog(LOG_LEVEL_FATAL,&userLog)

}

}

funcERROR(formatstring,v...interface{}){

iflogger:=getLogger();logger!=nil{

userLog:=fmt.Sprintf(format,v...)

logger.queueLog(LOG_LEVEL_ERROR,&userLog)

}

}

這就是我在實(shí)現(xiàn)bigpipe熱加載期間遇到的一些問題,希望對(duì)大家設(shè)計(jì)熱加載時(shí)有所幫助。

如果文章幫助您解決了工作難題,您可以幫我點(diǎn)擊屏幕上的任意廣告,或者贊助少量費(fèi)用來支持我的持續(xù)創(chuàng)作,謝謝~

c68972f84f7c4f47f59a1f69f0608e10.png

http://aloenet.com.cn/news/43668.html

相關(guān)文章:

  • 做網(wǎng)站江門天津百度seo排名優(yōu)化
  • wordpress5.2.2下載seo有哪些經(jīng)典的案例
  • 鎮(zhèn)江百度競(jìng)價(jià)南昌seo管理
  • 門戶網(wǎng)站開發(fā)要多久深圳seo優(yōu)化推廣公司
  • 如何做新聞源網(wǎng)站如何讓新網(wǎng)站被收錄
  • 網(wǎng)站建設(shè)的方法學(xué)生網(wǎng)頁制作成品
  • 專業(yè)網(wǎng)站建設(shè)服務(wù)公司哪家好廣州今日頭條新聞最新
  • 云南新建設(shè)國際小學(xué)網(wǎng)站百度手機(jī)下載安裝
  • app展示網(wǎng)站網(wǎng)絡(luò)seo首頁
  • 響應(yīng)式網(wǎng)站設(shè)計(jì)稿百度知道下載
  • google網(wǎng)站建設(shè)騰訊新聞最新消息
  • 怎么做淘寶客網(wǎng)站優(yōu)化seo排名第一的企業(yè)
  • wordpress換身 變身品牌企業(yè)seo咨詢
  • 網(wǎng)站建設(shè)h5seo的關(guān)鍵詞無需
  • 做名片哪個(gè)網(wǎng)站可以找軟文營銷模板
  • 山東省兩學(xué)一做網(wǎng)站百度競(jìng)價(jià)推廣流程
  • wordpress插件殘留怎么刪除網(wǎng)絡(luò)優(yōu)化包括
  • 廣州app網(wǎng)站建設(shè)長沙網(wǎng)絡(luò)優(yōu)化產(chǎn)品
  • 網(wǎng)站建設(shè)及售后服務(wù)的說明書網(wǎng)絡(luò)推廣哪個(gè)平臺(tái)好
  • 網(wǎng)站備案查詢系統(tǒng)php版網(wǎng)絡(luò)營銷的現(xiàn)狀和發(fā)展趨勢(shì)
  • 織夢(mèng)網(wǎng)站如何做關(guān)鍵詞產(chǎn)品營銷策略有哪些
  • 小蝌蚪緊急自動(dòng)跳轉(zhuǎn)中seo搜索引擎優(yōu)化技術(shù)
  • 企業(yè)網(wǎng)站設(shè)計(jì)中應(yīng)注意產(chǎn)品發(fā)布功能優(yōu)化互聯(lián)網(wǎng)營銷師證書怎么考多少錢
  • 網(wǎng)站建設(shè)價(jià)格與哪些關(guān)鍵詞優(yōu)化排名查詢
  • 地圖如果插入網(wǎng)站網(wǎng)站平臺(tái)都有哪些
  • 西安購物網(wǎng)站建設(shè)2022年新聞熱點(diǎn)事件
  • 學(xué)會(huì)網(wǎng)站建設(shè)網(wǎng)絡(luò)推廣員要怎么做
  • 專業(yè)網(wǎng)站建設(shè)網(wǎng)站設(shè)計(jì)百度云盤資源搜索
  • 網(wǎng)站建設(shè)兩年免費(fèi)維護(hù)正規(guī)seo排名公司
  • 高端網(wǎng)站建設(shè)天軟科技廣告設(shè)計(jì)與制作