距離上一篇文章居然已經過去兩個月了,畢竟苦逼打工人忙得一點空都沒有……
本文我們來講一講對於微服務架構來説,最重要的一個點了:服務發現及其對應的名字服務功能。
系列文章
- 騰訊 tRPC-Go 教學——(1)搭建服務
- 騰訊 tRPC-Go 教學——(2)trpc HTTP 能力
- 騰訊 tRPC-Go 教學——(3)微服務間調用
- 騰訊 tRPC-Go 教學——(4)tRPC 組件生態和使用
- 騰訊 tRPC-Go 教學——(5)filter、context 和日誌組件
- 騰訊 tRPC-Go 教學——(6)服務發現
- 騰訊 tRPC-Go 教學——(7)服務配置和指標上報
- 騰訊 tRPC-Go 教學——(8)通過泛 HTTP 能力實現和觀測 MCP 服務
概述
在 之前的文章 中我們提到,微服務之間調用時,我們需要在 client 中配置微服務的下游服務,這樣 tRPC 才知道如何尋址。
在那篇文章的例子中,我們把 target 字段的值配置為: ip://127.0.0.1:8002。這是一個 IP,指向型非常強的 IP 地址。但是直接指定下游服務的 IP 地址有幾個問題:
- 在微服務集羣中,一個服務可能有多個節點,只配置一個 IP 不能滿足業務主備的需求,也無法實現一致性哈希等複雜的尋址能力
- 隨着服務節點的持續伸縮,服務的 IP 列表是經常變化的,固定的 IP 配置不能滿足需求
tRPC 的名字服務
一個成熟的微服務框架,一般是通過名字服務來解決這個問題的。也就是説,一個微服務在調用其他微服務時,指定的不是 IP 地址,而是一個服務的名字。通過一系列的中間件將名字換成真實可觸達的 IP 地址。
在 tRPC 中提供了自定義名字服務的能力。如果要自開發名字服務,那麼在 tRPC 框架中,至少需要實現對應的 selector 和 registry 兩個能力(文檔)。筆者嘗試着實現過一個極為簡陋的 基於 MySQL 的名字服務,對於感興趣的讀者,可以藉由這個 package 瞭解一下。
本文不專注原理而是注重應用。在騰訊內部,絕大部分的 tRPC 微服務之間使用 北極星 名字服務。本文我們就以北極星名字服務為例子,説明如何在 tRPC 上應用一個實際可操作的名字服務。
北極星簡介
騰訊內部的北極星系統,是一個以名字服務為主業的系統。儘管 外網開源版 似乎功能更多,但是作為主業的服務治理,內外網版差別不大。
北極星系統的搭建和就請讀者查閲北極星的文檔了。作為教學目的,本文以筆者使用 Docker 在本地安裝的北極星系統為例,我們訪問北極星頁面並登錄,可以看到初始頁面:
看到兩個北極星自己的服務,可以不用管。接下來,按照正常流程,我們可以點新建按鈕,新建一個服務名字:
不過 Docker 版的北極星其實也可以略過這一步。因此我們直接進行下一階段:tRPC 服務的配置
tRPC 服務啓動配置
我們還是按照前面幾篇文章所描述的 http-auth 和 user 兩個服務來講述,一個是主調方,另一個是被調方。先看看 user 服務吧。
代碼中引用 tRPC 北極星支持
要在服務中啓用北極星支持,tRPC 的標準用法是在 main 包中匿名導入北極星的 package:
import (
// ......
_ "trpc.group/trpc-go/trpc-naming-polarismesh"
)
邏輯上,這個包會在 init() 階段調用 tRPC 的相關 RegisterXXXX 函數,將北極星的名字服務、負載均衡等功能註冊到 tRPC 中。
trpc_go.yaml 文件配置
前面 import 是為了在二進制中支持北極星。為了啓動北極星,我們還需要給 tRPC 服務相關的配置。對於作為被調方的 user 服務而言,我們需要在它的 trpc_go.yaml 文件 中,增加以下配置:
plugins:
## plugins 項下的其他值略過
registry:
polarismesh:
register_self: true
heartbeat_interval: 1000
protocol: grpc
address_list: host.docker.internal:8091
service:
- name: demo.account.User
namespace: dev
weight: 100
token: not_needed
其中 address_list: host.docker.internal:8091 指的是北極星服務的地址, 因為我是使用 Docker 部署的,北極星的註冊服務默認監聽在 8091 端口上。
使用該配置啓動 user 服務。然後我們回到北極星主頁,刷新一下:
可以看到多了一個 demo.account.User 服務。進入這個服務的詳情頁我們可以看到服務監聽的配置情況:
按照上面的默認配置,則北極星會根據 server 的配置判斷當前服務監聽在哪個地址、哪個端口上。其中 name 和 namespace 字段為必填。
目前 user 服務的配置為:
server:
filter:
- tracelog
service:
- name: demo.account.User
nic: eth0
port: 8002
network: tcp
protocol: trpc
timeout: 1800
可以看到根據配置,監聽在網卡 eth0、端口 8002。北極星獲取該信息之後則註冊到名字服務上。
尋址
好,現在我們回到作為主調方的 http-auth 服務。主調方也一樣需要在代碼中 import 同一個北極星 package。但作為主調方,則需要在 trpc_go.yaml 中添加以下配置:
plugins:
## plugins 項下的其他值略過
selector:
polarismesh:
protocol: grpc
join_point: default
address_list: host.docker.internal:8091
persistDir: ./polarismesh/backup
log_dir: ./polarismesh/log
配置項 selector 指定的是作為名字選擇器的北極星能力。其中 address_list 項,與前文 registry 的配置含義相同。
接着,在調用 user 服務時,我們放棄之前的 ip://xxxx 寫法,改為以下格式:
client:
filter:
- tracelog
service:
- name: demo.account.User
target: polarismesh://demo.account.User
namespace: dev
network: tcp
protocol: trpc
timeout: 1000
同樣地,我們以這個 trpc_go.yaml 啓動 http-auth 服務,然後還是參照前文,請求 http-auth 的方法:
curl '172.17.0.7:8001/demo/auth/Login?username=amc'
獲得錯誤響應:
{"err_code":10001,"err_msg":"密碼錯誤"}
按照這兩個服務的邏輯,這個時候我們可以很清楚地知道,這個錯誤碼,説明 http-auth -> user -> MySQL 的這一條鏈路已經通了。我們也可以從這兩個服務的日誌上看到。
其他注意項
至此,使用北極星進行名字服務註冊、發現的功能就介紹完了。至此的內容,讀者已經可以完整地構建一個微服務集羣,集羣之間的每一個微服務能夠自行靈活伸縮而不互相(包括在配置上)耦合;每一個微服務也可以通過多點互備來實現容災。
不過此外,有一個需要注意的點。如果簡單地用 go build 命令編譯的話,啓動服務時可能會出現以下錯誤:
panic: proto: file "auth.proto" is already registered
See https://protobuf.dev/reference/go/faq#namespace-conflict
這是因為 gRPC 的一些 proto 同名文件重複註冊導致。這個問題如果不好解決的話,可以在編譯時添加 -ldflags "-X google.golang.org/protobuf/reflect/protoregistry.conflictPolicy=warn" 參數解決。具體的話讀者可以參見我的 demo 工程的 Makefile 規則
下一步
本系列文章居然已經第六篇了……對於 tRPC 基本功能來説,還差一個配置和監控沒講。
在騰訊內部,使用口碑最好的配置系統被稱為 “七彩石”,這個系統對外提供商業化的私有化部署方案,本身並未開源。而口碑最好的監控系統成為 “伽利略”,這個系統也沒有對外開源。
因此接下來的這兩個話題,講述起來比較麻煩,因為兩個被受歡迎的系統未對外開源的緣故,導致在外網中基本上不可能擁有在內網一模一樣的體驗。下一篇文章,筆者打算簡單介紹一下接入方式,並且講述如何建立一個最為簡陋、最為簡單的配置和監控(展示)方案,快速跳過這一部份吧。
本文章採用 知識共享署名-非商業性使用-相同方式共享 4.0 國際許可協議 進行許可。
原作者: amc,原文發佈於騰訊雲開發者社區,也是本人的博客。歡迎轉載,但請註明出處。
原文標題:《騰訊 tRPC-Go 教學——(6)服務發現》
發佈日期:2024-05-01
原文鏈接:https://cloud.tencent.com/developer/article/2414446。