func TestDropRequestFailedNonFailFast(t *testing.T) { // Start a backend. beLis, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("Failed to listen %v", err) } beAddr := strings.Split(beLis.Addr().String(), ":") bePort, err := strconv.Atoi(beAddr[1]) backends := startBackends(t, besn, beLis) defer stopBackends(backends) // Start a load balancer. lbLis, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("Failed to create the listener for the load balancer %v", err) } lbCreds := &serverNameCheckCreds{ sn: lbsn, } lb := grpc.NewServer(grpc.Creds(lbCreds)) if err != nil { t.Fatalf("Failed to generate the port number %v", err) } be := &lbpb.Server{ IpAddress: []byte(beAddr[0]), Port: int32(bePort), LoadBalanceToken: lbToken, DropRequest: true, } var bes []*lbpb.Server bes = append(bes, be) sl := &lbpb.ServerList{ Servers: bes, } ls := newRemoteBalancer(sl) lbpb.RegisterLoadBalancerServer(lb, ls) go func() { lb.Serve(lbLis) }() defer func() { ls.stop() lb.Stop() }() creds := serverNameCheckCreds{ expected: besn, } ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) cc, err := grpc.DialContext(ctx, besn, grpc.WithBalancer(Balancer(&testNameResolver{ addr: lbLis.Addr().String(), })), grpc.WithBlock(), grpc.WithTransportCredentials(&creds)) if err != nil { t.Fatalf("Failed to dial to the backend %v", err) } helloC := hwpb.NewGreeterClient(cc) ctx, _ = context.WithTimeout(context.Background(), 10*time.Millisecond) if _, err := helloC.SayHello(ctx, &hwpb.HelloRequest{Name: "grpc"}, grpc.FailFast(false)); grpc.Code(err) != codes.DeadlineExceeded { t.Fatalf("%v.SayHello(_, _) = _, %v, want _, %s", helloC, err, codes.DeadlineExceeded) } cc.Close() }
func main() { // Set up a connection to the server. // 1. 创建一个Connection conn, err := grpc.Dial(address, grpc.WithInsecure()) if err != nil { log.Fatalf("did not connect: %v", err) } defer conn.Close() // 2. 创建一个Client c := pb.NewGreeterClient(conn) // Contact the server and print out its response. name := defaultName if len(os.Args) > 1 { name = os.Args[1] } // 输入: Name // 返回: Hello + Name r, err := c.SayHello(context.Background(), &pb.HelloRequest{Name: name}) if err != nil { log.Fatalf("could not greet: %v", err) } log.Printf("Greeting: %s", r.Message) }
func main() { flag.Parse() log.Infof("Simulating %v clients.", *count) for i := 0; i < *count; i++ { id := uuid.New() log.Infof("client %v with id %v", i, id) client, err := doorman.NewWithID(*addr, id, doorman.DialOpts(grpc.WithInsecure())) if err != nil { log.Exit(err) } defer client.Close() res, err := client.Resource(*resource, *initialCapacity) if err != nil { log.Exit(err) } go manipulateCapacity(res, *initialCapacity, id) conn, err := grpc.Dial(*target, grpc.WithInsecure()) if err != nil { log.Exitf("did not connect: %v", err) } defer conn.Close() c := pb.NewGreeterClient(conn) rl := ratelimiter.NewQPS(res) for i := 0; i < *workers; i++ { go func() { ctx := context.Background() for { if err := rl.Wait(ctx); err != nil { log.Exitf("rl.Wait: %v", err) } ctx, cancel := context.WithTimeout(ctx, 30*time.Second) if _, err := c.SayHello(ctx, &pb.HelloRequest{Name: *resource}); err != nil { log.Error(err) } cancel() } }() } } http.Handle("/metrics", prometheus.Handler()) http.ListenAndServe(fmt.Sprintf(":%v", *port), nil) }
func ConfigGRPChw(lib *glick.Library) error { return lib.AddConfigurator("gRPChw", func(l *glick.Library, line int, cfg *glick.Config) error { for _, action := range cfg.Actions { if err := l.RegPlugin(cfg.API, action, func(ctx context.Context, in interface{}) (out interface{}, err error) { ins, ok := in.(*pb.HelloRequest) if !ok { return nil, errors.New("not *pb.HelloRequest") } out = interface{}(&pb.HelloReply{}) outsp := out.(*pb.HelloReply) dialOpt := []grpc.DialOption{grpc.WithInsecure()} if deadline, ok := ctx.Deadline(); ok { dialOpt = append(dialOpt, grpc.WithTimeout(deadline.Sub(time.Now()))) } conn, err := grpc.Dial(address, dialOpt...) if err != nil { return nil, err } defer func() { if e := conn.Close(); e != nil { panic(e) } }() c := pb.NewGreeterClient(conn) r, err := c.SayHello(context.Background(), ins) if err != nil { return nil, err } *outsp = *r return out, nil }, cfg); err != nil { return fmt.Errorf("entry %d GRPChw register plugin error: %v", line, err) } } return nil }) }
func TestDropRequest(t *testing.T) { // Start 2 backends. beLis1, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("Failed to listen %v", err) } beAddr1 := strings.Split(beLis1.Addr().String(), ":") bePort1, err := strconv.Atoi(beAddr1[1]) beLis2, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("Failed to listen %v", err) } beAddr2 := strings.Split(beLis2.Addr().String(), ":") bePort2, err := strconv.Atoi(beAddr2[1]) backends := startBackends(t, besn, beLis1, beLis2) defer stopBackends(backends) // Start a load balancer. lbLis, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("Failed to create the listener for the load balancer %v", err) } lbCreds := &serverNameCheckCreds{ sn: lbsn, } lb := grpc.NewServer(grpc.Creds(lbCreds)) if err != nil { t.Fatalf("Failed to generate the port number %v", err) } var bes []*lbpb.Server be := &lbpb.Server{ IpAddress: []byte(beAddr1[0]), Port: int32(bePort1), LoadBalanceToken: lbToken, DropRequest: true, } bes = append(bes, be) be = &lbpb.Server{ IpAddress: []byte(beAddr2[0]), Port: int32(bePort2), LoadBalanceToken: lbToken, DropRequest: false, } bes = append(bes, be) sl := &lbpb.ServerList{ Servers: bes, } ls := newRemoteBalancer(sl) lbpb.RegisterLoadBalancerServer(lb, ls) go func() { lb.Serve(lbLis) }() defer func() { ls.stop() lb.Stop() }() creds := serverNameCheckCreds{ expected: besn, } ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) cc, err := grpc.DialContext(ctx, besn, grpc.WithBalancer(Balancer(&testNameResolver{ addr: lbLis.Addr().String(), })), grpc.WithBlock(), grpc.WithTransportCredentials(&creds)) if err != nil { t.Fatalf("Failed to dial to the backend %v", err) } // The 1st fail-fast RPC should fail because the 1st backend has DropRequest set to true. helloC := hwpb.NewGreeterClient(cc) if _, err := helloC.SayHello(context.Background(), &hwpb.HelloRequest{Name: "grpc"}); grpc.Code(err) != codes.Unavailable { t.Fatalf("%v.SayHello(_, _) = _, %v, want _, %s", helloC, err, codes.Unavailable) } // The 2nd fail-fast RPC should succeed since it chooses the non-drop-request backend according // to the round robin policy. if _, err := helloC.SayHello(context.Background(), &hwpb.HelloRequest{Name: "grpc"}); err != nil { t.Fatalf("%v.SayHello(_, _) = _, %v, want _, <nil>", helloC, err) } // The 3nd non-fail-fast RPC should succeed. if _, err := helloC.SayHello(context.Background(), &hwpb.HelloRequest{Name: "grpc"}, grpc.FailFast(false)); err != nil { t.Fatalf("%v.SayHello(_, _) = _, %v, want _, <nil>", helloC, err) } cc.Close() }
func main() { flag.Parse() ready := make(chan struct{}) go func() { <-ready var client helloworld.GreeterClient if *useGRPC { opts := []grpc.DialOption{ grpc.WithBlock(), grpc.WithTimeout(3 * time.Second), grpc.WithInsecure(), } conn, err := grpc.Dial(*addr, opts...) if err != nil { log.Fatalf("grpc.Dial: %v", err) } client = helloworld.NewGreeterClient(conn) } else { t := (http.DefaultTransport.(*http.Transport)) t.TLSClientConfig = &tls.Config{ InsecureSkipVerify: true, } if *useHTTP2 { if err := http2.ConfigureTransport(t); err != nil { log.Fatal(err) } } } ctx := context.Background() for i := 0; i < *numRuns; i++ { randomBytes := make([]byte, *msgSize) n, err := rand.Read(randomBytes) if err != nil { log.Fatal(err) } if n != *msgSize { log.Fatal("didn't read enough bytes") } msg := string(randomBytes) t1 := time.Now() var proto string if *useGRPC { _, err = client.SayHello(ctx, &helloworld.HelloRequest{Name: msg}) proto = "GRPC" } else { var resp *http.Response resp, err = http.Post("https://"+*addr, "text/plain", bytes.NewReader(randomBytes)) proto = "HTTP" if resp != nil { proto = resp.Proto resp.Body.Close() } } if *verbose { fmt.Println() } fmt.Printf("%v\t%v\t%v\n", time.Now().Sub(t1), *latency, proto) if err != nil { log.Fatal(err) } } os.Exit(0) }() var server *grpc.Server if *useGRPC { server = grpc.NewServer() helloworld.RegisterGreeterServer(server, greeter{}) } l, err := net.Listen("tcp", *addr) if err != nil { log.Fatal(err) } rate := Rate{Latency: *latency} l = &Listener{l, rate, rate} close(ready) if *useGRPC { log.Fatal(server.Serve(l)) } else { var config tls.Config var err error if *useHTTP2 { config.NextProtos = []string{"h2"} } config.Certificates = make([]tls.Certificate, 1) config.Certificates[0], err = tls.LoadX509KeyPair(certFile, keyFile) if err != nil { log.Fatal(err) } srv := &http.Server{Addr: *addr, TLSConfig: &config, Handler: http.HandlerFunc(validate)} tlsListener := tls.NewListener(l, &config) log.Fatal(srv.Serve(tlsListener)) } }
func TestServerExpiration(t *testing.T) { // Start a backend. beLis, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("Failed to listen %v", err) } beAddr := strings.Split(beLis.Addr().String(), ":") bePort, err := strconv.Atoi(beAddr[1]) backends := startBackends(t, besn, beLis) defer stopBackends(backends) // Start a load balancer. lbLis, err := net.Listen("tcp", "localhost:0") if err != nil { t.Fatalf("Failed to create the listener for the load balancer %v", err) } lbCreds := &serverNameCheckCreds{ sn: lbsn, } lb := grpc.NewServer(grpc.Creds(lbCreds)) if err != nil { t.Fatalf("Failed to generate the port number %v", err) } be := &lbpb.Server{ IpAddress: []byte(beAddr[0]), Port: int32(bePort), LoadBalanceToken: lbToken, } var bes []*lbpb.Server bes = append(bes, be) exp := &lbpb.Duration{ Seconds: 0, Nanos: 100000000, // 100ms } var sls []*lbpb.ServerList sl := &lbpb.ServerList{ Servers: bes, ExpirationInterval: exp, } sls = append(sls, sl) sl = &lbpb.ServerList{ Servers: bes, } sls = append(sls, sl) var intervals []time.Duration intervals = append(intervals, 0) intervals = append(intervals, 500*time.Millisecond) ls := newRemoteBalancer(sls, intervals) lbpb.RegisterLoadBalancerServer(lb, ls) go func() { lb.Serve(lbLis) }() defer func() { ls.stop() lb.Stop() }() creds := serverNameCheckCreds{ expected: besn, } ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) cc, err := grpc.DialContext(ctx, besn, grpc.WithBalancer(Balancer(&testNameResolver{ addr: lbLis.Addr().String(), })), grpc.WithBlock(), grpc.WithTransportCredentials(&creds)) if err != nil { t.Fatalf("Failed to dial to the backend %v", err) } helloC := hwpb.NewGreeterClient(cc) if _, err := helloC.SayHello(context.Background(), &hwpb.HelloRequest{Name: "grpc"}); err != nil { t.Fatalf("%v.SayHello(_, _) = _, %v, want _, <nil>", helloC, err) } // Sleep and wake up when the first server list gets expired. time.Sleep(150 * time.Millisecond) if _, err := helloC.SayHello(context.Background(), &hwpb.HelloRequest{Name: "grpc"}); grpc.Code(err) != codes.Unavailable { t.Fatalf("%v.SayHello(_, _) = _, %v, want _, %s", helloC, err, codes.Unavailable) } // A non-failfast rpc should be succeeded after the second server list is received from // the remote load balancer. if _, err := helloC.SayHello(context.Background(), &hwpb.HelloRequest{Name: "grpc"}, grpc.FailFast(false)); err != nil { t.Fatalf("%v.SayHello(_, _) = _, %v, want _, <nil>", helloC, err) } cc.Close() }