網(wǎng)關(guān)=反向代理+負(fù)載均衡+各種策略,技術(shù)實(shí)現(xiàn)也有多種多樣,有基于 nginx 使用 lua 的實(shí)現(xiàn),比如 openresty、kong;也有基于 zuul 的通用網(wǎng)關(guān);還有就是 golang 的網(wǎng)關(guān),比如 tyk。

創(chuàng)新互聯(lián)是一家專注于成都網(wǎng)站制作、成都網(wǎng)站建設(shè)、外貿(mào)營(yíng)銷網(wǎng)站建設(shè)與策劃設(shè)計(jì),柳城網(wǎng)站建設(shè)哪家好?創(chuàng)新互聯(lián)做網(wǎng)站,專注于網(wǎng)站建設(shè)十載,網(wǎng)設(shè)計(jì)領(lǐng)域的專業(yè)建站公司;建站業(yè)務(wù)涵蓋:柳城等地區(qū)。柳城做網(wǎng)站價(jià)格咨詢:18982081108
這篇文章主要是講如何基于 golang 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的網(wǎng)關(guān)。
轉(zhuǎn)自: troy.wang/docs/golang/posts/golang-gateway/
整理:go語言鐘文文檔:
啟動(dòng)兩個(gè)后端 web 服務(wù)(代碼)
這里使用命令行工具進(jìn)行測(cè)試
具體代碼
直接使用基礎(chǔ)庫(kù) httputil 提供的NewSingleHostReverseProxy即可,返回的reverseProxy對(duì)象實(shí)現(xiàn)了serveHttp方法,因此可以直接作為 handler。
具體代碼
director中定義回調(diào)函數(shù),入?yún)?http.Request,決定如何構(gòu)造向后端的請(qǐng)求,比如 host 是否向后傳遞,是否進(jìn)行 url 重寫,對(duì)于 header 的處理,后端 target 的選擇等,都可以在這里完成。
director在這里具體做了:
modifyResponse中定義回調(diào)函數(shù),入?yún)?http.Response,用于修改響應(yīng)的信息,比如響應(yīng)的 Body,響應(yīng)的 Header 等信息。
最終依舊是返回一個(gè)ReverseProxy,然后將這個(gè)對(duì)象作為 handler 傳入即可。
參考 2.2 中的NewSingleHostReverseProxy,只需要實(shí)現(xiàn)一個(gè)類似的、支持多 targets 的方法即可,具體實(shí)現(xiàn)見后面。
作為一個(gè)網(wǎng)關(guān)服務(wù),在上面 2.3 的基礎(chǔ)上,需要支持必要的負(fù)載均衡策略,比如:
隨便 random 一個(gè)整數(shù)作為索引,然后取對(duì)應(yīng)的地址即可,實(shí)現(xiàn)比較簡(jiǎn)單。
具體代碼
使用curIndex進(jìn)行累加計(jì)數(shù),一旦超過 rss 數(shù)組的長(zhǎng)度,則重置。
具體代碼
輪詢帶權(quán)重,如果使用計(jì)數(shù)遞減的方式,如果權(quán)重是5,1,1那么后端 rs 依次為a,a,a,a,a,b,c,a,a,a,a…,其中 a 后端會(huì)瞬間壓力過大;參考 nginx 內(nèi)部的加權(quán)輪詢,或者應(yīng)該稱之為平滑加權(quán)輪詢,思路是:
后端真實(shí)節(jié)點(diǎn)包含三個(gè)權(quán)重:
操作步驟:
具體代碼
一致性 hash 算法,主要是用于分布式 cache 熱點(diǎn)/命中問題;這里用于基于某 key 的 hash 值,路由到固定后端,但是只能是基本滿足流量綁定,一旦后端目標(biāo)節(jié)點(diǎn)故障,會(huì)自動(dòng)平移到環(huán)上最近的那么個(gè)節(jié)點(diǎn)。
實(shí)現(xiàn):
具體代碼
每一種不同的負(fù)載均衡算法,只需要實(shí)現(xiàn)添加以及獲取的接口即可。
然后使用工廠方法,根據(jù)傳入的參數(shù),決定使用哪種負(fù)載均衡策略。
具體代碼
作為網(wǎng)關(guān),中間件必不可少,這類包括請(qǐng)求響應(yīng)的模式,一般稱作洋蔥模式,每一層都是中間件,一層層進(jìn)去,然后一層層出來。
中間件的實(shí)現(xiàn)一般有兩種,一種是使用數(shù)組,然后配合 index 計(jì)數(shù);一種是鏈?zhǔn)秸{(diào)用。
具體代碼
個(gè)人覺得golang十分適合進(jìn)行網(wǎng)游服務(wù)器端開發(fā),寫下這篇文章總結(jié)一下。 從網(wǎng)游的角度看: 要成功的運(yùn)營(yíng)一款網(wǎng)游,很大程度上依賴于玩家自發(fā)形成的社區(qū)。只有玩家自發(fā)形成一個(gè)穩(wěn)定的生態(tài)系統(tǒng),游戲才能持續(xù)下去,避免鬼城的出現(xiàn)。而這就需要多次大量導(dǎo)入用戶,在同時(shí)在線用戶量達(dá)到某個(gè)臨界點(diǎn)的時(shí)候,才有可能完成。因此,多人同時(shí)在線十分有必要。 再來看網(wǎng)游的常見玩法,除了排行榜這類統(tǒng)計(jì)和數(shù)據(jù)匯總的功能外,基本沒有需要大量CPU時(shí)間的應(yīng)用。以前的項(xiàng)目里,即時(shí)戰(zhàn)斗產(chǎn)生的各種傷害計(jì)算對(duì)CPU的消耗也不大。玩家要完成一次操作,需要通過客戶端-服務(wù)器端-客戶端這樣一個(gè)來回,為了獲得高響應(yīng)速度,滿足玩家體驗(yàn),服務(wù)器端的處理也不能占用太多時(shí)間。所以,每次請(qǐng)求對(duì)應(yīng)的CPU占用是比較小的。 網(wǎng)游的IO主要分兩個(gè)方面,一個(gè)是網(wǎng)絡(luò)IO,一個(gè)是磁盤IO。網(wǎng)絡(luò)IO方面,可以分成美術(shù)資源的IO和游戲邏輯指令的IO,這里主要分析游戲邏輯的IO。游戲邏輯的IO跟CPU占用的情況相似,每次請(qǐng)求的字節(jié)數(shù)很小,但由于多人同時(shí)在線,因此并發(fā)數(shù)相當(dāng)高。另外,地圖信息的廣播也會(huì)帶來比較頻繁的網(wǎng)絡(luò)通信。磁盤IO方面,主要是游戲數(shù)據(jù)的保存。采用不同的數(shù)據(jù)庫(kù),會(huì)有比較大的區(qū)別。以前的項(xiàng)目里,就經(jīng)歷了從MySQL轉(zhuǎn)向MongoDB這種內(nèi)存數(shù)據(jù)庫(kù)的過程,磁盤IO不再是瓶頸。總體來說,還是用內(nèi)存做一級(jí)緩沖,避免大量小數(shù)據(jù)塊讀寫的方案。 針對(duì)網(wǎng)游的這些特點(diǎn),golang的語言特性十分適合開發(fā)游戲服務(wù)器端。 首先,go語言提供goroutine機(jī)制作為原生的并發(fā)機(jī)制。每個(gè)goroutine所需的內(nèi)存很少,實(shí)際應(yīng)用中可以啟動(dòng)大量的goroutine對(duì)并發(fā)連接進(jìn)行響應(yīng)。goroutine與gevent中的greenlet很相像,遇到IO阻塞的時(shí)候,調(diào)度器就會(huì)自動(dòng)切換到另一個(gè)goroutine執(zhí)行,保證CPU不會(huì)因?yàn)镮O而發(fā)生等待。而goroutine與gevent相比,沒有了python底層的GIL限制,就不需要利用多進(jìn)程來榨取多核機(jī)器的性能了。通過設(shè)置最大線程數(shù),可以控制go所啟動(dòng)的線程,每個(gè)線程執(zhí)行一個(gè)goroutine,讓CPU滿負(fù)載運(yùn)行。 同時(shí),go語言為goroutine提供了獨(dú)到的通信機(jī)制channel。channel發(fā)生讀寫的時(shí)候,也會(huì)掛起當(dāng)前操作channel的goroutine,是一種同步阻塞通信。這樣既達(dá)到了通信的目的,又實(shí)現(xiàn)同步,用CSP模型的觀點(diǎn)看,并發(fā)模型就是通過一組進(jìn)程和進(jìn)程間的事件觸發(fā)解決任務(wù)的。雖然說,主流的編程語言之間,只要是圖靈完備的,他們就都能實(shí)現(xiàn)相同的功能。但go語言提供的這種協(xié)程間通信機(jī)制,十分優(yōu)雅地揭示了協(xié)程通信的本質(zhì),避免了以往鎖的顯式使用帶給程序員的心理負(fù)擔(dān),確是一大優(yōu)勢(shì)。進(jìn)行網(wǎng)游開發(fā)的程序員,可以將游戲邏輯按照單線程阻塞式的寫,不需要額外考慮線程調(diào)度的問題,以及線程間數(shù)據(jù)依賴的問題。因?yàn)椋€程間的channel通信,已經(jīng)表達(dá)了線程間的數(shù)據(jù)依賴關(guān)系了,而go的調(diào)度器會(huì)給予妥善的處理。 另外,go語言提供的gc機(jī)制,以及對(duì)指針的保護(hù)式使用,可以大大減輕程序員的開發(fā)壓力,提高開發(fā)效率。 展望未來,我期待go語言社區(qū)能夠提供更多的goroutine間的隔離機(jī)制。個(gè)人十分推崇erlang社區(qū)的脆崩哲學(xué),推動(dòng)應(yīng)用發(fā)生預(yù)期外行為時(shí),盡早崩潰,再fork出新進(jìn)程處理新的請(qǐng)求。對(duì)于協(xié)程機(jī)制,需要由程序員保證執(zhí)行的函數(shù)不會(huì)發(fā)生死循環(huán),導(dǎo)致線程卡死。
go語言適用的領(lǐng)域有:
Go語言主要用作服務(wù)器端開發(fā),其定位是用來開發(fā)“大型軟件”的,適合于很多程序員一起開發(fā)大型軟件,并且開發(fā)周期長(zhǎng),支持云計(jì)算的網(wǎng)絡(luò)服務(wù)。
Go語言作為服務(wù)器編程語言,很適合處理日志、數(shù)據(jù)打包、虛擬機(jī)處理、文件系統(tǒng)、分布式系統(tǒng)、數(shù)據(jù)庫(kù)代理等;網(wǎng)絡(luò)編程方面,Go語言廣泛應(yīng)用于Web應(yīng)用、API應(yīng)用、下載應(yīng)用等;除此之外,Go語言還可用于內(nèi)存數(shù)據(jù)庫(kù)和云平臺(tái)領(lǐng)域,目前國(guó)外很多云平臺(tái)都是采用Go開發(fā)。
Go語言能夠讓程序員快速開發(fā),并且在軟件不斷的增長(zhǎng)過程中,它能讓程序員更容易地進(jìn)行維護(hù)和修改。它融合了傳統(tǒng)編譯型語言的高效性和腳本語言的易用性和富于表達(dá)性。
Go語言作為一門大型項(xiàng)目開發(fā)語言,在很多大公司相繼使用,甚至完全轉(zhuǎn)向Go開發(fā),其中代表有Google、Facebook、騰訊、百度、阿里巴巴、京東、小米以及360、美團(tuán)、滴滴以及新浪等,因此,Go語言的開發(fā)前景還是很不錯(cuò)的!
分享標(biāo)題:go語言與網(wǎng)聯(lián)網(wǎng) go語言網(wǎng)絡(luò)編程
網(wǎng)頁(yè)URL:http://chinadenli.net/article48/dojoohp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站、建站公司、定制開發(fā)、電子商務(wù)、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)