goweb3系列解析6:gorpc 模块解析gorpc 是 goweb3 项目中基于 go-micro 框架构建的 gRPC 通信模块,提供服务端启动、客户端调用、服务注册与发现等微服务通信能力
·
gorpc 模块解析
gorpc 是 goweb3 项目中基于 go-micro 框架构建的 gRPC 通信模块,提供服务端启动、客户端调用、服务注册与发现等完整的微服务通信能力。
一、模块架构
plainText
gorpc/
├── server/ # 服务端
│ ├── main.go # 入口文件
│ ├── startgrpc/startgrpc.go # 启动封装
│ ├── register/grpc_register.go # 服务注册
│ └── handler/ # 业务处理器
├── client/ # 客户端
│ ├── hello/hello_cli.go # 示例客户端
│ └── dbgorpc/ # 数据库RPC客户端
└── goconfig/gogrpc/ # 配置层
├── gorpcserver/ # 服务端核心
├── gorpcclient/ # 客户端核心
├── gofacade/ # RPC门面
└── proto/ # Protobuf定义
二、核心组件详解
1. GogrpcServer - 服务端核心
go
type GogrpcServer struct {
basedto.BaseEntitySingle
registerGrpc IgogrpcRegister // 服务注册器
}
服务启动流程:
go
func Start(reg IgogrpcRegister, dto *baseconfig.RpcServerDto) {
// 1. 创建服务实例
gogrpcServer := NewGogrpcServer(reg)
// 2. 运行服务
gogrpcServer.RunServer(dto)
}
func (server *GogrpcServer) RunServer(serverDto *baseconfig.RpcServerDto) {
// 1. 初始化服务(注册到 etcd)
service := server.Init(serverDto)
// 2. 注册 Handler
server.registerGrpc.RegisterGrpc(service)
// 3. 启动服务
service.Run()
}
服务初始化:
go
func (server *GogrpcServer) Init(serverDto *baseconfig.RpcServerDto) micro.Service {
// 1. 创建 etcd 注册中心
register := etcd.NewRegistry(func(options *registry.Options) {
options.Addrs = strutil.Split(serverDto.EtcdHost, ",")
})
// 2. 配置服务选项
opts := []micro.Option{
micro.Name(serverDto.ServerName),
micro.Version(version),
micro.RegisterTTL(time.Second * 90), // 服务过期时间
micro.RegisterInterval(time.Second * 30), // 心跳间隔
micro.Registry(register),
micro.Address(":" + serverDto.ServerPort),
}
// 3. 创建服务
service := micro.NewService(opts...)
service.Init()
return service
}
2. GorpcCli - 泛型客户端
go
type GorpcCli[S any] struct {
rpcClient S // 泛型 RPC 客户端
RpcServiceName string // 服务名称
FuncNew func(name string, c client.Client) S // 客户端构造函数
}
客户端初始化:
go
func (g *GorpcCli[S]) init(funcNew func(name string, c client.Client) S) *GorpcCli[S] {
// 使用 go-micro 共享客户端
g.rpcClient = funcNew(g.RpcServiceName, *common.Client())
return g
}
客户端管理:
go
var RpcCliMap sync.Map // 线程安全的客户端缓存
func Register[S any](s string, rpcli *GorpcCli[S]) {
RpcCliMap.Store(s, rpcli)
}
func Find[S any](s string) *GorpcCli[S] {
ci, ok := RpcCliMap.Load(s)
if ok {
return ci.(*GorpcCli[S])
}
return nil
}
3. GrpcRegister - 服务注册器
go
type GrpcRegister struct {
basedto.BaseEntitySingle
}
func (grpcRegister *GrpcRegister) RegisterGrpc(service micro.Service) {
// 注册各个 Handler
helloProto.RegisterHelloYeahHandler(service.Server(), handler.NewHelloRpc())
godbProto.RegisterGeneralGodbHandler(service.Server(), handler.NewGeneralGodbRpc())
}
三、服务发现机制
plainText
┌─────────────────────────────────────────────────────────────┐
│ 服务发现流程 │
├─────────────────────────────────────────────────────────────┤
│ 服务端 │
│ ├── 启动时注册到 etcd │
│ ├── 定时发送心跳(30s) │
│ └── TTL 过期自动下线(90s) │
├─────────────────────────────────────────────────────────────┤
│ 客户端 │
│ ├── 从 etcd 查询服务地址 │
│ ├── 负载均衡选择实例 │
│ └── 建立连接调用 │
└─────────────────────────────────────────────────────────────┘
配置项:
| 配置项 | 说明 | 默认值 |
|---|---|---|
RegisterTTL | 服务存活时间 | 90秒 |
RegisterInterval | 心跳间隔 | 30秒 |
EtcdHost | etcd 地址 | localhost:2379 |
四、配置与依赖
RPC 配置(来自 IchubConfig)
yaml
rpc:
servername: rpcweb.website.com
version: v1.0
serverport: "8081"
clientname: rpcweb-client
etcd:
server:
hosturl: localhost:2379
核心依赖
| 依赖 | 版本 | 用途 |
|---|---|---|
github.com/micro/go-micro/v2 | v2 | 微服务框架 |
github.com/micro/go-micro/v2/registry/etcd | v2 | etcd 服务发现 |
google.golang.org/grpc | - | gRPC 核心 |
五、使用示例
1. 服务端启动
go
func main() {
// 读取 RPC 配置
rpc := ichubconfig.FindBeanIchubConfig().ReadVar2Rpc("rpc")
// 启动服务
startgrpc.Start(rpc)
}
2. 定义 Handler
go
type HelloRpc struct{}
func NewHelloRpc() *HelloRpc {
return &HelloRpc{}
}
func (h *HelloRpc) SayHello(ctx context.Context, req *proto.HelloRequest, rsp *proto.HelloResponse) error {
rsp.Message = "Hello " + req.Name
return nil
}
3. 客户端调用
go
// 创建门面
facade := gofacade.NewRpcFacade()
// 调用 RPC
req := &proto.HelloRequest{Name: "World"}
rsp, err := facade.HelloService.RpcClient().SayHello(context.Background(), req)
4. 注册服务
go
func (grpcRegister *GrpcRegister) RegisterGrpc(service micro.Service) {
proto.RegisterHelloYeahHandler(service.Server(), handler.NewHelloRpc())
}
六、设计亮点
| 特性 | 实现方式 | 优势 |
|---|---|---|
| 泛型客户端 | GorpcCli[S] 泛型结构体 | 类型安全,支持任意服务 |
| 服务发现 | go-micro + etcd | 自动服务注册、健康检查 |
| 心跳机制 | RegisterTTL + RegisterInterval | 自动剔除故障节点 |
| 客户端缓存 | sync.Map | 复用连接,减少开销 |
| 依赖注入 | basedi 容器 | 统一管理,易于测试 |
七、完整调用链路
plainText
客户端请求
↓
RpcFacade.HelloService.RpcClient()
↓
GorpcCli[S].rpcClient(从 etcd 获取服务地址)
↓
gRPC 网络调用
↓
服务端 Handler 处理
↓
返回响应
八、代码生成支持
项目提供了 RPC 代码生成能力,通过模板自动生成:
config/factroy/template/gorpc/Rpc.template- Handler 模板config/factroy/template/gorpc/Rpc.proto.template- Proto 模板
生成的代码结构:
plainText
domain/internal/db/gorpc/
├── service/xxx_gorpc.go # Handler 实现
└── proto/
├── xxx_proto.pb.go # Go 代码
├── xxx_proto.pb.micro.go # go-micro 封装
└── pb/xxx_proto.proto # Proto 定义
九、典型应用场景
- 微服务间通信:替代 HTTP,实现高效的跨服务调用
- 数据库代理:通过 RPC 封装数据库操作,实现读写分离
- 分布式计算:将计算任务分发到多个 RPC 服务节点
- API 网关:通过 RPC 聚合多个后端服务
- 消息处理:与 NATS 配合,实现异步消息的同步处理
更多推荐
所有评论(0)