当前位置:首页 > 科技  > 软件

利用Go传统RPC和gRPC框架分别实现一个RPC服务端

来源: 责编: 时间:2024-01-02 17:28:11 141观看
导读1.RPC原理介绍RPC(Remote Procedure Call, 远程过程调用) 是一种计算机通信协议, 它允许程序调用另一个地址空间(通常是远程机器上的)的过程或函数, 就像本地调用一样, 而不需要显示地处理网络通信的细节。RPC使得分

1.RPC原理介绍

XPT28资讯网——每日最新资讯28at.com

RPC(Remote Procedure Call, 远程过程调用) 是一种计算机通信协议, 它允许程序调用另一个地址空间(通常是远程机器上的)的过程或函数, 就像本地调用一样, 而不需要显示地处理网络通信的细节。RPC使得分布式系统中的不同模块能够相互通信, 而对开发者而言, 这种通信就像是本地调用一样简单。其调用原理图如下:XPT28资讯网——每日最新资讯28at.com

图片图片XPT28资讯网——每日最新资讯28at.com

上面的步骤看起来很复杂, 实际上, 在当前的主流RPC框架, 例如:grpc、thrift, 只需要关心第1步和最后1步即可, 中间过程已经由框架进行了封装。在这篇文章中, 将从学习的角度自己来实现一个RPC的服务端全流程。XPT28资讯网——每日最新资讯28at.com

XPT28资讯网——每日最新资讯28at.com

XPT28资讯网——每日最新资讯28at.com

2.实现RPC服务端

XPT28资讯网——每日最新资讯28at.com

这里模拟了用户信息的注册管理流程, 在服务端, 保存有多个用户信息, 并提供两个远程调用接口, 一个是通过ID获取对应的用户信息接口, 另一个是添加新的用户。参考代码如下:XPT28资讯网——每日最新资讯28at.com

// 1. 定义要远程调用的方法type MathService struct {}func (m *MathService) Multiply(args *Args, reply *int) error {    *reply = args.A * args.B    return nil}// 2. 定义请求和响应的数据结构type Args struct {    A, B int}

在上面的代码中, 我们定义了一个MathService结构体,其中包含了一个Multiply方法,该方法用于实现两个整数相乘的远程调用。接下来我们需要完成服务端的服务端口监听和连接建立, 参考代码如下:XPT28资讯网——每日最新资讯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函数中, 我们注册了一个MathService服务,并在本地监听1234端口,当接收到客户端连接后, 使用rpc.ServeConn来处理RPC请求。XPT28资讯网——每日最新资讯28at.com

XPT28资讯网——每日最新资讯28at.com

XPT28资讯网——每日最新资讯28at.com

3.实现客户端连接

XPT28资讯网——每日最新资讯28at.com

客户端连接服务端的参考代码如下:XPT28资讯网——每日最新资讯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)}

先编译服务端代码并启动, 然后执行客户端程序,结果如下:XPT28资讯网——每日最新资讯28at.com

图片图片XPT28资讯网——每日最新资讯28at.com

客户端成功调用了服务端的远程函数并收到结果。XPT28资讯网——每日最新资讯28at.com

XPT28资讯网——每日最新资讯28at.com

XPT28资讯网——每日最新资讯28at.com

4.利用gRPC框架实现服务端

XPT28资讯网——每日最新资讯28at.com

gRPC(gRPC Remote Procedure Calls)是由Google开发的开源RPC(Remote Procedure Call,远程过程调用)框架,其目标是在跨网络的服务之间实现高效的通信。gRPC使用Protocol Buffers(protobuf)作为其接口描述语言,并支持多种编程语言,包括C++, Java, Python, Go, Node.js等。XPT28资讯网——每日最新资讯28at.com

首先需要安装gRPC相关的包,通过以下命令安装:XPT28资讯网——每日最新资讯28at.com

go get -u google.golang.org/grpc

接着需要安装Protocol Buffers工具, 可以从这里直接下载最新版, 根据自己的操作系统类型选择:XPT28资讯网——每日最新资讯28at.com

https://github.com/protocolbuffers/protobuf/releasesXPT28资讯网——每日最新资讯28at.com

接下来需要安装两个包:XPT28资讯网——每日最新资讯28at.com

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

紧接着创建proto文件, 内容如下:XPT28资讯网——每日最新资讯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。XPT28资讯网——每日最新资讯28at.com

我这里将protoc二进制程序放到工程根目录gosample下, 接着在命令行下输入以下命令:XPT28资讯网——每日最新资讯28at.com

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

该命令将把.proto文件内容生成对应的grpc Go代码, 生成后将在grpcsample目录下生成user.pb.go和user_grpc.pb.go文件,如图:XPT28资讯网——每日最新资讯28at.com

图片图片XPT28资讯网——每日最新资讯28at.com

在grpcsample目录下新建工程文件userservice.go, 加入以下代码:XPT28资讯网——每日最新资讯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查询对应的用户信息, AddUser支持添加一个新的用户。XPT28资讯网——每日最新资讯28at.com

接着添加服务端的主程序代码:XPT28资讯网——每日最新资讯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)  }}

在服务端主程序代码中, 我们调用了grpcsample中的RegisterUserServiceServer方法注册了一个服务,并在本地的50051端口监听客户端连接。XPT28资讯网——每日最新资讯28at.com

XPT28资讯网——每日最新资讯28at.com

XPT28资讯网——每日最新资讯28at.com

5.生成gRPC客户端

XPT28资讯网——每日最新资讯28at.com

同样的方式, 新打开一个工程, 按照服务端生成gRPC的方式生成客户端的代码, 如图:XPT28资讯网——每日最新资讯28at.com

图片图片XPT28资讯网——每日最新资讯28at.com

在客户端的主程序中利用如下代码进行服务端方法调用:XPT28资讯网——每日最新资讯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函数连接到本地50051端口, 并调用gRPC的方法NewUserServiceClient新建一个客户端连接, 接着远程调用了服务端的两个方法。首先开启服务端, 查看客户端调用方法后的返回,如图:XPT28资讯网——每日最新资讯28at.com

图片图片XPT28资讯网——每日最新资讯28at.com

可以看到,成功获取到远程的两个方法返回的结果。XPT28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-56409-0.html利用Go传统RPC和gRPC框架分别实现一个RPC服务端

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

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

下一篇: ExecutorCompletionService详解,你学会了吗?

标签:
  • 热门焦点
  • vivo TWS Air开箱体验:真轻 臻好听

    vivo TWS Air开箱体验:真轻 臻好听

    在vivo S15系列新机的发布会上,vivo的最新款真无线蓝牙耳机vivo TWS Air也一同发布,本次就这款耳机新品给大家带来一个简单的分享。外包装盒上,vivo TWS Air保持了vivo自家产
  • 6月安卓手机好评榜:魅族20 Pro蝉联冠军

    6月安卓手机好评榜:魅族20 Pro蝉联冠军

    性能榜和性价比榜之后,我们来看最后的安卓手机好评榜,数据来源安兔兔评测,收集时间2023年6月1日至6月30日,仅限国内市场。第一名:魅族20 Pro好评率:95%5月份的时候魅族20 Pro就是
  • 三言两语说透设计模式的艺术-简单工厂模式

    三言两语说透设计模式的艺术-简单工厂模式

    一、写在前面工厂模式是最常见的一种创建型设计模式,通常说的工厂模式指的是工厂方法模式,是使用频率最高的工厂模式。简单工厂模式又称为静态工厂方法模式,不属于GoF 23种设计
  • 服务存储设计模式:Cache-Aside模式

    服务存储设计模式:Cache-Aside模式

    Cache-Aside模式一种常用的缓存方式,通常是把数据从主存储加载到KV缓存中,加速后续的访问。在存在重复度的场景,Cache-Aside可以提升服务性能,降低底层存储的压力,缺点是缓存和底
  • 量化指标是与非:挽救被量化指标扼杀的技术团队

    量化指标是与非:挽救被量化指标扼杀的技术团队

    作者 | 刘新翠整理 | 徐杰承本文整理自快狗打车技术总监刘新翠在WOT2023大会上的主题分享,更多精彩内容及现场PPT,请关注51CTO技术栈公众号,发消息【WOT2023PPT】即可直接领取
  • 拼多多APP上线本地生活入口,群雄逐鹿万亿市场

    拼多多APP上线本地生活入口,群雄逐鹿万亿市场

    Tech星球(微信ID:tech618)文 | 陈桥辉 Tech星球独家获悉,拼多多在其APP内上线了“本地生活”入口,位置较深,位于首页的“充值中心”内,目前主要售卖美食相关的
  • 本地生活这块肥肉,拼多多也想吃一口

    本地生活这块肥肉,拼多多也想吃一口

    出品/壹览商业 作者/李彦编辑/木鱼拼多多也看上本地生活这块蛋糕了。近期,拼多多在App首页“充值中心”入口上线了本机生活界面。壹览商业发现,该界面目前主要
  • iQOO 11S评测:行业唯一的200W标准版旗舰

    iQOO 11S评测:行业唯一的200W标准版旗舰

    【Techweb评测】去年底,iQOO推出了“电竞旗舰”iQOO 11系列,作为一款性能强机,该机不仅全球首发2K 144Hz E6全感屏,搭载了第二代骁龙8平台及144Hz电竞
  • iQOO Neo8系列新品发布会

    iQOO Neo8系列新品发布会

    旗舰双芯 更强更Pro
Top