Go實現簡易RPC框架的方法步驟

2022-09-29 13:45:10 字數 2636 閱讀 7846

本文旨在講述 rpc 框架設計中的幾個核心問題及其解決方法,並基於 golang 反射技術,構建了乙個簡易的 rpc 框架。

專案位址:tiny-rpc

rpcrpc(remote procedure call),即遠端過程呼叫,可以理解成,服務 a 想呼叫不在同一記憶體空間的服務 b 的函式,由於不在乙個記憶體空間,不能直接呼叫,需要通過網路來表達呼叫的語義和傳達呼叫的資料。

服務端rpc 服務端需要解決 2 個問題:

核心流程

方法註冊

服務端需要維護 rpc 函式名到 rpc 函式實體的對映,我們可以使用map資料結構來維護對映關係。

type server struct

// register a method via name

func (s *server) register(name string, f inte***ce{})

s.funcs[name] = reflect.valueof(f)

}執行呼叫

一般來說,客戶端在呼叫 rpc 時,會將 函式名 和 引數列表 作為請求資料,傳送給服務端。

由於我們使用了map[string]reflect.value來維護函式名與函式實體之間的對映,則我們可以通過value.call()來呼叫與函式名相對應的函式。

package main

import (

"fmt"

"reflect"

)func main()

vals := funcs["add"].call(req)

var rsp inte***ce{}

for _, val := range vals

fmt.println(rsp)

}func add(a, b int) (int,

具體實現

由於篇幅的限制,此處沒有貼出服務端實現的具體**,細節請檢視專案位址。

客戶端rpc 客戶端需要解決 1 個問題:

核心流程

生成呼叫

我們可以通過 reflect.makefunc 為指定的函式原型繫結乙個函式實體。

package main

import (

"fmt"

"reflect"

)func main()

} var addptr func(int, int) int

container := reflect.valueof(&addptr).elem()

v := reflect.makefunc(container.type(), add)

container.set(v)

fmt.println(addptr(1, 2))

}具體實現

由於篇幅的限制,此處沒有貼出客戶端實現的具體**,細節請檢視專案位址。

資料傳輸格式

我們需要定義服務端與客戶端互動的資料格式。

type data struct // request's or response's body except error

err string // remote server error

}與互動資料相對應的編碼與解碼函式。

func encode(data data) (byte, error)

return buf.bytes(), nil

}func decode(b byte) (data, error) , err

} return data, nil

}同時,我們需要定義簡單的 tlv 協議(固定長度訊息頭 + 變長訊息體),規範資料的傳輸。

// transport struct

type transport struct

// newtransport creates a transport

func newtransport(conn net.conn) *transport

}// send data

func (t *transport) send(req data) error

buf := make(byte, 4+len(b))

binary.bigendian.putuint32(buf[:4], uint32(len(b))) // set header field

copy(buf[4:], b) // set data field

_, err = t.conn.write(buf)

return err

}// receive data

func (t *transport) receive() (data, error) , err

} datalen := binary.bigendian.uint32(header) // read header filed

data := make(byte, data程式設計客棧len) // read data field

_, err = io.readfull(t.conn, data)

if err != nil , err

} rsp, err := decode(data) // decode rsp from bytes

return rsp, err

}本文標題: go實現簡易rpc框架的方法步驟

本文位址:

實現基於springboot的RPC框架(序)

rpc框架大家或多或少都用過,出自於阿里系的就有dubbo,hsf,sofarpc等。但是,要深入理解rpc的原理卻不容易,其中光是核心部分,就涉及到動態 netty,服務註冊與發現,序列化,多執行緒等等。筆者為了弄清楚rpc框架的大致呼叫實現原理,自己造了個輪子 zrpc.首先,筆者寫這個rpc框...

Golang實現自己的RPC框架

rpc session.go package rpc import encoding binary io net 編寫資料會話中讀寫 會話連線的結構體 type session struct 建立新連線 func newsession conn net.conn session 向連線中寫資料 fu...

最簡單的Rpc框架的實現

平時用到接觸的都很少,每次用過之後就忘記,所以要想真正的達到拿來就用的境界那就 刻意練習 吧 下面介紹。寫不動。就寫寫自己的理解 主要的角色有一下幾種 服務提供者 執行在服務端,負責提供介面定義和服務實現類。其實就像現實生活中專門提供服務的,比如說酒店提供的服務是休息睡覺,飯店提供的服務是解決溫飽 ...