欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

GRPC中设置client的超时时间(golang)

程序员文章站 2024-03-14 14:12:34
...

超时

建立连接

主要就2函数Dail和DialContext。

// Dial creates a client connection to the given target.
func Dial(target string, opts ...DialOption) (*ClientConn, error) {
    return DialContext(context.Background(), target, opts...)
}
func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error){...}

DialContext 太长了不帖了.看Dial实际上也是调用DialContext来实现的.如果你想在建立连接的时候使用超时控制.就使用DialContext传入一个Timeout的context,就像下面的例子

ctx1, cel := context.WithTimeout(context.Background(), time.Second*3)
defer cel()
conn, err := grpc.DialContext(ctx1, address, grpc.WithBlock(), grpc.WithInsecure())

另外调用Dial建立连接默认只是返回一个ClientConn的指针,相当于new了一个ClientConn 把指针返回给你。并不是一定要建立真实的h2连接.至于真实的连接建立实际上是一个异步的过程。当然了如果你想等真实的链接完全建立再返回ClientConn可以通过WithBlock传入Options来实现,当然了这样的话链接如果建立不成功就会一直阻塞直到Contex超时。真正的建立链接的代码后面介绍重试的时候会再详细介绍。

调用超时

这个比较简单

ctx, cancel := context.WithTimeout(context.TODO(), time.Second*3)
defer cancel()
 r, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})

如上代码传入一个timeout context就可以。

Server

type SearchService struct{}

func (s *SearchService) Search(ctx context.Context, r *pb.SearchRequest) (*pb.SearchResponse, error) {
    for i := 0; i < 5; i++  {
        if ctx.Err() == context.Canceled {
            return nil, status.Errorf(codes.Canceled, "SearchService.Search canceled")
        }

        time.Sleep(1 * time.Second)
    }

    return &pb.SearchResponse{Response: r.GetRequest() + " Server"}, nil
}

func main() {
    ...
}

而在 Server 端,由于 Client 已经设置了截止时间。Server 势必要去检测它

否则如果 Client 已经结束掉了,Server 还傻傻的在那执行,这对资源是一种极大的浪费

因此在这里需要用 ctx.Err() == context.Canceled 进行判断,为了模拟场景我们加了循环和睡眠 ????

验证

重新启动 server.go 和 client.go,得到结果:

$ go run client.go
2018/10/06 17:45:55 client.Search err: deadline
exit status 1

总结

本章节比较简单,你需要知道以下知识点:

  • 怎么设置 Deadlines
  • 为什么要设置 Deadlines

你要清楚地明白到,gRPC Deadlines 是很重要的,否则这小小的功能点就会要了你生产的命

 

 

相关标签: grpc