本質(zhì)上,是作為文件處理的,發(fā)送是“write,print”,接受是“read”。
成都創(chuàng)新互聯(lián)從2013年開(kāi)始,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站制作、做網(wǎng)站網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個(gè)夢(mèng)想脫穎而出為使命,1280元壺關(guān)做網(wǎng)站,已為上家服務(wù),為壺關(guān)各地企業(yè)和個(gè)人服務(wù),聯(lián)系電話:18982081108
連接相當(dāng)于打開(kāi)文件。
網(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。
這篇文章主要是講如何基于 golang 實(shí)現(xiàn)一個(gè)簡(jiǎn)單的網(wǎng)關(guān)。
轉(zhuǎn)自: troy.wang/docs/golang/posts/golang-gateway/
整理:go語(yǔ)言鐘文文檔:
啟動(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)見(jià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ù),一旦超過(guò) 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ì)瞬間壓力過(guò)大;參考 nginx 內(nèi)部的加權(quán)輪詢,或者應(yīng)該稱之為平滑加權(quán)輪詢,思路是:
后端真實(shí)節(jié)點(diǎn)包含三個(gè)權(quán)重:
操作步驟:
具體代碼
一致性 hash 算法,主要是用于分布式 cache 熱點(diǎn)/命中問(wè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)去,然后一層層出來(lái)。
中間件的實(shí)現(xiàn)一般有兩種,一種是使用數(shù)組,然后配合 index 計(jì)數(shù);一種是鏈?zhǔn)秸{(diào)用。
具體代碼
本文介紹一些Go語(yǔ)言的基礎(chǔ)語(yǔ)法。
先來(lái)看一個(gè)簡(jiǎn)單的go語(yǔ)言代碼:
go語(yǔ)言的注釋方法:
代碼執(zhí)行結(jié)果:
下面來(lái)進(jìn)一步介紹go的基礎(chǔ)語(yǔ)法。
go語(yǔ)言中格式化輸出可以使用 fmt 和 log 這兩個(gè)標(biāo)準(zhǔn)庫(kù),
常用方法:
示例代碼:
執(zhí)行結(jié)果:
更多格式化方法可以訪問(wèn)中的fmt包。
log包實(shí)現(xiàn)了簡(jiǎn)單的日志服務(wù),也提供了一些格式化輸出的方法。
執(zhí)行結(jié)果:
下面來(lái)介紹一下go的數(shù)據(jù)類型
下表列出了go語(yǔ)言的數(shù)據(jù)類型:
int、float、bool、string、數(shù)組和struct屬于值類型,這些類型的變量直接指向存在內(nèi)存中的值;slice、map、chan、pointer等是引用類型,存儲(chǔ)的是一個(gè)地址,這個(gè)地址存儲(chǔ)最終的值。
常量是在程序編譯時(shí)就確定下來(lái)的值,程序運(yùn)行時(shí)無(wú)法改變。
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
Go 語(yǔ)言的運(yùn)算符主要包括算術(shù)運(yùn)算符、關(guān)系運(yùn)算符、邏輯運(yùn)算符、位運(yùn)算符、賦值運(yùn)算符以及指針相關(guān)運(yùn)算符。
算術(shù)運(yùn)算符:
關(guān)系運(yùn)算符:
邏輯運(yùn)算符:
位運(yùn)算符:
賦值運(yùn)算符:
指針相關(guān)運(yùn)算符:
下面介紹一下go語(yǔ)言中的if語(yǔ)句和switch語(yǔ)句。另外還有一種控制語(yǔ)句叫select語(yǔ)句,通常與通道聯(lián)用,這里不做介紹。
if語(yǔ)法格式如下:
if ... else :
else if:
示例代碼:
語(yǔ)法格式:
另外,添加 fallthrough 會(huì)強(qiáng)制執(zhí)行后面的 case 語(yǔ)句,不管下一條case語(yǔ)句是否為true。
示例代碼:
執(zhí)行結(jié)果:
下面介紹幾種循環(huán)語(yǔ)句:
執(zhí)行結(jié)果:
執(zhí)行結(jié)果:
也可以通過(guò)標(biāo)記退出循環(huán):
--THE END--