rpc & kitex
·
giftia
什么是RPC
RPC(Remote Procedure Call Protocol)即远程过程调用协议。
通俗描述:客户端无需了解底层实现细节,即可像调用本地函数一样调用远程服务器上的服务。
正式定义:一种通过网络透明地请求远程服务的协议,屏蔽了网络通信的复杂性。
RPC的核心优势
- 底层抽象:封装网络通信细节(如连接管理、数据传输),专注业务逻辑开发。
- 跨语言兼容:支持多语言混合开发(如Go客户端调用Java服务端)。
- 高性能通信:通过二进制协议(如Protobuf)和高效传输层(如HTTP/2),性能优于传统RESTful接口。
RPC 的实现方式对比
| 实现方式 | 典型框架 | 核心特点 | 适用场景 |
|---|---|---|---|
| 基于 Socket | Thrift、Dubbo | 手动控制序列化与网络层,性能极高但开发复杂 | 高性能场景(如金融、IM) |
| 基于 HTTP | gRPC、RESTful | 利用HTTP生态,gRPC基于HTTP/2+Protobuf实现高性能 | 通用场景、跨语言交互 |
| 基于消息队列 | Apache Kafka、RabbitMQ | 异步解耦,通过消息传递实现非阻塞调用(严格意义属异步通信而非RPC) | 高并发、最终一致性场景 |
gRPC 简介
gRPC 是 Google 开源的高性能 RPC 框架,核心特性包括:
- HTTP/2 底层:支持多路复用、流模式(单向/双向)。
- Protobuf 序列化:数据压缩率高、反序列化速度快。
- 多语言支持:原生支持Go、Java、Python等主流语言。
Kitex 是什么
Kitex 是字节跳动开源的 Go 微服务 RPC 框架,专为云原生场景设计:
- 高性能:基于自研Netpoll网络库,QPS可达百万级,延迟低于1ms。
- 全链路治理:内置服务发现(支持ETCD/Consul)、负载均衡、熔断限流。
- 灵活扩展:通过插件机制支持自定义协议、中间件(如链路追踪、监控)。
- 多协议兼容:原生支持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())),
)