0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

搞一個grpc動態(tài)代理的想法,并初步實現(xiàn)

jf_wN0SrCdH ? 來源:Rust語言中文社區(qū) ? 2023-02-08 16:13 ? 次閱讀

前言

?溝通服務(wù)間接口內(nèi)容(尤其是前后端接口),是非常讓人頭疼的事。極其容易扯皮。接口文檔寫起來也很痛苦,每個字段的改動都需要及時更新,否則就會出問題。服務(wù)端通信如果用rpc通信的話,一般會有proto或者thrift文件。這個文件很長時間里被我們當成接口文檔用,用著用著發(fā)現(xiàn),真tm好用。既減少了扯皮,還不用寫接口文檔。那可不可以用grpc和前端通信那,一開始我們的做法是用grpc-gateway。把grpc的接口映射成http接口。但這種方式需要編譯gateway的pb文件,對服務(wù)也是有侵入的。后來隨著我在公司的時間越來越長,接手的服務(wù)越來越多(經(jīng)常需要發(fā)版的項目就有十幾個),這種方式維護起來十分糟心,后一直想尋求一種一勞永逸的解決方法? ?本人之前很長一段時間從事saas,paas的開發(fā)。對于一些服務(wù)而言,既要提供grpc訪問的能力,也要對外提供http訪問的能力(做saas就是這么卑微)。并且這種需求通常不是一開始就提出來的,而是對一個已經(jīng)穩(wěn)定運行的龐大的服務(wù)做改造。而這會導致爬屎山,鑒權(quán)不一致等一系列問題。那有沒有一種無侵入的協(xié)議轉(zhuǎn)換能力? ? grpc是基于http2協(xié)議,而http2是長連接。這對k8s部署的服務(wù)非常不友好。在這我猜肯定有很多小伙伴說可以用linked,istio等基于Service Mesh的解決方案。一是這些技術(shù)是近兩年才穩(wěn)定下來的,以前問題很多,根本不敢用,當然現(xiàn)在istio已經(jīng)流行起來了,可以很完美的做到grpc的負載均衡和很優(yōu)秀的流量管理。但依然存在不滿足實際需求的情況,比如對grpc流量做精細過濾,細到每個請求的精準控制。這種二次開發(fā)的需求是很難在istio上完成。尤其是對一些小公司而言?;诤芏嘣虻目紤],最終誕生了搞一個grpc動態(tài)代理的想法,并初步實現(xiàn)。

grpc

? 在云原生,容器化,微服務(wù)的大背景下。rpc也徹底奠定了服務(wù)間通信協(xié)議的霸主地位。眾多rpc框架中g(shù)rpc和thrift是最流行最受歡迎的rpc框架。在實際開發(fā)中,我兩個框架都有深入的使用過。相較而言,我更喜歡grpc的風格。背靠google大樹(已經(jīng)是CNCF孵化項目),多語言都支持,基于protobuf極致編碼和急速傳輸,等等優(yōu)點就不一一詳述。有興趣的可以看grpc官網(wǎng),上面吹的比我吹的好。

實踐

github地址

https://github.com/woshihaoren4/grpc-proxy

第一步

先將代碼clone下來到本地,我這里用的mac系統(tǒng) 因為編譯需要cargo環(huán)境,需要先安裝rust,參考教程:https://www.rust-lang.org/zh-CN/上面有很詳細的中文教程。我安裝的是:rustc 1.66.0 (69f9c33d7 2022-12-12)版本

第二步

先進入項目根目錄,運行起測試例子

	
		./example/helloworld server 沒有權(quán)限的話,需要先加權(quán)限,然后再運行 chmod +x ./example/helloworld
		這個例子使用golang編寫的簡單的grpc服務(wù),實現(xiàn)上沒有啥特殊的部分,值得注意的是需要給grpc服務(wù)加上反射

	//grpc的HelloWorld方法實現(xiàn),就是在字符串上加一個 world func (s *Service) HelloWorld(ctx context.Context, req *proto.HelloWorldRequest) (*proto.HelloWorldResponse, error) { return &proto.HelloWorldResponse{Response: req.Request + " world"}, nil } //這里相當于main函數(shù) 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。當前項目中的配置文件已經(jīng)寫好了這些內(nèi)容,不需要再配置什么了。當然不放心也可以查看一下。

	[[proxy_sink]] name = "hello" addr = "127.0.0.1:8888"
  • 需要在addr中指明上面服務(wù)的地址和端口。

第四步

另起終端,編譯并運行項目

	
		cargo run -- run
		國內(nèi)沒有科學上網(wǎng)的話會有些慢,主要是下載包比較慢,可以用清華源或者其他的,教程參考:https://www.w3cschool.cn/cargo_guide/cargo_guide-uxdg3l62.html 服務(wù)啟動后會打印如下日志,說明服務(wù)啟動成功f79e9010-a787-11ed-bfe3-dac502259ad0.png

測試

發(fā)起一個http請求

	
		curl --location --request POST 'http://127.0.0.1:6789/api/v2/hello'  --header 'Content-Type: application/json' --data-raw '{ "request": "hello" }'
		可以看到返回內(nèi)容:{"response": "hello world"}并且在代理服務(wù)上產(chǎn)生訪問日志:f7b5da68-a787-11ed-bfe3-dac502259ad0.png?到這里一個簡單的演示就成功了

結(jié)構(gòu)和原理

主要是根據(jù)grpc的反射的描述,生成http路由,并動態(tài)完成json和proto的映射。更進一步的原理和結(jié)構(gòu),未完待續(xù)~

尾語

當前版本還只是一個比較初級的版本,功能還很初級。還有很多功能需要完善,架構(gòu)也可能會有大的變動,所有上一節(jié)并沒有詳細描述。作者預計但不承諾會繼續(xù)完成下面的內(nèi)容。
  • restful支持:這個功能是P0級,在我go版本的grpc動態(tài)代理服務(wù)中經(jīng)常被用到,在可預計的規(guī)劃里一定會實現(xiàn)。
  • 事件系統(tǒng):該功能是為了方便二次開發(fā),很有必要。也有可能用中間件模式,類似traefik
  • 負載均衡/sidecar:負載均衡是為了用在服務(wù)網(wǎng)關(guān)上,sidecar是用在pod里,二者會選一個實現(xiàn),我傾向于前者,和我之前寫的rust-ingress聯(lián)動上。這里自薦一波rust-ingress項目:https://gitee.com/yutiandou/rust-ingress
  • 性能優(yōu)化,這個會一直持續(xù)做下去,歡迎有性能極致追求的小伙伴能夠共同前進
  • 實時反射:目前是通過配置文件,在啟動的時候加載服務(wù)源。好的(懶人)方案是proto文件變化后能夠?qū)崟r監(jiān)控到,下一步會完成這個功能。
歡迎有興趣的小伙伴提出建議,并熱烈歡迎大家參與進來。

審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 通信協(xié)議
    +關(guān)注

    關(guān)注

    28

    文章

    899

    瀏覽量

    40348
  • HTTP
    +關(guān)注

    關(guān)注

    0

    文章

    510

    瀏覽量

    31357
  • 編碼
    +關(guān)注

    關(guān)注

    6

    文章

    951

    瀏覽量

    54882

原文標題:尾語

文章出處:【微信號:Rust語言中文社區(qū),微信公眾號:Rust語言中文社區(qū)】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏

    評論

    相關(guān)推薦

    GRPC的基礎(chǔ)使用方法

    語言的 gRPC 客戶端和服務(wù)器實現(xiàn),它提供了簡單易用的 API,可以方便地創(chuàng)建和使用 gRPC 服務(wù)。 基礎(chǔ)用法 創(chuàng)建
    的頭像 發(fā)表于 09-19 16:08 ?966次閱讀

    JDK動態(tài)代理的原理

    在Java中,動態(tài)代理種機制,允許在運行時動態(tài)地創(chuàng)建代理對象來代替某個實際對象,從而在其前后執(zhí)行額外的邏輯。 為什么JDK
    的頭像 發(fā)表于 09-30 10:51 ?597次閱讀

    特斯拉馬斯克稱在城市里飛行汽車是愚蠢的想法

    馬斯克稱在城市里飛行汽車是愚蠢的想法。同時,他還提到了自己的地下隧道計劃,馬斯克認為這項計劃雖然也非常瘋狂,但比飛行汽車好多了。
    發(fā)表于 02-18 11:24 ?1123次閱讀

    java的動態(tài)代理機制和作用

    的我們的功能,我們更需要學習的是其底層是怎么樣的原理,而AOP的原理就是java的動態(tài)代理機制,所以本篇隨筆就是對java的動態(tài)機制進行
    發(fā)表于 09-27 14:37 ?0次下載

    java動態(tài)代理分析

    定義:為其他對象提供代理以控制對這個對象的訪問。 動態(tài)代理使用 java動態(tài)代理機制以巧妙的
    發(fā)表于 09-27 15:14 ?0次下載

    java動態(tài)代理機制詳解的類和接口描述

    的我們的功能,我們更需要學習的是其底層是怎么樣的原理,而AOP的原理就是java的動態(tài)代理機制,所以本篇隨筆就是對java的動態(tài)機制進行
    發(fā)表于 09-28 13:33 ?0次下載

    java的動態(tài)代理

    代理類的對象與委托類的對象關(guān)聯(lián),代理類的對象本身并不真正實現(xiàn)服務(wù),而是通過調(diào)用委托類的對象的相關(guān)方法,來提供特定的服務(wù)。 按照
    發(fā)表于 03-12 14:12 ?0次下載

    基于JDK和CGLB分別實現(xiàn)動態(tài)代理

    本文檔內(nèi)容介紹了基于JDK和CGLB分別實現(xiàn)動態(tài)代理及源代碼
    發(fā)表于 03-12 14:56 ?0次下載

    什么是動態(tài)ip代理電腦軟件?

    動態(tài)IP代理計算機軟件是計算機瀏覽器和Web群集服務(wù)器之間的網(wǎng)絡(luò)服務(wù)器。如果使用動態(tài)IP代理計算機軟件訪問Internet,則計算機瀏覽器不會立即轉(zhuǎn)到Web網(wǎng)絡(luò)服務(wù)器來檢索網(wǎng)頁,而是僅
    發(fā)表于 01-14 18:06 ?981次閱讀
    什么是<b class='flag-5'>動態(tài)</b>ip<b class='flag-5'>代理</b>電腦軟件?

    IP知識百科之什么是gRPC

    對網(wǎng)絡(luò)設(shè)備進行配置和管理的種方法。 gRPC vs REST REST(Representational State Transfer)表征狀態(tài)轉(zhuǎn)移,是種軟件架構(gòu)風格,同樣為管理和配置網(wǎng)絡(luò)設(shè)備提供
    的頭像 發(fā)表于 11-16 15:13 ?3308次閱讀

    gRPC-Web訪問gRPC服務(wù)的Web客戶端

    ./oschina_soft/grpc-web.zip
    發(fā)表于 06-22 09:25 ?0次下載
    <b class='flag-5'>gRPC</b>-Web訪問<b class='flag-5'>gRPC</b>服務(wù)的Web客戶端

    正確使用gRPC與GraphQL

    TLDR:使用 GraphQL 進行客戶端-服務(wù)器通信,使用 gRPC 進行服務(wù)器到服務(wù)器通信。有關(guān)此規(guī)則的例外情況,請參閱“判定”部分。 我已經(jīng)閱讀了很多關(guān)于這兩種協(xié)議的比較,想寫
    的頭像 發(fā)表于 12-08 15:47 ?1129次閱讀

    Golang實現(xiàn)簡單的http代理

    本文詳細介紹了Golang 實現(xiàn) http 代理實現(xiàn),在實際業(yè)務(wù)中有需求的同學可以學起來了!
    的頭像 發(fā)表于 04-10 11:29 ?1470次閱讀

    mybatis接口動態(tài)代理原理

    MyBatis是款輕量級的Java持久化框架,它通過XML或注解配置的方式,將數(shù)據(jù)庫操作與SQL語句解耦,提供了種簡單、靈活的數(shù)據(jù)訪問方式。在MyBatis中,使用動態(tài)代理技術(shù)來
    的頭像 發(fā)表于 12-03 11:52 ?973次閱讀

    使用go語言實現(xiàn)grpc攔截器

    在開發(fā)grpc服務(wù)時,我們經(jīng)常會遇到些通用的需求,比如:日志、鏈路追蹤、鑒權(quán)等。這些需求可以通過grpc攔截器來實現(xiàn)。本文使用go語言來實現(xiàn)
    的頭像 發(fā)表于 12-18 10:13 ?714次閱讀
    使用go語言<b class='flag-5'>實現(xiàn)</b><b class='flag-5'>一</b><b class='flag-5'>個</b><b class='flag-5'>grpc</b>攔截器