项目地址:https://github.com/yakaa/grpcx
grpc client常规使用方法
func main() {
conn, err := grpc.Dial("127.0.0.1:9000", grpc.WithInsecure())
if err != nil {
log.Fatalf(" grpc.Dial %v", err)
}
defer conn.Close()
//UserService
userClient := protoFiles_hello.NewUserServiceClient(conn)
userRes, err := userClient.UserList(context.Background(), &protoFiles_hello.UserRequest{
Name: "小明",
Mobile: "18811118888",
})
if nil != err {
log.Fatal(err)
}
//fmt.Printf("%T, %v\n",userRes,userRes)
for key, user := range userRes.User {
fmt.Println(key, user)
}
}
grpcx客户端启动代码
- 配置clientConf配置文件
- grpxc.MustNewGrpcxCLient函数看下面分析
- r.GetConnection看下面分析,
- 获取到conn后生成一个新的RegionHandlerClient,然后调用rpc的接口即可
- 内部的负载均衡,是有官方的grpc第三方库实现的(自己的理解)
func Client() {
conf := &config.ClientConf{
EtcdAuth: config.EtcdAuth{},
Target: "www.vector.com:///knowing",
Endpoints: []string{"127.0.0.1:2379"},
WithBlock: false,
}
r, err := grpcx.MustNewGrpcxClient(conf)
if err != nil {
panic(err)
}
conn, err := r.GetConnection()
if err != nil {
panic(err)
}
regionHandlerClient := proto.NewRegionHandlerClient(conn)
for {
res, err := regionHandlerClient.GetListenAudio(
context.Background(),
&proto.FindRequest{Tokens: []string{"a_"}},
)
if err != nil {
log.Fatal(err)
}
fmt.Println(res)
time.Sleep(1 * time.Second)
}
}
grpcx.MustNewGrpcxClient()函数
conf := &config.ClientConf{ EtcdAuth: config.EtcdAuth{}, Target: "www.vector.com:///knowing", Endpoints: []string{"127.0.0.1:2379"}, WithBlock: false, }
- NewResolver
Resolver模块是客户端操作etcd的主要模块
-
client3, err := clientv3.New( clientv3.Config{ Endpoints: conf.Endpoints, //[]string{"127.0.0.1:2379"}, Username: conf.UserName, Password: conf.PassWord, DialTimeout: config.GrpcxDialTimeout, //GrpcxDialTimeout = 3 * time.Second })
-
&Resolver{ client3: client3, //2获取的client3 withBlock: conf.WithBlock, //是否阻塞 target: conf.Target, //"www.vector.com:///knowing", //必须这样配置 }, nil
- resolver的其他接口(自己理解是用于grpc负载均衡调用的方法),客户端我们用不到
func MustNewGrpcxClient(conf *config.ClientConf) (*GrpcxClient, error) {
r, err := resolver.NewResolver(conf)
if err != nil {
return nil, err
}
rpcResolver.Register(r)
return &GrpcxClient{resolver: r, timeOut: config.GrpcxDialTimeout}, nil
}
// NewResolver initialize an etcd client
func NewResolver(conf *config.ClientConf) (*Resolver, error) {
client3, err := clientv3.New(
clientv3.Config{
Endpoints: conf.Endpoints,
Username: conf.UserName,
Password: conf.PassWord,
DialTimeout: config.GrpcxDialTimeout,
})
if nil != err {
return nil, err
}
return &Resolver{
client3: client3,
withBlock: conf.WithBlock,
target: conf.Target, //"www.vector.com:///knowing",
}, nil
}
GetConnection函数
主要作用是和常规使用差不多, 进行了部分参数配置,grpc.WithBalancerName(roundrobin.Name)使用轮训的负载均衡方法
context是使用有超时的上下文,timeout是在MustNewGrpcxClient函数的时候赋值的,然后带超时上下文和etcd节点的connection
func (c *GrpcxClient) GetConnection(options ...grpc.DialOption) (*grpc.ClientConn, error) {
opts := []grpc.DialOption{grpc.WithInsecure(), grpc.WithBalancerName(roundrobin.Name)}
if c.resolver.WithBlock() {
opts = append(opts, grpc.WithBlock())
}
opts = append(opts, options...)
ctx, _ := context.WithTimeout(context.Background(), c.timeOut)
return grpc.DialContext(ctx, c.resolver.Target(), opts...)
}