微服務(wù)(Microservices)是一種軟件架構(gòu)風格睡蟋,它是以專注于單一責任與功能的小型功能區(qū)塊 (Small Building Blocks) 為基礎(chǔ)疾棵,利用模塊化的方式組合出復(fù)雜的大型應(yīng)用程序肴甸,各功能區(qū)塊使用與語言無關(guān) (Language-Independent/Language agnostic)的API集相互通信庶艾。
go-micro
比如有 user 和 order 兩個服務(wù)溃论,這 2 個服務(wù)不在一臺服務(wù)器上悠栓,user 怎么調(diào)用 order 服務(wù)中訂單查詢功能呢?這就涉及到服務(wù)間的通信惫周。
在 RESTful 架構(gòu)中尘惧,我們可以通過 GET /api/user/:id/orders 進行獲取數(shù)據(jù),然后對數(shù)據(jù)進行解碼(json递递、xml)等處理再返回給用戶喷橙,如果是 POST 請求啥么,傳遞的數(shù)據(jù)同樣也是 json 或 xml 編碼協(xié)議。
在微服務(wù)中贰逾,同樣也可以通過 RESTful api 進行數(shù)據(jù)調(diào)用饥臂,但是服務(wù)間走 http 開銷太大了,原因是 http 要傳遞的無用的元數(shù)據(jù)太多(header 等)似踱,再一個就是 http 協(xié)議本身比較慢隅熙。另外還有一個原因就是 xml 和 json 的編碼解碼速度效率不算高,編碼后的字節(jié)較大核芽。
這時候就要走 tcp/udp 協(xié)議了囚戚,那不能自己對數(shù)據(jù)進行編碼解碼這些麻煩的工作吧,所以有了 RPC 框架轧简,比如dubbo驰坊、 grpc,rpc 框架可以讓你在 A 服務(wù)器調(diào)用 B 服務(wù)器上的函數(shù)接口哮独,這中間因為走了網(wǎng)絡(luò)拳芙,所以是沒有單體應(yīng)用中本地函數(shù)調(diào)用效率高的,但是當業(yè)務(wù)上規(guī)模后皮璧,這點損耗是可以忽略的舟扎,比如訂單查詢需求非常大,那么可以部署 50個 order 服務(wù)來提供查詢悴务,可以進行負載均衡睹限,可以彈性擴展等,這個時候微服務(wù)的效果就出來了讯檐。
這 50 個 order 服務(wù)怎么管理羡疗、怎么監(jiān)控,怎么確定其中某一個是不是掛了别洪?這里面涉及的概念就很多了叨恨,服務(wù)監(jiān)控、服務(wù)發(fā)現(xiàn)挖垛、熔斷機制等各類名詞可能會讓人頭疼痒钝,但是因為服務(wù)進行了拆分,服務(wù)又分布在不同的位置晕换,所以如果你自己解決這些問題會花費大量的時間和精力午乓,這時候你就需要 go-micro 站宗,它提供了各類組件闸准,解決微服務(wù)架構(gòu)中的不同問題。
Cloud Native (國內(nèi)譯為“云原生”)梢灭,最早是 Matt Stine 提出的一個概念夷家。與微服務(wù)一樣蒸其,Cloud Native 并不是一種具體的技術(shù),而是一類思想的集合库快,包括DevOps摸袁、持續(xù)交付(Continuous Delivery)、微服務(wù)(MicroServices)义屏、敏捷基礎(chǔ)設(shè)施(Agile Infrastructure)靠汁、康威定律(Conways Law)等,以及根據(jù)商業(yè)能力對公司進行重組闽铐。Cloud Native 既包含技術(shù)(微服務(wù)蝶怔,敏捷基礎(chǔ)設(shè)施),也包含管理(DevOps兄墅,持續(xù)交付踢星,康威定律,重組等)隙咸。所以沐悦,Cloud Native 也可以說是一系列Cloud技術(shù)、企業(yè)管理方法的集合五督。
RPC
遠程過程調(diào)用(Remote Procedure Call藏否,RPC)是一個計算機通信協(xié)議。
gRPC (gRPC Remote Procedure Calls) 是 Google 發(fā)起的一個開源遠程過程調(diào)用系統(tǒng)充包,該系統(tǒng)基于 HTTP/2 協(xié)議傳輸秕岛。默認采用Protocol Buffers數(shù)據(jù)序列化協(xié)議,支持多種開發(fā)語言误证。
Protocol Buffers是一種更加靈活继薛、高效的數(shù)據(jù)格式,與XML愈捅、JSON類似遏考,在一些高性能且對響應(yīng)速度有要求的數(shù)據(jù)傳輸場景非常適用。
gRPC可以實現(xiàn)微服務(wù)蓝谨,將大的項目拆分為多個小且獨立的業(yè)務(wù)模塊灌具,也就是服務(wù),各服務(wù)間使用高效的protobuf協(xié)議進行RPC調(diào)用譬巫,gRPC默認使用protocol buffers咖楣,這是google開源的一套成熟的結(jié)構(gòu)數(shù)據(jù)序列化機制。
廣義上來講芦昔,所有本應(yīng)用程序外的調(diào)用都可以歸類為RPC诱贿,不管是分布式服務(wù),第三方服務(wù)的HTTP接口,還是讀寫Redis的一次請求珠十。從抽象的角度來講料扰,它們都一樣是RPC,由于不在本地執(zhí)行焙蹭,都有三個特點:
- 需要事先約定調(diào)用的語義(接口語法)
- 需要網(wǎng)絡(luò)傳輸
- 需要約定網(wǎng)絡(luò)傳輸中的內(nèi)容格式
RESTfull HTTP JSON
RESTfull是一種資源狀態(tài)轉(zhuǎn)換的架構(gòu)風格晒杈,也可以用來實現(xiàn)RPC, 互聯(lián)網(wǎng)對HTTP超廣泛的支持孔厉,使得這相當簡單拯钻,也是大多數(shù)情況下的首選。
通過HTTP協(xié)議來進行內(nèi)容傳輸撰豺,Header用來約定編碼说庭、body大小等,彼此以\r\n來分割郑趁,Header和body之間通過兩個連續(xù)的\r\n來間隔刊驴,能很容易地區(qū)分不同的請求。
通過Url和對應(yīng)參數(shù)來標示要調(diào)用的方法和參數(shù)寡润。在body中用JSON對內(nèi)容進行編碼捆憎,極易跨語言,不需要約定特定的復(fù)雜編碼格式和Stub文件梭纹。在版本兼容性上非常友好躲惰,擴展也很容易。
其缺點:
- HTTP的header和Json的數(shù)據(jù)冗余和低壓縮率使得傳輸性能差
- JSON難以表達復(fù)雜的參數(shù)類型变抽,如結(jié)構(gòu)體等
gRPC是一款RPC框架础拨,在性能和版本兼容上做了提升和讓步:
- Protobuf進行數(shù)據(jù)編碼,提高數(shù)據(jù)壓縮率
- 使用HTTP2.0彌補了HTTP1.1的不足
- 同樣在調(diào)用方和服務(wù)方使用協(xié)議約定文件绍载,提供參數(shù)可選诡宗,為版本兼容留下緩沖空間
protobuf 是一款用C++開發(fā)的跨語言、二進制編碼的數(shù)據(jù)序列化協(xié)議击儡,以超高的壓縮率著稱塔沃。它和早期的RPC方案一樣,需要雙方維護一個協(xié)議約束文件阳谍,以.proto結(jié)尾蛀柴,使用proto命令對文件進行解析,會生成對應(yīng)的Stub程序矫夯,客戶端和服務(wù)端都需要保存這份Stub程序用來進行編解碼鸽疾。對于這種協(xié)議文件導(dǎo)致的升級困難問題,protobuf 3 中定義的字段默認都是可選的(可以不傳)训貌,在接口升級時制肮,部分客戶端不需要升級自己的Stub程序。
對于JSON等文本形式的序列化協(xié)議來說,protobuf能有幾十倍空間和性能提升弄企, 比如傳輸123,文本類的需要3個字節(jié)(ascii 31 32 33)來傳輸区拳,而二進制類只需要一個字節(jié)(01111011)就可以表示拘领。
同時protobuf會維護.proto文件,這樣在解析文件生成Stub程序時樱调,可以對方法名等進行編號约素,傳輸時只傳編號,而不用傳方法的名字笆凌,這又可以節(jié)省大量字節(jié)圣猎,還有其他更多的精巧壓縮方法。
解決了數(shù)據(jù)體積的問題后乞而,gRPC使用HTTP2來改善傳輸性能送悔。
HTTP2解決了HTTP1.1的一些問題,并引入了新的機制:
- 在兩端建立Header索引表爪模,每次只發(fā)送索引欠啤,減小header體積
- 建立虛擬通道,將數(shù)據(jù)拆分成多個流屋灌,每個流有自己的ID和優(yōu)先級洁段,并且流可以雙向傳輸,每個流可以進一步拆成多個幀共郭§羲浚可以將多個請求切成不同的流發(fā)送,每個流可以獨立返回除嘹,避開1.1的串行或隊首阻塞問題写半。
同時,基于HTTP2的數(shù)據(jù)流機制尉咕,gRPC客戶端和服務(wù)端可以實現(xiàn)批量操作優(yōu)化污朽,客戶端可以攢一些請求,一口氣發(fā)給服務(wù)端龙考,服務(wù)端也可以批量返回結(jié)果蟆肆,借此實現(xiàn)流式rpc。
DevOps
DevOps(Development和Operations的組合詞)是一種重視“軟件開發(fā)人員(Dev)”和“IT運維技術(shù)人員(Ops)”之間溝通合作的文化晦款、運動或慣例炎功。透過自動化“軟件交付”和“架構(gòu)變更”的流程,來使得構(gòu)建缓溅、測試蛇损、發(fā)布軟件能夠更加地快捷、頻繁和可靠。
JWT(JSON Web Token)
JWT 的原理是淤齐,服務(wù)器認證以后股囊,生成一個 JSON格式的 對象,發(fā)回給客戶端更啄,如
{
"用戶名": "admin",
"角色": "超級管理員",
"到期時間": "2019-07-13 00:00:00"
}
- 為了防止用戶篡改數(shù)據(jù)稚疹,服務(wù)器在生成這個對象的時候,會加上簽名祭务。
- 服務(wù)器不再保存任何 session 數(shù)據(jù)内狗,也就是服務(wù)器變成無狀態(tài)了,從而比較容易實現(xiàn)擴展义锥。
- 客戶端收到服務(wù)器返回的 JWT柳沙,可以儲存在 Cookie 里面,也可以儲存在 localStorage拌倍。
此后赂鲤,客戶端每次與服務(wù)器通信,都要帶上這個 JWT柱恤。你可以把它放在 Cookie 里面自動發(fā)送蛤袒,但是這樣不能跨域,所以更好的做法是放在 HTTP 請求的頭信息Authorization字段里面膨更。
Authorization: Bearer <token>