掌握了gRPC的基本原理后,我们可以借助它来实现日志的微服务功能。在构建高并发系统时,内部的服务组件通常使用gRPC来实现高效数据传输,因此我们把前面使用json完成的日志服务改成用gRPC来完成。
第一步还是要定义proto文件,修改proglog/api/v1下面的log.proto文件:
syntax = "proto3";
package log.v1;
option go_package = "api/log_v1";
service Log {
rpc Produce(ProduceRequest) returns (ProduceResponse) {}
rpc Consume(ConsumeRequest) returns (ConsumeResponse) {}
rpc ConsumeStream(ConsumeRequest) returns (stream ConsumeResponse){}
rpc ProduceStream(stream ProduceRequest) returns (stream ProduceResponse) {}
}
message Record {
bytes value = 1;
uint64 offset = 2;
}
message ProduceRequest {
Record record = 1;
}
message ProduceResponse {
uint64 offset = 1;
}
message ConsumeRequest {
uint64 offset = 1;
}
message ConsumeResponse {
Record record = 2;
}
代码的逻辑跟前面几节我们尝试使用gRPC时的proto文件定义逻辑没什么不同,Produce接口是客户端向服务端提交一条日志信息,Consume是客户端向服务端提交日志编号,然后服务端返回日志信息,ConsumeStream是客户端向服务端提交一连串的日志编号,然后服务端返回一连串的日志信息,ProduceStream是客户端向服务端提交一连串的日志信息,然后服务端返回日志添加后对应的编号。完成上面proto文件定义后,将它编译出对应的pb.go文件,这些文件会放置在api/v1/api_log_v1目录下,然后我们看看服务端的逻辑设计。
在internal/server下新建server.go文件,首先我们添加依赖模块,同时生成gRPC服务器对象,并注册我们要实现的接口:
package server
import (
"context"
api "api/v1/api/log_v1"
"google.golang.org/grpc"
)
type commitLog interface {
Append(*api.Record) (uint64, error)
Read(uint64) (*api.Record, error)
}
type Config struct { //实现依赖注入
CommitLog commitLog
}
var _ api.LogServer = (*grpcServer)(nil) //gRPC服务器对象
func NewGRPCServer(config *Confi