日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

利用Go傳統(tǒng)RPC和gRPC框架分別實現(xiàn)一個RPC服務(wù)端

來源: 責(zé)編: 時間:2024-01-02 17:28:11 232觀看
導(dǎo)讀1.RPC原理介紹RPC(Remote Procedure Call, 遠程過程調(diào)用) 是一種計算機通信協(xié)議, 它允許程序調(diào)用另一個地址空間(通常是遠程機器上的)的過程或函數(shù), 就像本地調(diào)用一樣, 而不需要顯示地處理網(wǎng)絡(luò)通信的細節(jié)。RPC使得分

1.RPC原理介紹

Eeb28資訊網(wǎng)——每日最新資訊28at.com

RPC(Remote Procedure Call, 遠程過程調(diào)用) 是一種計算機通信協(xié)議, 它允許程序調(diào)用另一個地址空間(通常是遠程機器上的)的過程或函數(shù), 就像本地調(diào)用一樣, 而不需要顯示地處理網(wǎng)絡(luò)通信的細節(jié)。RPC使得分布式系統(tǒng)中的不同模塊能夠相互通信, 而對開發(fā)者而言, 這種通信就像是本地調(diào)用一樣簡單。其調(diào)用原理圖如下:Eeb28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Eeb28資訊網(wǎng)——每日最新資訊28at.com

上面的步驟看起來很復(fù)雜, 實際上, 在當(dāng)前的主流RPC框架, 例如:grpc、thrift, 只需要關(guān)心第1步和最后1步即可, 中間過程已經(jīng)由框架進行了封裝。在這篇文章中, 將從學(xué)習(xí)的角度自己來實現(xiàn)一個RPC的服務(wù)端全流程。Eeb28資訊網(wǎng)——每日最新資訊28at.com

Eeb28資訊網(wǎng)——每日最新資訊28at.com

Eeb28資訊網(wǎng)——每日最新資訊28at.com

2.實現(xiàn)RPC服務(wù)端

Eeb28資訊網(wǎng)——每日最新資訊28at.com

這里模擬了用戶信息的注冊管理流程, 在服務(wù)端, 保存有多個用戶信息, 并提供兩個遠程調(diào)用接口, 一個是通過ID獲取對應(yīng)的用戶信息接口, 另一個是添加新的用戶。參考代碼如下:Eeb28資訊網(wǎng)——每日最新資訊28at.com

// 1. 定義要遠程調(diào)用的方法type MathService struct {}func (m *MathService) Multiply(args *Args, reply *int) error {    *reply = args.A * args.B    return nil}// 2. 定義請求和響應(yīng)的數(shù)據(jù)結(jié)構(gòu)type Args struct {    A, B int}

在上面的代碼中, 我們定義了一個MathService結(jié)構(gòu)體,其中包含了一個Multiply方法,該方法用于實現(xiàn)兩個整數(shù)相乘的遠程調(diào)用。接下來我們需要完成服務(wù)端的服務(wù)端口監(jiān)聽和連接建立, 參考代碼如下:Eeb28資訊網(wǎng)——每日最新資訊28at.com

func main() {    mathService := new(MathService)    rpc.Register(mathService)    listener, err := net.Listen("tcp", ":1234")    if err != nil {        log.Fatal("Listen error:", err)    }    for {        conn, err := listener.Accept()        if err != nil {            log.Fatal("Accept error:", err)        }        go rpc.ServeConn(conn)    }}

在上面的main函數(shù)中, 我們注冊了一個MathService服務(wù),并在本地監(jiān)聽1234端口,當(dāng)接收到客戶端連接后, 使用rpc.ServeConn來處理RPC請求。Eeb28資訊網(wǎng)——每日最新資訊28at.com

Eeb28資訊網(wǎng)——每日最新資訊28at.com

Eeb28資訊網(wǎng)——每日最新資訊28at.com

3.實現(xiàn)客戶端連接

Eeb28資訊網(wǎng)——每日最新資訊28at.com

客戶端連接服務(wù)端的參考代碼如下:Eeb28資訊網(wǎng)——每日最新資訊28at.com

type Args struct {  A, B int}func main() {    client, err := rpc.Dial("tcp", "localhost:1234")    if err != nil {        log.Fatal("Dial error:", err)    }    args := &Args{7, 8}    var reply int    err = client.Call("MathService.Multiply", args, &reply)    if err != nil {        log.Fatal("MathService.Multiply error:", err)    }    fmt.Printf("MathService.Multiply: %d * %d = %d/n", args.A, args.B, reply)}

先編譯服務(wù)端代碼并啟動, 然后執(zhí)行客戶端程序,結(jié)果如下:Eeb28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Eeb28資訊網(wǎng)——每日最新資訊28at.com

客戶端成功調(diào)用了服務(wù)端的遠程函數(shù)并收到結(jié)果。Eeb28資訊網(wǎng)——每日最新資訊28at.com

Eeb28資訊網(wǎng)——每日最新資訊28at.com

Eeb28資訊網(wǎng)——每日最新資訊28at.com

4.利用gRPC框架實現(xiàn)服務(wù)端

Eeb28資訊網(wǎng)——每日最新資訊28at.com

gRPC(gRPC Remote Procedure Calls)是由Google開發(fā)的開源RPC(Remote Procedure Call,遠程過程調(diào)用)框架,其目標(biāo)是在跨網(wǎng)絡(luò)的服務(wù)之間實現(xiàn)高效的通信。gRPC使用Protocol Buffers(protobuf)作為其接口描述語言,并支持多種編程語言,包括C++, Java, Python, Go, Node.js等。Eeb28資訊網(wǎng)——每日最新資訊28at.com

首先需要安裝gRPC相關(guān)的包,通過以下命令安裝:Eeb28資訊網(wǎng)——每日最新資訊28at.com

go get -u google.golang.org/grpc

接著需要安裝Protocol Buffers工具, 可以從這里直接下載最新版, 根據(jù)自己的操作系統(tǒng)類型選擇:Eeb28資訊網(wǎng)——每日最新資訊28at.com

https://github.com/protocolbuffers/protobuf/releasesEeb28資訊網(wǎng)——每日最新資訊28at.com

接下來需要安裝兩個包:Eeb28資訊網(wǎng)——每日最新資訊28at.com

go install google.golang.org/protobuf/cmd/protoc-gen-go@latestgo install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest

緊接著創(chuàng)建proto文件, 內(nèi)容如下:Eeb28資訊網(wǎng)——每日最新資訊28at.com

syntax = "proto3";package grpcsample;option go_package = ".";message User {  string id = 1;  string name = 2;  int32 age = 3;}service UserService {  rpc GetUserById (UserRequest) returns (User);  rpc AddUser (User) returns (User);}message UserRequest {  string id = 1;}

將上面的代碼生成文件, 文件名為: user.proto。Eeb28資訊網(wǎng)——每日最新資訊28at.com

我這里將protoc二進制程序放到工程根目錄gosample下, 接著在命令行下輸入以下命令:Eeb28資訊網(wǎng)——每日最新資訊28at.com

./protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relative ./grpcsample/user.proto

該命令將把.proto文件內(nèi)容生成對應(yīng)的grpc Go代碼, 生成后將在grpcsample目錄下生成user.pb.go和user_grpc.pb.go文件,如圖:Eeb28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Eeb28資訊網(wǎng)——每日最新資訊28at.com

在grpcsample目錄下新建工程文件userservice.go, 加入以下代碼:Eeb28資訊網(wǎng)——每日最新資訊28at.com

import (  "context"  "fmt")var users = map[string]User{  "1": {Id: "1", Name: "John Doe", Age: 30},  "2": {Id: "2", Name: "Jane Doe", Age: 25},}type UserServer struct {  UnimplementedUserServiceServer}func (s *UserServer) GetUserById(ctx context.Context, req *UserRequest) (*User, error) {  user, exists := users[req.Id]  if exists {    return &user, nil  }  return nil, fmt.Errorf("User with ID %s not found", req.Id)}func (s *UserServer) AddUser(ctx context.Context, user *User) (*User, error) {  users[user.Id] = *user  return user, nil}

上面的代碼提供了兩個RPC方法, GetUserById支持通過ID查詢對應(yīng)的用戶信息, AddUser支持添加一個新的用戶。Eeb28資訊網(wǎng)——每日最新資訊28at.com

接著添加服務(wù)端的主程序代碼:Eeb28資訊網(wǎng)——每日最新資訊28at.com

import (  "google.golang.org/grpc"  pb "gosample/grpcsample")func main() {    listener, err := net.Listen("tcp", ":50051")  if err != nil {    log.Fatalf("Failed to listen: %v", err)  }  server := grpc.NewServer()  pb.RegisterUserServiceServer(server, &pb.UserServer{})  log.Println("gRPC server is running on port 50051")  if err := server.Serve(listener); err != nil {    log.Fatalf("Failed to serve: %v", err)  }}

在服務(wù)端主程序代碼中, 我們調(diào)用了grpcsample中的RegisterUserServiceServer方法注冊了一個服務(wù),并在本地的50051端口監(jiān)聽客戶端連接。Eeb28資訊網(wǎng)——每日最新資訊28at.com

Eeb28資訊網(wǎng)——每日最新資訊28at.com

Eeb28資訊網(wǎng)——每日最新資訊28at.com

5.生成gRPC客戶端

Eeb28資訊網(wǎng)——每日最新資訊28at.com

同樣的方式, 新打開一個工程, 按照服務(wù)端生成gRPC的方式生成客戶端的代碼, 如圖:Eeb28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Eeb28資訊網(wǎng)——每日最新資訊28at.com

在客戶端的主程序中利用如下代碼進行服務(wù)端方法調(diào)用:Eeb28資訊網(wǎng)——每日最新資訊28at.com

package mainimport (  "context"  "fmt"  "log"  "google.golang.org/grpc"  "google.golang.org/grpc/credentials/insecure"  pb "sampleclient/grpcsample")func main() {   conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials()))  if err != nil {    log.Fatalf("Failed to connect: %v", err)  }  defer conn.Close()  client := pb.NewUserServiceClient(conn)  // 通過ID查詢用戶  user, err := client.GetUserById(context.Background(), &pb.UserRequest{Id: "1"})  if err != nil {    log.Fatalf("Error getting user: %v", err)  }  fmt.Printf("User: %+v/n", user)  // 添加一個新用戶  newUser := &pb.User{Id: "3", Name: "Alice", Age: 28}  addedUser, err := client.AddUser(context.Background(), newUser)  if err != nil {    log.Fatalf("Error adding user: %v", err)  }  fmt.Printf("Added User: %+v/n", addedUser)}

在上面的代碼中, 首先通過grpc包中的Dial函數(shù)連接到本地50051端口, 并調(diào)用gRPC的方法NewUserServiceClient新建一個客戶端連接, 接著遠程調(diào)用了服務(wù)端的兩個方法。首先開啟服務(wù)端, 查看客戶端調(diào)用方法后的返回,如圖:Eeb28資訊網(wǎng)——每日最新資訊28at.com

圖片圖片Eeb28資訊網(wǎng)——每日最新資訊28at.com

可以看到,成功獲取到遠程的兩個方法返回的結(jié)果。Eeb28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-56409-0.html利用Go傳統(tǒng)RPC和gRPC框架分別實現(xiàn)一個RPC服務(wù)端

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 聊一聊 C# 的線程本地存儲TLS到底是什么

下一篇: ExecutorCompletionService詳解,你學(xué)會了嗎?

標(biāo)簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 肥西县| 津市市| 宁津县| 铜山县| 上栗县| 中阳县| 兴化市| 金阳县| 滦南县| 大安市| 石景山区| 治多县| 亳州市| 沂南县| 瓦房店市| 韶关市| 思茅市| 新民市| 营口市| 兴业县| 车致| 济源市| 无棣县| 库尔勒市| 永胜县| 多伦县| 礼泉县| 和政县| 新疆| 东至县| 高雄市| 大连市| 岳池县| 修文县| 红河县| 柯坪县| 纳雍县| 广州市| 吉安县| 葵青区| 兖州市|