客户端修改gRPC连接服务的部分代码即可:
func main() { r := etcdv3.NewServiceDiscovery(EtcdEndpoints) resolver.Register(r) // 连接服务器 conn, err := grpc.Dial(r.Scheme()+"://8.8.8.8/simple_grpc", grpc.WithBalancerName("round_robin"), grpc.WithInsecure()) if err != nil { log.Fatalf("net.Connect err: %v", err) } defer conn.Close() // 建立gRPC连接 grpcClient = pb.NewSimpleClient(conn)gRPC内置了简单的负载均衡策略round_robin,根据负载均衡地址,以轮询的方式进行调用服务。
服务端启动时,把服务地址注册到etcd中即可:
func main() { // 监听本地端口 listener, err := net.Listen(Network, Address) if err != nil { log.Fatalf("net.Listen err: %v", err) } log.Println(Address + " net.Listing...") // 新建gRPC服务器实例 grpcServer := grpc.NewServer() // 在gRPC服务器注册我们的服务 pb.RegisterSimpleServer(grpcServer, &SimpleService{}) //把服务注册到etcd ser, err := etcdv3.NewServiceRegister(EtcdEndpoints, SerName, Address, 5) if err != nil { log.Fatalf("register service err: %v", err) } defer ser.Close() //用服务器 Serve() 方法以及我们的端口信息区实现阻塞等待,直到进程被杀死或者 Stop() 被调用 err = grpcServer.Serve(listener) if err != nil { log.Fatalf("grpcServer.Serve err: %v", err) } } 运行效果我们先启动并注册三个服务
然后客户端进行调用
看服务端接收到的请求
关闭localhost:8000服务,剩余localhost:8001和localhost:8002服务接收请求
重新打开localhost:8000服务
可以看到,gRPC客户端负载均衡运行良好。
总结本文介绍了gRPC客户端负载均衡的实现,它简单实现了gRPC负载均衡的功能。但在对接其他语言时候比较麻烦,需要每种语言都实现一套服务发现和负载策略,且如果要较为复杂的负载策略,需要修改客户端代码才能完成。
下篇将介绍如何实现官方推荐的负载均衡策略(External Load Balancing Service)。
源码地址:https://github.com/Bingjian-Zhu/etcd-example
参考:
https://segmentfault.com/a/1190000008672912
https://github.com/wothing/wonaming