前言
?溝通服務間接口內容(尤其是前后端接口),是非常讓人頭疼的事。極其容易扯皮。接口文檔寫起來也很痛苦,每個字段的改動都需要及時更新,否則就會出問題。服務端通信如果用rpc通信的話,一般會有proto或者thrift文件。這個文件很長時間里被我們當成接口文檔用,用著用著發現,真tm好用。既減少了扯皮,還不用寫接口文檔。那可不可以用grpc和前端通信那,一開始我們的做法是用grpc-gateway。把grpc的接口映射成http接口。但這種方式需要編譯gateway的pb文件,對服務也是有侵入的。后來隨著我在公司的時間越來越長,接手的服務越來越多(經常需要發版的項目就有十幾個),這種方式維護起來十分糟心,后一直想尋求一種一勞永逸的解決方法? ?本人之前很長一段時間從事saas,paas的開發。對于一些服務而言,既要提供grpc訪問的能力,也要對外提供http訪問的能力(做saas就是這么卑微)。并且這種需求通常不是一開始就提出來的,而是對一個已經穩定運行的龐大的服務做改造。而這會導致爬屎山,鑒權不一致等一系列問題。那有沒有一種無侵入的協議轉換能力? ? grpc是基于http2協議,而http2是長連接。這對k8s部署的服務非常不友好。在這我猜肯定有很多小伙伴說可以用linked,istio等基于Service Mesh的解決方案。一是這些技術是近兩年才穩定下來的,以前問題很多,根本不敢用,當然現在istio已經流行起來了,可以很完美的做到grpc的負載均衡和很優秀的流量管理。但依然存在不滿足實際需求的情況,比如對grpc流量做精細過濾,細到每個請求的精準控制。這種二次開發的需求是很難在istio上完成。尤其是對一些小公司而言。基于很多原因的考慮,最終誕生了搞一個grpc動態代理的想法,并初步實現。grpc
? 在云原生,容器化,微服務的大背景下。rpc也徹底奠定了服務間通信協議的霸主地位。眾多rpc框架中grpc和thrift是最流行最受歡迎的rpc框架。在實際開發中,我兩個框架都有深入的使用過。相較而言,我更喜歡grpc的風格。背靠google大樹(已經是CNCF孵化項目),多語言都支持,基于protobuf極致編碼和急速傳輸,等等優點就不一一詳述。有興趣的可以看grpc官網,上面吹的比我吹的好。實踐
github地址
https://github.com/woshihaoren4/grpc-proxy第一步
先將代碼clone下來到本地,我這里用的mac系統 因為編譯需要cargo環境,需要先安裝rust,參考教程:https://www.rust-lang.org/zh-CN/上面有很詳細的中文教程。我安裝的是:rustc 1.66.0 (69f9c33d7 2022-12-12)
版本第二步
先進入項目根目錄,運行起測試例子./example/helloworld server 沒有權限的話,需要先加權限,然后再運行 chmod +x ./example/helloworld 這個例子使用golang編寫的簡單的grpc服務,實現上沒有啥特殊的部分,值得注意的是需要給grpc服務加上反射
//grpc的HelloWorld方法實現,就是在字符串上加一個 world func (s *Service) HelloWorld(ctx context.Context, req *proto.HelloWorldRequest) (*proto.HelloWorldResponse, error) { return &proto.HelloWorldResponse{Response: req.Request + " world"}, nil } //這里相當于main函數 func server(ctx *wdevent.Context) error { ls, _ := net.Listen("tcp", ":8888") gs := grpc.NewServer() proto.RegisterHelloWorldServiceServer(gs, new(Service)) reflection.Register(gs) logrus.Infoln("grpc server start workd ....") gs.Serve(ls) return nil } 再看一下pb文件,需要注意的是在option里指明 需要映射的http的路徑和方法
syntax = "proto3"; package proto; option go_package = "./proto"; import "google/api/annotations.proto"; // HelloWorld Service service HelloWorldService { rpc HelloWorld(HelloWorldRequest) returns (HelloWorldResponse){ option (google.api.http) = { post: "/api/v2/hello" body: "*" }; }; } message HelloWorldRequest { string request = 1; } message HelloWorldResponse { string response = 1; }
第三步
修改配置文件如下,路徑:./src/config/config.toml。當前項目中的配置文件已經寫好了這些內容,不需要再配置什么了。當然不放心也可以查看一下。[[proxy_sink]] name = "hello" addr = "127.0.0.1:8888"
- 需要在addr中指明上面服務的地址和端口。
第四步
另起終端,編譯并運行項目cargo run -- run 國內沒有科學上網的話會有些慢,主要是下載包比較慢,可以用清華源或者其他的,教程參考:https://www.w3cschool.cn/cargo_guide/cargo_guide-uxdg3l62.html 服務啟動后會打印如下日志,說明服務啟動成功
測試
發起一個http請求curl --location --request POST 'http://127.0.0.1:6789/api/v2/hello' --header 'Content-Type: application/json' --data-raw '{ "request": "hello" }' 可以看到返回內容:
{"response": "hello world"}
并且在代理服務上產生訪問日志:?到這里一個簡單的演示就成功了結構和原理
主要是根據grpc的反射的描述,生成http路由,并動態完成json和proto的映射。更進一步的原理和結構,未完待續~尾語
當前版本還只是一個比較初級的版本,功能還很初級。還有很多功能需要完善,架構也可能會有大的變動,所有上一節并沒有詳細描述。作者預計但不承諾會繼續完成下面的內容。- restful支持:這個功能是P0級,在我go版本的grpc動態代理服務中經常被用到,在可預計的規劃里一定會實現。
- 事件系統:該功能是為了方便二次開發,很有必要。也有可能用中間件模式,類似traefik
- 負載均衡/sidecar:負載均衡是為了用在服務網關上,sidecar是用在pod里,二者會選一個實現,我傾向于前者,和我之前寫的rust-ingress聯動上。這里自薦一波rust-ingress項目:https://gitee.com/yutiandou/rust-ingress
- 性能優化,這個會一直持續做下去,歡迎有性能極致追求的小伙伴能夠共同前進
- 實時反射:目前是通過配置文件,在啟動的時候加載服務源。好的(懶人)方案是proto文件變化后能夠實時監控到,下一步會完成這個功能。
聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。
舉報投訴
-
通信協議
+關注
關注
28文章
879瀏覽量
40299 -
HTTP
+關注
關注
0文章
504瀏覽量
31197 -
編碼
+關注
關注
6文章
940瀏覽量
54814
原文標題:尾語
文章出處:【微信號:Rust語言中文社區,微信公眾號:Rust語言中文社區】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
特斯拉馬斯克稱在城市里搞飛行汽車是個愚蠢的想法
馬斯克稱在城市里搞飛行汽車是個愚蠢的想法。同時,他還提到了自己的地下隧道計劃,馬斯克認為這項計劃雖然也非常瘋狂,但比飛行汽車好多了。
發表于 02-18 11:24
?1118次閱讀
java的動態代理機制和作用
的我們的功能,我們更需要學習的是其底層是怎么樣的一個原理,而AOP的原理就是java的動態代理機制,所以本篇隨筆就是對java的動態機制進行
發表于 09-27 14:37
?0次下載
java動態代理機制詳解的類和接口描述
的我們的功能,我們更需要學習的是其底層是怎么樣的一個原理,而AOP的原理就是java的動態代理機制,所以本篇隨筆就是對java的動態機制進行
發表于 09-28 13:33
?0次下載
什么是動態ip代理電腦軟件?
動態IP代理計算機軟件是計算機瀏覽器和Web群集服務器之間的網絡服務器。如果使用動態IP代理計算機軟件訪問Internet,則計算機瀏覽器不會立即轉到Web網絡服務器來檢索網頁,而是僅
發表于 01-14 18:06
?975次閱讀
IP知識百科之什么是gRPC
對網絡設備進行配置和管理的一種方法。 gRPC vs REST REST(Representational State Transfer)表征狀態轉移,是一種軟件架構風格,同樣為管理和配置網絡設備提供
正確使用gRPC與GraphQL
TLDR:使用 GraphQL 進行客戶端-服務器通信,使用 gRPC 進行服務器到服務器通信。有關此規則的例外情況,請參閱“判定”部分。 我已經閱讀了很多關于這兩種協議的比較,并想寫一個
mybatis接口動態代理原理
MyBatis是一款輕量級的Java持久化框架,它通過XML或注解配置的方式,將數據庫操作與SQL語句解耦,提供了一種簡單、靈活的數據訪問方式。在MyBatis中,使用動態代理技術來
評論