golang学习笔记:了解RPC框架 | 青训营

139 阅读3分钟

当涉及分布式系统或网络应用程序时,远程过程调用(RPC)框架是一种用于实现不同计算机上程序之间通信的技术。它允许开发人员像调用本地函数一样调用远程服务器上的函数,无需手动处理底层通信细节。以下是RPC框架的一些关键概念和优势:

目录

1、概念学习

2、golang中gRPC框架学习

 

  —————————————————————

概念学习

1. 概念:

  • Stub(存根): 客户端使用存根来调用远程服务器上的函数,这些存根实际上是客户端代码中的代理函数。
  • Serialization(序列化): 数据在客户端和服务器之间传递时,需要进行序列化(将数据转换为字节流)和反序列化(将字节流转换回数据)。
  • Transport(传输): 传输层负责将序列化的数据在网络上传递。
  • Server(服务器): 服务器端注册并提供实际的函数实现,以供远程调用。
  • Client(客户端): 客户端通过存根调用远程函数,而不必了解底层通信细节。

2. 工作原理:

  • 客户端调用存根的方法,就好像调用本地函数一样。
  • 存根将调用信息打包成请求,通过网络发送到远程服务器。
  • 服务器接收请求,解包调用信息,调用实际的函数,然后将结果打包成响应返回给客户端。
  • 客户端接收响应,解包结果,继续执行代码。

3. 优势:

  • 封装性: 开发人员无需关心底层通信细节,只需关注函数调用和参数传递。
  • 可移植性: 跨不同编程语言和操作系统的应用程序可以进行通信。
  • 重用性: 可以在多个项目中重复使用远程函数,提高了代码的可维护性。
  • 性能优化: 一些RPC框架提供了性能优化选项,例如连接池和异步调用。
  • 分布式编程: RPC在分布式系统中扮演重要角色,使得分布式应用程序的构建更加方便。

4. 示例RPC框架:

  • gRPC: 由Google开发,基于HTTP/2和Protocol Buffers(一种高效的序列化格式)构建,支持多种编程语言。
  • Apache Thrift: 开源框架,支持多种传输协议和序列化格式,用于构建跨语言的服务。
  • JSON-RPC: 使用JSON作为数据格式的轻量级RPC协议,易于使用。

—————————————————————

2 golang中gRPC框架学习

试试学习一个简单的 gRPC 入门示例:

步骤1:安装 gRPC

首先,我们需要安装 gRPC 相关的库。在终端中执行以下命令:

go get -u google.golang.org/grpc

步骤2:定义服务和消息

创建一个 calculator.proto 文件,定义一个简单的计算器服务:

syntax = "proto3";

package calculator;

service Calculator {
  rpc Add (AddRequest) returns (AddResponse);
}

message AddRequest {
  int32 a = 1;
  int32 b = 2;
}

message AddResponse {
  int32 result = 1;
}

步骤3:生成代码

在终端中使用 protoc 工具将 .proto 文件编译成 Go 代码:

protoc --go_out=. calculator.proto

这将生成 calculator.pb.go 文件。

步骤4:实现服务器

创建一个服务器端的 Go 文件,实现 gRPC 服务:

package main

import (
	"context"
	"fmt"
	"net"

	"google.golang.org/grpc"
	"calculator"
)

type server struct{}

func (s *server) Add(ctx context.Context, req *calculator.AddRequest) (*calculator.AddResponse, error) {
	result := req.A + req.B
	return &calculator.AddResponse{Result: result}, nil
}

func main() {
	lis, err := net.Listen("tcp", ":8080")
	if err != nil {
		fmt.Printf("failed to listen: %v\n", err)
		return
	}

	s := grpc.NewServer()
	calculator.RegisterCalculatorServer(s, &server{})
	
	fmt.Println("Server listening on :8080")
	if err := s.Serve(lis); err != nil {
		fmt.Printf("failed to serve: %v\n", err)
	}
}

步骤5:实现客户端

创建一个客户端的 Go 文件,调用服务器上的 gRPC 服务:

package main

import (
	"context"
	"fmt"
	"log"

	"google.golang.org/grpc"
	"calculator"
)

func main() {
	conn, err := grpc.Dial("localhost:8080", grpc.WithInsecure())
	if err != nil {
		log.Fatalf("did not connect: %v", err)
	}
	defer conn.Close()

	c := calculator.NewCalculatorClient(conn)
	
	req := &calculator.AddRequest{A: 10, B: 5}
	res, err := c.Add(context.Background(), req)
	if err != nil {
		log.Fatalf("could not add: %v", err)
	}
	
	fmt.Printf("Result: %d\n", res.Result)
}

步骤6:运行程序

分别运行服务器和客户端程序,我们会看到客户端调用服务器上的 Add 函数并打印结果。