giftiaのblog

rpc & kitex

· giftia

什么是RPC

RPC(Remote Procedure Call Protocol)即远程过程调用协议。
通俗描述:客户端无需了解底层实现细节,即可像调用本地函数一样调用远程服务器上的服务。
正式定义:一种通过网络透明地请求远程服务的协议,屏蔽了网络通信的复杂性。

RPC的核心优势

  • 底层抽象:封装网络通信细节(如连接管理、数据传输),专注业务逻辑开发。
  • 跨语言兼容:支持多语言混合开发(如Go客户端调用Java服务端)。
  • 高性能通信:通过二进制协议(如Protobuf)和高效传输层(如HTTP/2),性能优于传统RESTful接口。

RPC 的实现方式对比

实现方式典型框架核心特点适用场景
基于 SocketThrift、Dubbo手动控制序列化与网络层,性能极高但开发复杂高性能场景(如金融、IM)
基于 HTTPgRPC、RESTful利用HTTP生态,gRPC基于HTTP/2+Protobuf实现高性能通用场景、跨语言交互
基于消息队列Apache Kafka、RabbitMQ异步解耦,通过消息传递实现非阻塞调用(严格意义属异步通信而非RPC)高并发、最终一致性场景

gRPC 简介

gRPC 是 Google 开源的高性能 RPC 框架,核心特性包括:

  • HTTP/2 底层:支持多路复用、流模式(单向/双向)。
  • Protobuf 序列化:数据压缩率高、反序列化速度快。
  • 多语言支持:原生支持Go、Java、Python等主流语言。

Kitex 是什么

Kitex 是字节跳动开源的 Go 微服务 RPC 框架,专为云原生场景设计:

  1. 高性能:基于自研Netpoll网络库,QPS可达百万级,延迟低于1ms。
  2. 全链路治理:内置服务发现(支持ETCD/Consul)、负载均衡、熔断限流。
  3. 灵活扩展:通过插件机制支持自定义协议、中间件(如链路追踪、监控)。
  4. 多协议兼容:原生支持Thrift/Protobuf,兼容gRPC协议。

Kitex 快速入门

1. 环境准备

# 安装 Kitex 命令行工具
go get -u github.com/cloudwego/kitex/cmd/kitex@latest

2. 定义服务接口(Protobuf示例)

// hello.proto
syntax = "proto3";
package hello;

service Hello {
  rpc SayHello(Request) returns (Response) {} // 定义远程方法
}

message Request {
  string name = 1; // 请求参数
}

message Response {
  string message = 1; // 响应结果
}

3. 生成代码

kitex -name hello -proto ./hello.proto -dst ./kitex_gen # 生成服务代码

4. 编写服务端

// server/main.go
package main

import (
	"context"
	"log"
	"net"

	"kitex_gen/hello"        // 自动生成的代码包
	"kitex_gen/hello/helloimpl" // 服务实现包
)

// 实现服务接口
type HelloServiceImpl struct{}
func (s *HelloServiceImpl) SayHello(ctx context.Context, req *hello.Request) (*hello.Response, error) {
	return &hello.Response{Message: "Hello " + req.Name}, nil
}

func main() {
	// 初始化服务端,指定地址和处理器
	svr := hello.NewHelloServer(
		&helloimpl.HelloServiceImpl{},
		hello.WithServiceAddr(net.JoinHostPort("127.0.0.1", "8888")), // 绑定地址
	)
	
	// 启动服务
	if err := svr.Run(); err != nil {
		log.Fatalf("Server exited with error: %v", err)
	}
}

5. 编写客户端

// client/main.go
package main

import (
	"context"
	"log"

	"kitex_gen/hello" // 自动生成的代码包
)

func main() {
	// 初始化客户端,指定服务名和地址
	cli, err := hello.NewHelloClient(
		"hello-service", // 服务名(需与服务端一致)
		hello.WithHostPorts("127.0.0.1:8888"), // 目标地址
	)
	if err != nil {
		log.Fatalf("Client initialization failed: %v", err)
	}

	// 调用远程方法
	resp, err := cli.SayHello(context.Background(), &hello.Request{Name: "Kitex"})
	if err != nil {
		log.Fatalf("RPC call failed: %v", err)
	}
	log.Println("Response:", resp.Message) // 输出:Response: Hello Kitex
}

进阶特性(生产环境建议)

1. 服务治理配置

// 启用 ETCD 注册中心
import (
	etcd "github.com/kitex-contrib/registry-etcd"
)

resolver, err := etcd.NewResolver([]string{"etcd-server:2379"})
svr := hello.NewHelloServer(
	&helloimpl.HelloServiceImpl{},
	hello.WithRegistry(resolver), // 注册服务到 ETCD
)

// 客户端负载均衡
cli, err := hello.NewHelloClient(
	"hello-service",
	hello.WithLoadBalancer(p2c.NewBalancer()), // 平滑加权负载均衡
)

2. 观测性支持

// 集成 OpenTelemetry 链路追踪
import (
	"go.opentelemetry.io/otel"
	kitexotel "github.com/kitex-contrib/otel"
)

// 服务端添加追踪中间件
svr := hello.NewHelloServer(
	&helloimpl.HelloServiceImpl{},
	hello.WithMiddleware(kitexotel.ServerMiddleware(otel.GetTracerProvider())),
)

// 客户端添加指标监控
cli, err := hello.NewHelloClient(
	"hello-service",
	hello.WithClientOption(kitexotel.ClientMiddleware(otel.GetTracerProvider())),
)

官方文档:https://www.cloudwego.io/zh/docs/kitex/