RPC框架 | 青训营笔记

86 阅读4分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 13 天

课程内容与选题缘由

之前的课程中介绍了一下RPC框架的内容,本篇笔记就RPC框架的课程笔记与个人思考作一个总结。

RPC框架是什么

RPC (Remote Procedure Call) 是一种计算机网络协议,允许一个程序(客户端)在运行另一个程序(服务器)上执行一个函数——使得远程函数调用,就像调用本地函数一样。

RPC 框架则是一种封装了RPC通信机制的软件架构,用于快速构建分布式系统中的远程过程调用应用。开发人员就可以在不同的程序之间编写和组织代码,而无需考虑网络通信的细节。

1

RPC框架的调用过程

2

基于RPC框架的项目中,客户端向服务端进行RPC调用需要经过的流程如下:

  1. 客户端(Caller machine)通过调用程序和用户存根(User-stub)组件,将远程调用请求封装成一个调用数据包(Call packet)。
  2. 调用数据包通过RPC运行时组件(RPCRuntime)进行网络传输,发送到服务端(Callee machine)。
  3. 服务端接收到调用数据包后,通过服务端存根(Server-stub)组件进行解码,提取出调用请求。
  4. 服务端通过执行实际业务逻辑处理程序(Server),对调用请求进行处理。
  5. 处理完成后,服务端通过Server-stub将结果封装成一个结果数据包(Result Packet),通过RPC运行时组件进行网络传输,发送回客户端
  6. 客户端接收到结果数据包后,通过User-stub解码得到最终结果。

客户端和服务端通过RPC框架进行通信时,两者只需要关注各自的请求数据(request data)和响应数据(response data),而不需要关注对方的代码类型。RPC框架隐藏了跨语言和跨平台的差异,让客户端和服务端能够通过统一的接口进行通信。

换句话说,RPC框架实现了客户端和服务端的抽象,使得客户端和服务端可以忽略实现细节,只关注请求和响应数据的格式。

RPC框架的优点

3

RPC框架的优点:

  1. 让远程调用像本地调用一样简单,缩短开发时间,降低维护成本。
  2. 不同功能模块之间是独立的,有利于分工协作和运维开发。
  3. 支持高可扩展性,资源的调度分配可以进行优化。
  4. 支持多种语言开发,可以跨语言调用。
  5. 支持高并发,高可用的远程调用。
  6. 支持负载均衡,增强系统的稳定性和可靠性

如何使用RPC框架

把大象放进冰箱分几步?

  1. 把冰箱门打开。
  2. 把大象放进去。
  3. 把冰箱门带上。

RPC开发同样分三步:

  • 编写.proto文件定义服务
  • 生成指定语言的代码
  • 编写业务逻辑代码

以下是一段在Gin框架下使用Kitex进行RPC通信的代码:

package main

import (
	"github.com/gin-gonic/gin"
	"github.com/kitextech/kitex-go/v2"
	"github.com/kitextech/kitex-go/v2/services"
	"golang.org/x/net/context"
	"douyin.core/core"
	"strconv"
)

type UserLoginHandler struct {}

func (h *UserLoginHandler) UserLogin(ctx context.Context, req *douyin.core.douyin_user_register_request) (*douyin.core.douyin_user_register_response, error) {
	// 根据需求实现登录逻辑
	// ...

	// 返回响应
	return &douyin.core.douyin_user_register_response{
		StatusCode: 0,
		StatusMsg: "登录成功",
		UserId: 123456,
		Token: "token",
	}, nil
}

func main() {
	router := gin.Default()

	// 实例化kitex服务
	kitexService := kitex.NewService("127.0.0.1:8080")
	err := kitexService.RegisterHandler(context.Background(), &UserLoginHandler{})
	if err != nil {
		panic(err)
	}
	
	// 将Kitex与Gin框架结合
	kitexService.Start()
	defer kitexService.Stop()

	// 配置Gin路由
	router.POST("/user_login", func(c *gin.Context) {
		// 获取请求数据
		username := c.PostForm("username")
		password := c.PostForm("password")

		// 发送RPC请求
		client := kitex.NewClient("127.0.0.1:8080")
		req := &douyin.core.douyin_user_register_request{
			Username: username,
			Password: password,
		}
		res, err := client.UserLogin(context.Background(), req)
		if err != nil {
			c.JSON(500, gin.H{
				"error": err.Error(),
			})
			return
		}

		// 返回响应
		c.JSON(200, gin.H{
			"status_code": res.StatusCode,
		})
}

总的来说,就是在使用Kitex框架的同时,将原有的功能代码封装成一个RPC服务,然后在Gin框架的应用程序中调用这个RPC服务。

您需要做的是:

  1. 创建RPC服务:将原来的功能代码放入RPC服务的处理方法中。
  2. 发布RPC服务:在Kitex框架中发布这个RPC服务,并设置相关的RPC服务地址、端口等信息。
  3. 在Gin框架中调用RPC服务:通过Kitex框架的客户端调用发布的RPC服务,并将结果返回给Gin框架。