packagemainimport("context""fmt""log""net""sync""google.golang.org/grpc"pb"github.com/lixd/grpc-go-example/features/proto/echo")var(addrs=[]string{":50051",":50052"})typeecServerstruct{pb.UnimplementedEchoServeraddrstring}func(s*ecServer)UnaryEcho(ctxcontext.Context,req*pb.EchoRequest)(*pb.EchoResponse,error){return&pb.EchoResponse{Message:fmt.Sprintf("%s (from %s)",req.Message,s.addr)},nil}funcstartServer(addrstring){lis,err:=net.Listen("tcp",addr)iferr!=nil{log.Fatalf("failed to listen: %v",err)}s:=grpc.NewServer()pb.RegisterEchoServer(s,&ecServer{addr:addr})log.Printf("serving on 0.0.0.0%s\n",addr)iferr:=s.Serve(lis);err!=nil{log.Fatalf("failed to serve: %v",err)}}funcmain(){varwgsync.WaitGroupfor_,addr:=rangeaddrs{wg.Add(1)gofunc(addrstring){deferwg.Done()startServer(addr)}(addr)}wg.Wait()}
packagemainimport("context""fmt""log""time"pb"github.com/lixd/grpc-go-example/features/proto/echo""google.golang.org/grpc""google.golang.org/grpc/resolver")const(exampleScheme="example"exampleServiceName="lb.example.grpc.lixueduan.com")varaddrs=[]string{"localhost:50051","localhost:50052"}funccallUnaryEcho(cpb.EchoClient,messagestring){ctx,cancel:=context.WithTimeout(context.Background(),time.Second)defercancel()r,err:=c.UnaryEcho(ctx,&pb.EchoRequest{Message:message})iferr!=nil{log.Fatalf("could not greet: %v",err)}fmt.Println(r.Message)}funcmakeRPCs(cc*grpc.ClientConn,nint){hwc:=pb.NewEchoClient(cc)fori:=0;i<n;i++{callUnaryEcho(hwc,"this is examples/load_balancing")}}funcmain(){// "pick_first" is the default, so there's no need to set the load balancer.pickfirstConn,err:=grpc.Dial(fmt.Sprintf("%s:///%s",exampleScheme,exampleServiceName),grpc.WithInsecure(),grpc.WithBlock(),)iferr!=nil{log.Fatalf("did not connect: %v",err)}deferpickfirstConn.Close()fmt.Println("--- calling helloworld.Greeter/SayHello with pick_first ---")makeRPCs(pickfirstConn,10)fmt.Println()// Make another ClientConn with round_robin policy.roundrobinConn,err:=grpc.Dial(fmt.Sprintf("%s:///%s",exampleScheme,exampleServiceName),grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy":"round_robin"}`),// This sets the initial balancing policy.grpc.WithInsecure(),grpc.WithBlock(),)iferr!=nil{log.Fatalf("did not connect: %v",err)}deferroundrobinConn.Close()fmt.Println("--- calling helloworld.Greeter/SayHello with round_robin ---")makeRPCs(roundrobinConn,10)}
// Following is an example name resolver implementation. Read the name// resolution example to learn more about it.typeexampleResolverBuilderstruct{}func(*exampleResolverBuilder)Build(targetresolver.Target,ccresolver.ClientConn,optsresolver.BuildOptions)(resolver.Resolver,error){r:=&exampleResolver{target:target,cc:cc,addrsStore:map[string][]string{exampleServiceName:addrs,},}r.start()returnr,nil}func(*exampleResolverBuilder)Scheme()string{returnexampleScheme}typeexampleResolverstruct{targetresolver.Targetccresolver.ClientConnaddrsStoremap[string][]string}func(r*exampleResolver)start(){addrStrs:=r.addrsStore[r.target.Endpoint]addrs:=make([]resolver.Address,len(addrStrs))fori,s:=rangeaddrStrs{addrs[i]=resolver.Address{Addr:s}}r.cc.UpdateState(resolver.State{Addresses:addrs})}func(*exampleResolver)ResolveNow(oresolver.ResolveNowOptions){}func(*exampleResolver)Close(){}
3. Test
分别运行服务端和客户端查看结果
1
2
3
lixd@17x:~/17x/projects/grpc-go-example/features/load_balancing/server$ go run main.go
2021/05/23 09:47:59 serving on 0.0.0.0:50052
2021/05/23 09:47:59 serving on 0.0.0.0:50051
lixd@17x:~/17x/projects/grpc-go-example/features/load_balancing/client$ go run main.go
--- calling helloworld.Greeter/SayHello with pick_first ---
this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50051)--- calling helloworld.Greeter/SayHello with round_robin ---
this is examples/load_balancing (from :50052)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50052)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50052)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50052)this is examples/load_balancing (from :50051)this is examples/load_balancing (from :50052)this is examples/load_balancing (from :50051)