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