網(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。
網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)建站!專注于網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、微信小程序開發(fā)、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了陽(yáng)高免費(fèi)建站歡迎大家使用!
這篇文章主要是講如何基于 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)見后面。
作為一個(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)用。
具體代碼
Revel Web開源框架
個(gè)高效的Go語(yǔ)言Web開發(fā)框架,?其思路完全來(lái)自 Java 的?Play Framework。
特點(diǎn)
熱編譯,簡(jiǎn)單可選,同步(每個(gè)請(qǐng)求都創(chuàng)建自己的goroutine來(lái)處理。
Go語(yǔ)言Web框架:beego
一個(gè)用Go開發(fā)的應(yīng)用框架,思路來(lái)自于tornado,路由設(shè)計(jì)來(lái)源于sinatra。
支持特性
MVC;
REST;
智能路由;
日志調(diào)試;
配置管理;
模板自動(dòng)渲染;
layout設(shè)計(jì);
中間件插入邏輯;
方便的JSON/XML服務(wù);
第一個(gè):Beego框架
Beego框架是astaxie的GOWeb開發(fā)的開源框架。Beego框架最大的特點(diǎn)是由八個(gè)大的基礎(chǔ)模塊組成,八大基礎(chǔ)模塊的特點(diǎn)是可以根據(jù)自己的需要進(jìn)行引入,模塊相互獨(dú)立,模塊之間耦合性低。
相應(yīng)的Beego的缺點(diǎn)就是全部使用時(shí)比較臃腫,通過(guò)bee工具來(lái)構(gòu)建項(xiàng)目時(shí),直接生成項(xiàng)目目錄和耦合關(guān)系,從而會(huì)導(dǎo)致在項(xiàng)目開發(fā)過(guò)程中受制性較大。
第二個(gè):Gin框架
Gin是一個(gè)GOlang的微框架,封裝比較優(yōu)雅,API友好,源碼注釋比較明確,已經(jīng)發(fā)布了1.0版本;具有快速靈活、容錯(cuò)方便等特點(diǎn),其實(shí)對(duì)于golang而言,web框架的依賴遠(yuǎn)比Python、Java更小。
目前在很多使用golang的中小型公司中進(jìn)行業(yè)務(wù)開發(fā),使用Gin框架的很多,大家如果想使用golang進(jìn)行熟練Web開發(fā),可以多關(guān)注一下這個(gè)框架。
第三個(gè):Iris框架
Iris框架在其官方網(wǎng)站上被描述為GO開發(fā)中最快的Web框架,并給出了多框架和多語(yǔ)言之前的性能對(duì)比。目前在github上,Iris框架已經(jīng)收獲了14433個(gè)star和1493個(gè)fork,可見是非常受歡迎的。
在實(shí)際開發(fā)中,Iris框架與Gin框架的學(xué)習(xí)曲線幾乎相同,所以掌握了Gin就可以輕松掌握Iris框架。
第四個(gè):Echo框架
也是golang的微型Web框架,其具備快速HTTP路由器、支持?jǐn)U展中間件,同時(shí)還支持靜態(tài)文件服務(wù)、Websocket以及支持制定綁定函數(shù),制定相應(yīng)渲染函數(shù),并允許使用任意的HTML模版引擎。
1. 介紹
最近在研究一些消息中間件,常用的MQ如RabbitMQ,ActiveMQ,Kafka等。NSQ是一個(gè)基于Go語(yǔ)言的分布式實(shí)時(shí)消息平臺(tái),它基于MIT開源協(xié)議發(fā)布,由bitly公司開源出來(lái)的一款簡(jiǎn)單易用的消息中間件。
官方和第三方還為NSQ開發(fā)了眾多客戶端功能庫(kù),如官方提供的基于HTTP的nsqd、Go客戶端go-nsq、Python客戶端pynsq、基于Node.js的JavaScript客戶端nsqjs、異步C客戶端libnsq、Java客戶端nsq-java以及基于各種語(yǔ)言的眾多第三方客戶端功能庫(kù)。
1.1 Features
1). Distributed
NSQ提供了分布式的,去中心化,且沒(méi)有單點(diǎn)故障的拓?fù)浣Y(jié)構(gòu),穩(wěn)定的消息傳輸發(fā)布保障,能夠具有高容錯(cuò)和HA(高可用)特性。
2). Scalable易于擴(kuò)展
NSQ支持水平擴(kuò)展,沒(méi)有中心化的brokers。內(nèi)置的發(fā)現(xiàn)服務(wù)簡(jiǎn)化了在集群中增加節(jié)點(diǎn)。同時(shí)支持pub-sub和load-balanced 的消息分發(fā)。
3). Ops Friendly
NSQ非常容易配置和部署,生來(lái)就綁定了一個(gè)管理界面。二進(jìn)制包沒(méi)有運(yùn)行時(shí)依賴。官方有Docker image。
4.Integrated高度集成
官方的 Go 和 Python庫(kù)都有提供。而且為大多數(shù)語(yǔ)言提供了庫(kù)。
1.2 組件
1.3 拓?fù)浣Y(jié)構(gòu)
NSQ推薦通過(guò)他們相應(yīng)的nsqd實(shí)例使用協(xié)同定位發(fā)布者,這意味著即使面對(duì)網(wǎng)絡(luò)分區(qū),消息也會(huì)被保存在本地,直到它們被一個(gè)消費(fèi)者讀取。更重要的是,發(fā)布者不必去發(fā)現(xiàn)其他的nsqd節(jié)點(diǎn),他們總是可以向本地實(shí)例發(fā)布消息。
NSQ
首先,一個(gè)發(fā)布者向它的本地nsqd發(fā)送消息,要做到這點(diǎn),首先要先打開一個(gè)連接,然后發(fā)送一個(gè)包含topic和消息主體的發(fā)布命令,在這種情況下,我們將消息發(fā)布到事件topic上以分散到我們不同的worker中。
事件topic會(huì)復(fù)制這些消息并且在每一個(gè)連接topic的channel上進(jìn)行排隊(duì),在我們的案例中,有三個(gè)channel,它們其中之一作為檔案channel。消費(fèi)者會(huì)獲取這些消息并且上傳到S3。
nsqd
每個(gè)channel的消息都會(huì)進(jìn)行排隊(duì),直到一個(gè)worker把他們消費(fèi),如果此隊(duì)列超出了內(nèi)存限制,消息將會(huì)被寫入到磁盤中。Nsqd節(jié)點(diǎn)首先會(huì)向nsqlookup廣播他們的位置信息,一旦它們注冊(cè)成功,worker將會(huì)從nsqlookup服務(wù)器節(jié)點(diǎn)上發(fā)現(xiàn)所有包含事件topic的nsqd節(jié)點(diǎn)。
nsqlookupd
2. Internals
2.1 消息傳遞擔(dān)保
1)客戶表示已經(jīng)準(zhǔn)備好接收消息
2)NSQ 發(fā)送一條消息,并暫時(shí)將數(shù)據(jù)存儲(chǔ)在本地(在 re-queue 或 timeout)
3)客戶端回復(fù) FIN(結(jié)束)或 REQ(重新排隊(duì))分別指示成功或失敗。如果客戶端沒(méi)有回復(fù), NSQ 會(huì)在設(shè)定的時(shí)間超時(shí),自動(dòng)重新排隊(duì)消息
這確保了消息丟失唯一可能的情況是不正常結(jié)束 nsqd 進(jìn)程。在這種情況下,這是在內(nèi)存中的任何信息(或任何緩沖未刷新到磁盤)都將丟失。
如何防止消息丟失是最重要的,即使是這個(gè)意外情況可以得到緩解。一種解決方案是構(gòu)成冗余 nsqd對(duì)(在不同的主機(jī)上)接收消息的相同部分的副本。因?yàn)槟銓?shí)現(xiàn)的消費(fèi)者是冪等的,以兩倍時(shí)間處理這些消息不會(huì)對(duì)下游造成影響,并使得系統(tǒng)能夠承受任何單一節(jié)點(diǎn)故障而不會(huì)丟失信息。
2.2 簡(jiǎn)化配置和管理
單個(gè) nsqd 實(shí)例被設(shè)計(jì)成可以同時(shí)處理多個(gè)數(shù)據(jù)流。流被稱為“話題”和話題有 1 個(gè)或多個(gè)“通道”。每個(gè)通道都接收到一個(gè)話題中所有消息的拷貝。在實(shí)踐中,一個(gè)通道映射到下行服務(wù)消費(fèi)一個(gè)話題。
在更底的層面,每個(gè) nsqd 有一個(gè)與 nsqlookupd 的長(zhǎng)期 TCP 連接,定期推動(dòng)其狀態(tài)。這個(gè)數(shù)據(jù)被 nsqlookupd 用于給消費(fèi)者通知 nsqd 地址。對(duì)于消費(fèi)者來(lái)說(shuō),一個(gè)暴露的 HTTP /lookup 接口用于輪詢。為話題引入一個(gè)新的消費(fèi)者,只需啟動(dòng)一個(gè)配置了 nsqlookup 實(shí)例地址的 NSQ 客戶端。無(wú)需為添加任何新的消費(fèi)者或生產(chǎn)者更改配置,大大降低了開銷和復(fù)雜性。
2.3 消除單點(diǎn)故障
NSQ被設(shè)計(jì)以分布的方式被使用。nsqd 客戶端(通過(guò) TCP )連接到指定話題的所有生產(chǎn)者實(shí)例。沒(méi)有中間人,沒(méi)有消息代理,也沒(méi)有單點(diǎn)故障。
這種拓?fù)浣Y(jié)構(gòu)消除單鏈,聚合,反饋。相反,你的消費(fèi)者直接訪問(wèn)所有生產(chǎn)者。從技術(shù)上講,哪個(gè)客戶端連接到哪個(gè) NSQ 不重要,只要有足夠的消費(fèi)者連接到所有生產(chǎn)者,以滿足大量的消息,保證所有東西最終將被處理。對(duì)于 nsqlookupd,高可用性是通過(guò)運(yùn)行多個(gè)實(shí)例來(lái)實(shí)現(xiàn)。他們不直接相互通信和數(shù)據(jù)被認(rèn)為是最終一致。消費(fèi)者輪詢所有的配置的 nsqlookupd 實(shí)例和合并 response。失敗的,無(wú)法訪問(wèn)的,或以其他方式故障的節(jié)點(diǎn)不會(huì)讓系統(tǒng)陷于停頓。
2.4 效率
對(duì)于數(shù)據(jù)的協(xié)議,通過(guò)推送數(shù)據(jù)到客戶端最大限度地提高性能和吞吐量的,而不是等待客戶端拉數(shù)據(jù)。這個(gè)概念,稱之為 RDY 狀態(tài),基本上是客戶端流量控制的一種形式。
efficiency
2.5 心跳和超時(shí)
組合應(yīng)用級(jí)別的心跳和 RDY 狀態(tài),避免頭阻塞現(xiàn)象,也可能使心跳無(wú)用(即,如果消費(fèi)者是在后面的處理消息流的接收緩沖區(qū)中,操作系統(tǒng)將被填滿,堵心跳)為了保證進(jìn)度,所有的網(wǎng)絡(luò) IO 時(shí)間上限勢(shì)必與配置的心跳間隔相關(guān)聯(lián)。這意味著,你可以從字面上拔掉之間的網(wǎng)絡(luò)連接 nsqd 和消費(fèi)者,它會(huì)檢測(cè)并正確處理錯(cuò)誤。當(dāng)檢測(cè)到一個(gè)致命錯(cuò)誤,客戶端連接被強(qiáng)制關(guān)閉。在傳輸中的消息會(huì)超時(shí)而重新排隊(duì)等待傳遞到另一個(gè)消費(fèi)者。最后,錯(cuò)誤會(huì)被記錄并累計(jì)到各種內(nèi)部指標(biāo)。
2.6 分布式
因?yàn)镹SQ沒(méi)有在守護(hù)程序之間共享信息,所以它從一開始就是為了分布式操作而生。個(gè)別的機(jī)器可以隨便宕機(jī)隨便啟動(dòng)而不會(huì)影響到系統(tǒng)的其余部分,消息發(fā)布者可以在本地發(fā)布,即使面對(duì)網(wǎng)絡(luò)分區(qū)。
這種“分布式優(yōu)先”的設(shè)計(jì)理念意味著NSQ基本上可以永遠(yuǎn)不斷地?cái)U(kuò)展,需要更高的吞吐量?那就添加更多的nsqd吧。唯一的共享狀態(tài)就是保存在lookup節(jié)點(diǎn)上,甚至它們不需要全局視圖,配置某些nsqd注冊(cè)到某些lookup節(jié)點(diǎn)上這是很簡(jiǎn)單的配置,唯一關(guān)鍵的地方就是消費(fèi)者可以通過(guò)lookup節(jié)點(diǎn)獲取所有完整的節(jié)點(diǎn)集。清晰的故障事件——NSQ在組件內(nèi)建立了一套明確關(guān)于可能導(dǎo)致故障的的故障權(quán)衡機(jī)制,這對(duì)消息傳遞和恢復(fù)都有意義。雖然它們可能不像Kafka系統(tǒng)那樣提供嚴(yán)格的保證級(jí)別,但NSQ簡(jiǎn)單的操作使故障情況非常明顯。
2.7 no replication
不像其他的隊(duì)列組件,NSQ并沒(méi)有提供任何形式的復(fù)制和集群,也正是這點(diǎn)讓它能夠如此簡(jiǎn)單地運(yùn)行,但它確實(shí)對(duì)于一些高保證性高可靠性的消息發(fā)布沒(méi)有足夠的保證。我們可以通過(guò)降低文件同步的時(shí)間來(lái)部分避免,只需通過(guò)一個(gè)標(biāo)志配置,通過(guò)EBS支持我們的隊(duì)列。但是這樣仍然存在一個(gè)消息被發(fā)布后馬上死亡,丟失了有效的寫入的情況。
2.8 沒(méi)有嚴(yán)格的順序
雖然Kafka由一個(gè)有序的日志構(gòu)成,但NSQ不是。消息可以在任何時(shí)間以任何順序進(jìn)入隊(duì)列。在我們使用的案例中,這通常沒(méi)有關(guān)系,因?yàn)樗械臄?shù)據(jù)都被加上了時(shí)間戳,但它并不適合需要嚴(yán)格順序的情況。
2.9 無(wú)數(shù)據(jù)重復(fù)刪除功能
NSQ對(duì)于超時(shí)系統(tǒng),它使用了心跳檢測(cè)機(jī)制去測(cè)試消費(fèi)者是否存活還是死亡。很多原因會(huì)導(dǎo)致我們的consumer無(wú)法完成心跳檢測(cè),所以在consumer中必須有一個(gè)單獨(dú)的步驟確保冪等性。
3. 實(shí)踐安裝過(guò)程
本文將nsq集群具體的安裝過(guò)程略去,大家可以自行參考官網(wǎng),比較簡(jiǎn)單。這部分介紹下筆者實(shí)驗(yàn)的拓?fù)?,以及nsqadmin的相關(guān)信息。
3.1 拓?fù)浣Y(jié)構(gòu)
topology
實(shí)驗(yàn)采用3臺(tái)NSQD服務(wù),2臺(tái)LOOKUPD服務(wù)。
采用官方推薦的拓?fù)?,消息發(fā)布的服務(wù)和NSQD在一臺(tái)主機(jī)。一共5臺(tái)機(jī)器。
NSQ基本沒(méi)有配置文件,配置通過(guò)命令行指定參數(shù)。
主要命令如下:
LOOKUPD命令
NSQD命令
工具類,消費(fèi)后存儲(chǔ)到本地文件。
發(fā)布一條消息
3.2 nsqadmin
對(duì)Streams的詳細(xì)信息進(jìn)行查看,包括NSQD節(jié)點(diǎn),具體的channel,隊(duì)列中的消息數(shù),連接數(shù)等信息。
nsqadmin
channel
列出所有的NSQD節(jié)點(diǎn):
nodes
消息的統(tǒng)計(jì):
msgs
lookup主機(jī)的列表:
hosts
4. 總結(jié)
NSQ基本核心就是簡(jiǎn)單性,是一個(gè)簡(jiǎn)單的隊(duì)列,這意味著它很容易進(jìn)行故障推理和很容易發(fā)現(xiàn)bug。消費(fèi)者可以自行處理故障事件而不會(huì)影響系統(tǒng)剩下的其余部分。
事實(shí)上,簡(jiǎn)單性是我們決定使用NSQ的首要因素,這方便與我們的許多其他軟件一起維護(hù),通過(guò)引入隊(duì)列使我們得到了堪稱完美的表現(xiàn),通過(guò)隊(duì)列甚至讓我們?cè)黾恿藥讉€(gè)數(shù)量級(jí)的吞吐量。越來(lái)越多的consumer需要一套嚴(yán)格可靠性和順序性保障,這已經(jīng)超過(guò)了NSQ提供的簡(jiǎn)單功能。
結(jié)合我們的業(yè)務(wù)系統(tǒng)來(lái)看,對(duì)于我們所需要傳輸?shù)陌l(fā)票消息,相對(duì)比較敏感,無(wú)法容忍某個(gè)nsqd宕機(jī),或者磁盤無(wú)法使用的情況,該節(jié)點(diǎn)堆積的消息無(wú)法找回。這是我們沒(méi)有選擇該消息中間件的主要原因。簡(jiǎn)單性和可靠性似乎并不能完全滿足。相比Kafka,ops肩負(fù)起更多負(fù)責(zé)的運(yùn)營(yíng)。另一方面,它擁有一個(gè)可復(fù)制的、有序的日志可以提供給我們更好的服務(wù)。但對(duì)于其他適合NSQ的consumer,它為我們服務(wù)的相當(dāng)好,我們期待著繼續(xù)鞏固它的堅(jiān)實(shí)的基礎(chǔ)。
大多數(shù)現(xiàn)代Web組件棧允許通過(guò)棧式/組件式中間件“過(guò)濾”請(qǐng)求,這樣就能干凈地從web應(yīng)用中分離出橫切關(guān)注點(diǎn)(譯注:面向方面程序設(shè)計(jì)中的概念?)。 本周我嘗試在Go語(yǔ)言的 http.FileServer 中植入鉤子,發(fā)現(xiàn)實(shí)現(xiàn)起來(lái)十分簡(jiǎn)便,讓我非常驚訝。
讓我們從一個(gè)基本的文件服務(wù)器開始說(shuō)起:
func main() {
http.ListenAndServe(":8080", http.FileServer(http.Dir("/tmp")))
}
標(biāo)題名稱:go語(yǔ)言開發(fā)的中間件 go語(yǔ)言集成開發(fā)環(huán)境
文章來(lái)源:http://jinyejixie.com/article26/hepjjg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供靜態(tài)網(wǎng)站、關(guān)鍵詞優(yōu)化、外貿(mào)建站、網(wǎng)頁(yè)設(shè)計(jì)公司、移動(dòng)網(wǎng)站建設(shè)、虛擬主機(jī)
聲明:本網(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í)需注明來(lái)源: 創(chuàng)新互聯(lián)