您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關java中dubbo-go有什么用,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
2020年是我司發展壯大的一年,整個公司團隊由原來的幾百人擴充至現在的幾千人,在集中使用的時候基本上會有幾千人同時在運營后臺進行操作,公司原有的內部后臺運營系統是用PHP搭建起來的,性能跟業務上已逐漸不能滿足公司的需求規劃,加上目前我司開發部已經做了微服務拆分,主體對外服務是java語言的Dubbo集群,后臺系統需要無縫對接java的Dubbo服務,所以PHP已經逐漸不能滿足我司的需求。
當時自己也調研過PHP的Dubbo項目,由于項目已基本無人更新維護所以pass掉,后面自己對簡潔高性能的go語言感興趣,然后就關注到了Dubbo-go項目,經過一段時間的調研之后發現Dubbo Go 符合我們的業務需要,并且社區非常的活躍,后面便決定選用 Dubbo-go 作為后臺的 pc 業務框架。
可能也有同學會問為什么不使用跨言支持程度更好的 gRPC 呢,因為很多公司最開始的 RPC 服務集群都是基于Dubbo 生態構建的,如果換框架成本太大,所以基本不會考慮,gRPC 雖然跨語言支持程度更好但是很多東西都需要自己造輪子,比如服務注冊,服務發現,日志監控等。
當時在決定選用 Dubbo-go 的時候開發內部也有一些反對的聲音的,為什么不直接轉 java,轉 java 的話就沒有跨語言通信的問題了,轉 java 的問題在于入門成本高,而且對于整個公司的技術棧來說,保持語言的多樣性,才能更加從容的應對未來的業務變化,Go 本身是一個不弱于 Java 的高性能語言,非常適合微服務架構。
確定了框架選型后,我接到的首要任務便是要搭建出一套可快速創建業務項目的腳手架,開發出基于 HTTP 協議的RPC 代理服務,部署需要接入公司的容器化部署平臺,一切都是從零開始,在網上基本上找不到可以借鑒的資料。 首先是要進行 Dubbo-go 項目的架構的規劃,確定項目目錄結構,經過參考 Dubbo-go Demo以及其它的 Go 項目最終確定了項目的目錄結構,以下目錄結構可作為參考。
為了與 Java服務注冊中心保持一致,Dubbo-go 在項目選型上選用如下組件:
使用 zookeeper 作為注冊中心
nacos 作為配置中心
數據庫 orm 采用 gorm
消息隊列使用 RocketMQ
為了增加開發的效率我們在 provider 服務初始化前可以對配置進行精簡只保留最基礎的配置就可以類似下面這種,provider 服務的編碼參考 Dubbo-go demo 就可以了
下面是服務啟動的main方法代碼
一般使用 Dubbo,provider 端需要暴露出接口和方法,consumer 端要十分明確服務使用的接口定義和方法定義,還有入參返參類型等等信息,還需要基于provider端提供的 API,兩端才能正常通信調用。
然而網關的使用場景是并不關心要調用的接口的詳細定義,網關只關注要調用的方法、傳遞的參數、能接收返回結果就可以了,實現網關代理的基礎是 Dubbo/Dubbo-go 的泛化調用特性。
下面是 Dubbo-go 官方給的 demo,泛化服務加載后需要等待 3 秒才能完成調用,然而在實際使用的時候肯定是不能實時加載服務去等待 3 秒,所以在網關應用啟動時就需要加載緩存好需要泛化調的服務。
經過對 Dubbo-go 泛化調用 demo 的研究,發現用該特性設計 dubbo-go 網關是可行的,難點在于我們需要把每一個需要網關代理 RPC 服務方法的參數以及服務的路徑等配置獲取到并緩存起來,這樣才能在調用前初始化好泛化調用服務,一個服務的配置如下。
由于是用 go 語言做的網關代理,所以不能通過 Java 的 jar 包來獲取到 Java RPC 服務配置,如果通過人工維護的話工作量太大,而且易出錯,顯然是不可接受的。經過一段時間的了解,Java 服務可以通過注解來實現配置的獲取,Java 端在方法上加上注解后啟動服務的時候會將配置信息通過消息發送到 MQ,網關消費這些消息來實現獲取Java RPC 服務的配置
Dubbo Go 的 RPC 服務由于 go 語言不支持注解,所以我經過思考自己寫了一個掃描代碼的小工具,在每個 RPC 服務方法前加上對應的注釋,通過對注釋的掃描來獲取 RPC 服務的配置,獲取到配置后在項目目錄內生成 RPC 服務配置,啟動應用的時候讀取配置發送到 MQ。
網關代理實現之后還可以在網關的基礎實現更多的功能,比如 token驗證、白名單、限流、熔斷、日志監控功能,網關代理請求實現效果如下:
公司內部的容器化部署環境為阿里云的 k8s,部署至 k8s 平臺只需要提供鏡像文件,由于 Dubbo-go 編譯后是一個二進制的文件,不需任何額外的第三方庫,能在 Docker 環境下穩定運行。有 docker 鏡像文件如下圖所示,可以用 centos 等任一 linux 發行版作為 base 鏡像。
LABEL maintainer="<xxx@xx.com>" LABEL version="1.0" LABEL description="KKL-GO-NKO-BASE"` ARG envType=stable #設置環境變量 ENV envType ${envType} #編譯打包好的壓縮包 ADD ./target/nko-base-${envType}.tar.gz /app/ WORKDIR /app EXPOSE 20000
鏡像寫好后提供給發布平臺,發布平臺機器啟動鏡像并解壓打包文件,執行Dubbo-Go程序 。
Container entrypoint set to [bash, -c, tar -zxf nko-base-stable.tar.gz && SERVER_ENV=kubernetes && sh ./nko-base/bin/load.sh start -group=stable]
由于開發測試到生產一般是有多個部署環境的,所以我們需要改動的 dubbo-go samples demo【見相關鏈接 1】 里的編譯腳本,讓其支持多環境打包。
另外,Dubbo-go 默認注冊的 IP 是 k8s pod 的虛擬 IP,不同 k8s 集群之間網絡是不能互通的,所以如果需要跨集群調用就需要修改默認注冊 IP,將默認注冊的 pod IP + 端口 修改為 kubernetes 實體機的 IP 加對應端口,kubernetes 會在 pod 內寫入實體機的 IP 加對應端口環境變量,應用程序可以通過讀取環境變量獲取實體機的 IP加端口,如果需要實現此功能需要修改 Dubbo-go 的注冊邏輯。例如以 zookeeper 注冊中心為例,我們可以通過擴展 registery/zookeeper/registry.go的registerTempZookeeperNode 方法來實現修改注冊 IP 跟端口,代碼如下圖,Dubbo-go 官方將在后面的版本以配置的形式支持自定義注冊 IP 跟端口的功能。
func (r *zkRegistry) registerTempZookeeperNode(root string, node string) error { ... regIp = os.Getenv(constant2.RegistryEnvIP) //實體機的ip regPort = os.Getenv(constant2.RegistryEnvPort) //實體機的端口 urlNode, _ := common.NewURL(node) role, _ := strconv.Atoi(urlNode.GetParam(constant.ROLE_KEY, "")) if role == common.PROVIDER && regIp != "" && regPort != "" { urlNode.Ip = regIp urlNode.Port = regPort node = url.QueryEscape(urlNode.String()) } zkPath, err = r.client.RegisterTemp(root, node) ... }
關于“java中dubbo-go有什么用”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,使各位可以學到更多知識,如果覺得文章不錯,請把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。