服务中没有listen_Go语言微服务框架实战:2.Go语言实现RPC编程绍
Go語言實現RPC編程
@author:Davie 版權所有:北京千鋒互聯科技有限公司
上節課我們對RPC知識做了介紹,講解了RPC的原理,通過圖示方式講解了RPC的內部執行過程。本節課,我們繼續來學習RPC相關的內容。
RPC官方庫
在Go語言官方網站的pkg說明中,提供了官方支持的rpc包,具體鏈接如下:https://golang.org/pkg/net/rpc/。官方提供的rpc包完整的包名是:net/rpc。根據官方的解釋,rpc包主要是提供通過網絡訪問一個對象方法的功能。
本節課,我們就來學習如何使用go語言官方提供的RPC包實現RPC調用編碼。
net/rpc庫實現RPC調用編程
前文我們已經講過rpc調用有兩個參與者,分別是:客戶端(client)和服務器(server)。
首先是提供方法暴露的一方--服務器。
一、服務定義及暴露
在編程實現過程中,服務器端需要注冊結構體對象,然后通過對象所屬的方法暴露給調用者,從而提供服務,該方法稱之為輸出方法,此輸出方法可以被遠程調用。當然,在定義輸出方法時,能夠被遠程調用的方法需要遵循一定的規則。我們通過代碼進行講解:
func (t *T) MethodName(request T1,response *T2) error上述代碼是go語言官方給出的對外暴露的服務方法的定義標準,其中包含了主要的幾條規則,分別是: 1、對外暴露的方法有且只能有兩個參數,這個兩個參數只能是輸出類型或內建類型,兩種類型中的一種。 2、方法的第二個參數必須是指針類型。 3、方法的返回類型為error。 4、方法的類型是可輸出的。 * 5、方法本身也是可輸出的。
我們舉例說明:假設目前我們有一個需求,給出一個float類型變量,作為圓形的半徑,要求通過RPC調用,返回對應的圓形面積。具體的編程實現思路如下:
type MathUtil struct{ } //該方法向外暴露:提供計算圓形面積的服務 func (mu *MathUtil) CalculateCircleArea(req float32, resp *float32) error {*resp = math.Pi * req * req //圓形的面積 s = π * r * rreturn nil //返回類型 }在上述的案例中,我們可以看到: 1、Calculate方法是服務對象MathUtil向外提供的服務方法,該方法用于接收傳入的圓形半徑數據,計算圓形面積并返回。 2、第一個參數req代表的是調用者(client)傳遞提供的參數。 3、第二個參數resp代表要返回給調用者的計算結果,必須是指針類型。 4、正常情況下,方法的返回值為是error,為nil。如果遇到異常或特殊情況,則error將作為一個字符串返回給調用者,此時,resp參數就不會再返回給調用者。
至此為止,已經實現了服務端的功能定義,接下來就是讓服務代碼生效,需要將服務進行注冊,并啟動請求處理。
二、注冊服務及監聽請求
net/rpc包為我們提供了注冊服務和處理請求的一系列方法,結合本案例實現注冊及處理邏輯,如下所示:
//1、初始化指針數據類型 mathUtil := new(MathUtil) //初始化指針數據類型//2、調用net/rpc包的功能將服務對象進行注冊 err := rpc.Register(mathUtil) if err != nil {panic(err.Error()) }//3、通過該函數把mathUtil中提供的服務注冊到HTTP協議上,方便調用者可以利用http的方式進行數據傳遞 rpc.HandleHTTP()//4、在特定的端口進行監聽 listen, err := net.Listen("tcp", ":8081") if err != nil {panic(err.Error()) } go http.Serve(listen, nil)經過服務注冊和監聽處理,RPC調用過程中的服務端實現就已經完成了。接下來需要實現的是客戶端請求代碼的實現。
三、客戶端調用
在服務端是通過Http的端口監聽方式等待連接的,因此在客戶端就需要通過http連接,首先與服務端實現連接。
- 客戶端連接服務端go client, err := rpc.DialHTTP("tcp", "localhost:8081") if err != nil { panic(err.Error()) }
- 遠端方法調用 客戶端成功連接服務端以后,就可以通過方法調用調用服務端的方法,具體調用方法如下:
```go var req float32 //請求值 req = 3
var resp float32 //返回值 err = client.Call("MathUtil.CalculateCircleArea", req, &resp) if err != nil { panic(err.Error()) } fmt.Println(resp) ```
上述的調用方法核心在于client.Call方法的調用,該方法有三個參數,第一個參數表示要調用的遠端服務的方法名,第二個參數是調用時要傳入的參數,第三個參數是調用要接收的返回值。 上述的Call方法調用實現的方式是同步的調用,除此之外,還有一種異步的方式可以實現調用。異步調用代碼實現如下:go var respSync *float32 //異步的調用方式 syncCall := client.Go("MathUtil.CalculateCircleArea", req, &respSync, nil) replayDone := <-syncCall.Done fmt.Println(replayDone) fmt.Println(*respSync)
多參數的請求調用參數傳遞
上述內容演示了單個參數下的RPC調用,對于多參數下的請求該如何實現。我們通過另外一個案例進行演示。
假設現在需要實現另外一個需求:通過RPC調用實現計算兩個數字相加功能并返回計算結果。此時,就需要傳遞兩個參數,具體實現如下:
將參數定義在一個新的結構體中,存放在param包中:
type AddParma struct {Args1 float32 //第一個參數Args2 float32 //第二個參數 }在server.go文件中,實現兩數相加的功能,并實現服務注冊的邏輯:
func (mu *MathUtil) Add(param param.AddParma, resp *float32) error {*resp = param.Args1 + param.Args2 //實現兩數相加的功能return nil } mathUtil := new(MathUtil)err := rpc.RegisterName("MathUtil", mathUtil)if err != nil {panic(err.Error())}rpc.HandleHTTP()listen, err := net.Listen("tcp", ":8082")http.Serve(listen, nil)在本案例中,我們通過新的注冊方法rpc.RegisterName實現了服務的注冊和調用。
至此,我們已經完成了net/rpc包的最基礎的使用。
總結
以上是生活随笔為你收集整理的服务中没有listen_Go语言微服务框架实战:2.Go语言实现RPC编程绍的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 已知旋转矩阵求角度_如何推导旋转矩阵
- 下一篇: python rpc_python与RP