protobuf 介绍,Python 和 Go 编写 rpc 服务(gRPC) (23)

Go 客户端访问也是没有问题的,当然你也可以试试 Go 调用 Python 服务端,也是没有任何问题的。尽管不同语言的错误处理机制不同,但是 gRPC 已经帮你规避掉了。

grpc 的超时机制

rpc 调用涉及网络传输,如果出现了网络故障、抖动等等,那么会造成长时间不返回的情况,这个时候我们可以设置一个超时时间。我们在 Python 的服务端中 sleep 10 秒,然后客户端去调用:

import grpc pb2, pb2_grpc = grpc.protos_and_services("hello.proto") channel = grpc.insecure_channel("127.0.0.1:22222") client = pb2_grpc.HelloStub(channel=channel) try: response = client.SayHello(pb2.HelloRequest(name="神乐七奈"), timeout=3) # 3 秒钟超时 except grpc.RpcError as e: print(e.details()) # Deadline Exceeded print(e.code().name) # DEADLINE_EXCEEDED print(e.code().value) # (4, \'deadline exceeded\')

我们看到报了一个 DEADLINE_EXCEEDED,这是 gRPC 内置的错误。然后看看 Go 如何设置超时:

package main import ( "context" "fmt" "google.golang.org/grpc" "google.golang.org/grpc/status" "matsuri/yoyoyo" "time" ) func main() { // 这里调用 Python 的服务端,端口 22222 conn, err := grpc.Dial("127.0.0.1:22222", grpc.WithInsecure()) if err != nil { fmt.Println(err) return } defer func() { _ = conn.Close() }() client := yoyoyo.NewHelloClient(conn) // 使用 context.WithTimeout, 3 秒钟后取消 ctx, cancel := context.WithTimeout(context.Background(), time.Second * 3) defer cancel() // 这一步也可以不要,3s 后自动取消 _, err = client.SayHello(ctx, &yoyoyo.HelloRequest{}) if err != nil { st, ok := status.FromError(err) if !ok { fmt.Println("错误解析失败") return } // st.Message() 返回打印信息,一个字符串 // st.Code() 返回状态码,Code 类型、uint32 的别名 fmt.Println("错误信息:", st.Message()) fmt.Println("状态码:", st.Code()) } /* 错误信息: context deadline exceeded 状态码: DeadlineExceeded */ }

直接利用了标准库 context 方法。

小结

以上就是 Python 和 Go 编写 rpc 服务的一些知识点,总的来说 gRPC 是非常值得我们掌握的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zwfsgj.html