Golang gRPC学习(04): Deadlines超时限制
为什么要使用Deadlines#
当我们使用gRPC时,gRPC库关系的是连接,序列化,反序列化和超时执行。Deadlines 允许gRPC客户端设置自己等待多长时间来完成rpc操作,直到出现这个错误 DEADLINE_EXCEEDED。但是在正常情况下,这个DEADLINE_EXCEEDED默认设置是一个很大的数值。
一些语言的API用deadline,一些用 timeout。
在正常情况下,你没有设置deadline,那么所有的请求可能在最大请求时间过后才超时。这样你对于你的服务器资源,可能存在风险,比如内存,可能因为这个长期运行的服务而增长很快,从而耗尽资源。
为了避免这种情况,需要给你的客户端请求程序设置一个默认的超时时间,在这段时间内请求没有返回,那么就超时报错。
怎么使用?Deadlines使用步骤#
使用步骤:#
1.设置deadlines
Copy
var deadlineMs = flag.Int(“deadline_ms”, 20*1000, “Default deadline in milliseconds.”)
clientDeadline := time.Now().Add(time.Duration(*deadlineMs) * time.Millisecond)
ctx, cancel := context.WithDeadline(ctx, clientDeadline)
2.检查deadlines
Copy
if ctx.Err() == context.Canceled {
return status.New(codes.Canceled, “Client cancelled, abandoning.”)
}
具体使用:#
- 建立连接时超时控制:
客户端建立连接时,使用的Dial()函数,它位于
google.golang.org/grpc/clientconn.go 中,我们看看这个函数内容:
Copy
func Dial(target string, opts …DialOption) (*ClientConn, error) {
return DialContext(context.Background(), target, opts…)
}
它里面调用的 DialContext() 函数,这个函数非常长,他们在同一个文件中,它是实际执行的函数,这里面就有context的timeout和Done相关操作。你也可以到google.golang.org/grpc/clientconn.go文件中去看看这个函数DialContext具体是干嘛的。
使用的时候传入设置timeout的context,如下:
Copy
ctx, cancel := context.Timeout(context.Bakcground(), time.Second*5)
defer cancel()
conn, err := grpc.DialContext(ctx, address, grpc.WithBlock(), grpc.WithInsecure())
grpc.WithInsecure() ,这个参数啥意思?
gRPC是建立在HTTP/2上的,所以对TLS提供了很好的支持。如果在客户端建立连接过程中设置 grpc.WithInsecure() 就可以跳过对服务器证书的验证。写练习时可以用这个参数,但是在真实的环境中,不要这样做,因为有泄露信息的风险。
grpc.WithBlock()
这个参数会阻塞等待握手成功。
因为用Dial连接时是异步连接,连接状态为正在连接,如果设置了这个参数就是同步连接,会阻塞等待握手成功。
这个还和超时设置有关,如果你没有设置这个参数,那么context超时控制将会失效。
2. 调用时超时:
函数的调用超时控制
Copy
ctx, cancel := context.WithTimeout(context.TODO(), time.Second*5)
defer cancel()
result, err := c.SayHello(ctx, &pb.HelloRequest{Name: name})
实例#
用grpc官方的例子来练习下
目录结构:
Copy
grpc-tutorial
– 04deadlines
–client
- main.go
–server
- main.go
–proto/echo
- echo.proto
- echo.pb.go
1.首先是定义服务 echo.proto#
Copy
syntax = “proto3”;
package echo;message
EchoRequest {
string message = 1;
}
message EchoResponse {
string message = 1;
}
service Echo {
rpc UnaryEcho(EchoRequest) returns (EchoRequest) {}
rpc ServerStreamingEcho(EchoRequest) returns (stream EchoResponse) {}
rpc ClientStreamingEcho(stream EchoRequest) returns (EchoResponse) {}
rpc BidirectionalStreamingEcho(stream EchoRequest) returns (stream EchoResponse){}
}
进入到proto/echo目录,生成go文件,命令如下:
protoc -I . --go_out=plugins=grpc:. ./echo.proto
2.客户端#
client\main.go
有2个主要的函数,2端都是stream和都不是stream,先看都不是stream的函数
都不是stream的函数
Copy
// unaryCall 不是stream的请求
func unaryCall(c pb.EchoClient, requestID int, message string, want codes.Code) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second) //超时设置
defer cancel()
req := &pb.EchoRequest{Message: message} //参数部分_, err := c.UnaryEcho(ctx, req) //调用函数发送请求给服务端
got := status.Code(err) //
fmt.Printf("[%v] wanted = %v, got = %v\n", requestID, want, got)
}
上面的code设置在文件 grpc/codes/codes.go
Copy
type Code uint32
const (
OK Code = 0
Canceled Code = 1
Unknown Code = 2
InvalidArgument Code = 3
DeadlineExceeded Code = 4
… …
)
2端都是stream的函数:
Copy
// streamingCall,2端都是stream
func streamingCall(c pb.EchoClient, requestID int, message string, want codes.Code) {
ctx, cancel := context.WithTimeout(context.Background(), time.Second)//超时设置
defer cancel()
stream, err := c.BidirectionalStreamingEcho(ctx)//双向stream
if err != nil {log.Printf("Send error : %v", err)return
}err = stream.Send(&pb.EchoRequest{Message: message})//发送
if err != nil {log.Printf("Send error : %v", err)return
}_, err = stream.Recv() //接收got := status.Code(err)
fmt.Printf("[%v] wanted = %v, got = %v\n", requestID, want, got)
}
main 执行函数
Copy
func main() {
flag.Parse()
conn, err := grpc.Dial(*addr, grpc.WithInsecure(), grpc.WithBlock())
if err != nil {log.Fatalf("did not connect : %v ", err)
}
defer conn.Close()c :=pb.NewEchoClient(conn)// 成功请求
unaryCall(c, 1, "word", codes.OK)
// 超时 deadline
unaryCall(c, 2, "delay", codes.DeadlineExceeded)
// A successful request with propagated deadline
unaryCall(c, 3, "[propagate me]world", codes.OK)
// Exceeds propagated deadline
unaryCall(c, 4, "[propagate me][propagate me]world", codes.DeadlineExceeded)
// Receives a response from the stream successfully.
streamingCall(c, 5, "[propagate me]world", codes.OK)
// Exceeds propagated deadline before receiving a response
streamingCall(c, 6, "[propagate me][propagate me]world", codes.DeadlineExceeded)
}
3.服务端#
定义一个struct
Copy
type server struct {
pb.UnimplementedEchoServer
client pb.EchoClient
cc *grpc.ClientConn
}
2端不是stream的函数:
Copy
func (s *server) UnaryEcho(ctx context.Context, req *pb.EchoRequest)(*pb.EchoResponse, error) {
message := req.Message
if strings.HasPrefix(message, “[propagate me]”) {//判断接收的值
time.Sleep(800 * time.Millisecond)
message := strings.TrimPrefix(message, “[propagate me]”)
return s.client.UnaryEcho(ctx, &pb.EchoRequest{Message:message}) //<1>
}
if message == "delay" {time.Sleep(1500 * time.Millisecond) // message=delay 时睡眠1500毫秒,大于client的设置的1秒,这里就超时了
}return &pb.EchoResponse{Message:message}, nil
}
上面函数标注 <1> 这个地方比较有意思,当client端发送的字符串包含 [propagate me] 字符串时,先睡眠800毫秒,然后在重新执行客户端请求服务端的函数 s.client.UnaryEcho() , 在次运行到服务端的 UnaryEcho(),客户端已经超时了。
也就是说client/main.go 先请求了一次服务端,然后在server/main.go 的函数 func (s *server) UnaryEcho(ctx context.Context, req *pb.EchoRequest)又执行了一次请求服务端,所以会导致超时。
2端设置stream的函数:
Copy
func (s *server) BidirectionalStreamingEcho(stream pb.Echo_BidirectionalStreamingEchoServer) error {
for {
req, err := stream.Recv()
if err == io.EOF {
return status.Error(codes.InvalidArgument, “request message not received”)
}
if err != nil {
return err
}
message := req.Messageif strings.HasPrefix(message, "[propagate me]") {time.Sleep(800 * time.Millisecond)message = strings.TrimPrefix(message, "[propagate me]")res, err := s.client.UnaryEcho(stream.Context(), &pb.EchoRequest{Message:message})//再次执行客户端请求服务端函数,这里可能会超时if err != nil {return err}stream.Send(res)}if message == "delay" {time.Sleep(1500 * time.Millisecond)}stream.Send(&pb.EchoResponse{Message:message})
}
}
main函数
Copy
func main() {
flag.Parse()
address := fmt.Sprintf(":%v", *port)
lis, err := net.Listen("tcp", address)
if err != nil {log.Fatalf("failed to listen: %v ", err)
}echoServer := newEchoServer()
defer echoServer.Close()grpcServer := grpc.NewServer()
pb.RegisterEchoServer(grpcServer, echoServer)if err := grpcServer.Serve(lis); err != nil {log.Fatalf("failed to serve: %v ", err)
}
}
执行#
先运行 /server/main.go , go run main.go
在运行 /client/main.go, go run main.go
执行结果:
Copy
go run main.go
[1] wanted = OK, got = OK
[2] wanted = DeadlineExceeded, got = DeadlineExceeded
[3] wanted = OK, got = Unavailable
[4] wanted = DeadlineExceeded, got = Unavailable
[5] wanted = OK, got = Unavailable
[6] wanted = DeadlineExceeded, got = Unavailable
gRPC 系列代码地址:#
01hello grpc helloworld
02fourinteractionmode grpc 四种传输方式
03customer grpc 一个小练习demo
04deadlines grpc 超时限制
https://www.dwell.com/@LmMW8tU764
https://www.dwell.com/@LmMW8tU764/followers
https://www.dwell.com/@LmMW8tU764/following
https://www.dwell.com/@W0DA3B2vD3
https://www.dwell.com/@W0DA3B2vD3/followers
https://www.dwell.com/@W0DA3B2vD3/following
https://www.dwell.com/@bp0yDTlOL
https://www.dwell.com/@bp0yDTlOL/followers
https://www.dwell.com/@bp0yDTlOL/following
https://www.dwell.com/@qEQq0N5udc
https://www.dwell.com/@qEQq0N5udc/followers
https://www.dwell.com/@qEQq0N5udc/following
https://www.dwell.com/@Rct0xZNiu
https://www.dwell.com/@Rct0xZNiu/followers
https://www.dwell.com/@Rct0xZNiu/following
https://www.dwell.com/@LiXk8hB3ELR
https://www.dwell.com/@LiXk8hB3ELR/followers
https://www.dwell.com/@LiXk8hB3ELR/following
https://www.dwell.com/@K68Y3eczo3
https://www.dwell.com/@K68Y3eczo3/followers
https://www.dwell.com/@K68Y3eczo3/following
https://www.dwell.com/@BPENd17H8sG
https://www.dwell.com/@BPENd17H8sG/followers
https://www.dwell.com/@BPENd17H8sG/following
https://www.dwell.com/@8H854qEx9
https://www.dwell.com/@8H854qEx9/followers
https://www.dwell.com/@8H854qEx9/following
https://www.dwell.com/@p9OI4nPyR6v
https://www.dwell.com/@p9OI4nPyR6v/followers
https://www.dwell.com/@p9OI4nPyR6v/following
https://www.dwell.com/@u72Y7dA7PH
https://www.dwell.com/@u72Y7dA7PH/followers
https://www.dwell.com/@u72Y7dA7PH/following
https://www.dwell.com/@kB44RxCit
https://www.dwell.com/@kB44RxCit/followers
https://www.dwell.com/@kB44RxCit/following
https://www.dwell.com/@yq7s7q8fh7
https://www.dwell.com/@yq7s7q8fh7/followers
https://www.dwell.com/@yq7s7q8fh7/following
https://www.dwell.com/@6BSbDdPx3
https://www.dwell.com/@6BSbDdPx3/followers
https://www.dwell.com/@6BSbDdPx3/following
https://www.dwell.com/@9SI165V3DT
https://www.dwell.com/@9SI165V3DT/followers
https://www.dwell.com/@9SI165V3DT/following
https://www.dwell.com/@d65RKKfNBR
https://www.dwell.com/@d65RKKfNBR/followers
https://www.dwell.com/@d65RKKfNBR/following
https://www.dwell.com/@8fuJO2gKr
https://www.dwell.com/@8fuJO2gKr/followers
https://www.dwell.com/@8fuJO2gKr/following
https://www.dwell.com/@5iN4K4FlXC
https://www.dwell.com/@5iN4K4FlXC/followers
https://www.dwell.com/@5iN4K4FlXC/following
https://www.dwell.com/@vw10NbDzL
https://www.dwell.com/@vw10NbDzL/followers
https://www.dwell.com/@vw10NbDzL/following
https://www.dwell.com/@QTh36P44iK9
https://www.dwell.com/@QTh36P44iK9/followers
https://www.dwell.com/@QTh36P44iK9/following
https://www.dwell.com/@ZZDgB2AS5
https://www.dwell.com/@ZZDgB2AS5/followers
https://www.dwell.com/@ZZDgB2AS5/following
https://www.dwell.com/@fr7ZalK6D
https://www.dwell.com/@fr7ZalK6D/followers
https://www.dwell.com/@fr7ZalK6D/following
https://www.dwell.com/@LWyU6o67s
https://www.dwell.com/@LWyU6o67s/followers
https://www.dwell.com/@LWyU6o67s/following
https://www.dwell.com/@v1v49prK5k
https://www.dwell.com/@v1v49prK5k/followers
https://www.dwell.com/@v1v49prK5k/following
https://www.dwell.com/@S7ToUpi20
https://www.dwell.com/@S7ToUpi20/followers
https://www.dwell.com/@S7ToUpi20/following
https://www.dwell.com/@h9WPb2rw93
https://www.dwell.com/@h9WPb2rw93/followers
https://www.dwell.com/@h9WPb2rw93/following
https://www.dwell.com/@5yQJ67683
https://www.dwell.com/@5yQJ67683/followers
https://www.dwell.com/@5yQJ67683/following
https://www.dwell.com/@SrxYclmHS4g
https://www.dwell.com/@SrxYclmHS4g/followers
https://www.dwell.com/@SrxYclmHS4g/following
https://www.dwell.com/@2LZoaQ92l
https://www.dwell.com/@2LZoaQ92l/followers
https://www.dwell.com/@2LZoaQ92l/following
https://www.dwell.com/@V9pyDZ6gRXN
https://www.dwell.com/@V9pyDZ6gRXN/followers
https://www.dwell.com/@V9pyDZ6gRXN/following
https://www.dwell.com/@e4pDBOcNlkD
https://www.dwell.com/@e4pDBOcNlkD/followers
https://www.dwell.com/@e4pDBOcNlkD/following
https://www.dwell.com/@t2Ie7oV09nf
https://www.dwell.com/@t2Ie7oV09nf/followers
https://www.dwell.com/@t2Ie7oV09nf/following
https://www.dwell.com/@tvg6PT101XE
https://www.dwell.com/@tvg6PT101XE/followers
https://www.dwell.com/@tvg6PT101XE/following
https://www.dwell.com/@zUUImnUT1
https://www.dwell.com/@zUUImnUT1/followers
https://www.dwell.com/@zUUImnUT1/following
https://www.dwell.com/@18y3WC3OU
https://www.dwell.com/@18y3WC3OU/followers
https://www.dwell.com/@18y3WC3OU/following
https://www.dwell.com/@TGMmUuXjNf7
https://www.dwell.com/@TGMmUuXjNf7/followers
https://www.dwell.com/@TGMmUuXjNf7/following
https://www.dwell.com/@a79GrLYg7
https://www.dwell.com/@a79GrLYg7/followers
https://www.dwell.com/@a79GrLYg7/following
https://www.dwell.com/@hO1Zr899RU
https://www.dwell.com/@hO1Zr899RU/followers
https://www.dwell.com/@hO1Zr899RU/following
https://www.dwell.com/@S749Y1E56A
https://www.dwell.com/@S749Y1E56A/followers
https://www.dwell.com/@S749Y1E56A/following
https://www.dwell.com/@6B481766I
https://www.dwell.com/@6B481766I/followers
https://www.dwell.com/@6B481766I/following
https://www.dwell.com/@HLb0KGlim4L
https://www.dwell.com/@HLb0KGlim4L/followers
https://www.dwell.com/@HLb0KGlim4L/following
https://www.dwell.com/@1L76LWgmy3
https://www.dwell.com/@1L76LWgmy3/followers
https://www.dwell.com/@1L76LWgmy3/following
https://www.dwell.com/@5r3289lRw7d
https://www.dwell.com/@5r3289lRw7d/followers
https://www.dwell.com/@5r3289lRw7d/following
https://www.dwell.com/@taAbYF5k4
https://www.dwell.com/@taAbYF5k4/followers
https://www.dwell.com/@taAbYF5k4/following
https://www.dwell.com/@L1dnJ8pc6J
https://www.dwell.com/@L1dnJ8pc6J/followers
https://www.dwell.com/@L1dnJ8pc6J/following
https://www.dwell.com/@tZr8IFB59
https://www.dwell.com/@tZr8IFB59/followers
https://www.dwell.com/@tZr8IFB59/following
https://www.dwell.com/@bXIdAS5r47
https://www.dwell.com/@bXIdAS5r47/followers
https://www.dwell.com/@bXIdAS5r47/following
https://www.dwell.com/@mAQCccrNI
https://www.dwell.com/@mAQCccrNI/followers
https://www.dwell.com/@mAQCccrNI/following
https://www.dwell.com/@2JF9K68N1r
https://www.dwell.com/@2JF9K68N1r/followers
https://www.dwell.com/@2JF9K68N1r/following
https://www.dwell.com/@DxVa6Y4zK5
https://www.dwell.com/@DxVa6Y4zK5/followers
https://www.dwell.com/@DxVa6Y4zK5/following
https://www.dwell.com/@648OV4r9fE
https://www.dwell.com/@648OV4r9fE/followers
https://www.dwell.com/@648OV4r9fE/following
https://www.dwell.com/@C34BT9Ug6F
https://www.dwell.com/@C34BT9Ug6F/followers
https://www.dwell.com/@C34BT9Ug6F/following
https://www.dwell.com/@6Y4dsQ8511r
https://www.dwell.com/@6Y4dsQ8511r/followers
https://www.dwell.com/@6Y4dsQ8511r/following
https://www.dwell.com/@72RF82R3jZ2
https://www.dwell.com/@72RF82R3jZ2/followers
https://www.dwell.com/@72RF82R3jZ2/following
https://www.dwell.com/@L3U71yM3YGY
https://www.dwell.com/@L3U71yM3YGY/followers
https://www.dwell.com/@L3U71yM3YGY/following
https://www.dwell.com/@Txn8yE3N5j
https://www.dwell.com/@Txn8yE3N5j/followers
https://www.dwell.com/@Txn8yE3N5j/following
https://www.dwell.com/@h79cN55qRs
https://www.dwell.com/@h79cN55qRs/followers
https://www.dwell.com/@h79cN55qRs/following
https://www.dwell.com/@C93VW9vcS
https://www.dwell.com/@C93VW9vcS/followers
https://www.dwell.com/@C93VW9vcS/following
https://www.dwell.com/@OVnvJq766IL
https://www.dwell.com/@OVnvJq766IL/followers
https://www.dwell.com/@OVnvJq766IL/following
https://www.dwell.com/@I4K0uqT5ybs
https://www.dwell.com/@I4K0uqT5ybs/followers
https://www.dwell.com/@I4K0uqT5ybs/following
https://www.dwell.com/@R5W8dgxQ44L
https://www.dwell.com/@R5W8dgxQ44L/followers
https://www.dwell.com/@R5W8dgxQ44L/following
https://www.dwell.com/@RZ27cM8Hg
https://www.dwell.com/@RZ27cM8Hg/followers
https://www.dwell.com/@RZ27cM8Hg/following
https://www.dwell.com/@nVT889x9YKP
https://www.dwell.com/@nVT889x9YKP/followers
https://www.dwell.com/@nVT889x9YKP/following
https://www.dwell.com/@Q492717sldw
https://www.dwell.com/@Q492717sldw/followers
https://www.dwell.com/@Q492717sldw/following
https://www.dwell.com/@0KF9G7Ckm0
https://www.dwell.com/@0KF9G7Ckm0/followers
https://www.dwell.com/@0KF9G7Ckm0/following
https://www.dwell.com/@An2WgA4oDg
https://www.dwell.com/@An2WgA4oDg/followers
https://www.dwell.com/@An2WgA4oDg/following
https://www.dwell.com/@Tw05LPEBcB
https://www.dwell.com/@Tw05LPEBcB/followers
https://www.dwell.com/@Tw05LPEBcB/following
https://www.dwell.com/@nGITskEHE
https://www.dwell.com/@nGITskEHE/followers
https://www.dwell.com/@nGITskEHE/following
https://www.dwell.com/@82vqq0Il401
https://www.dwell.com/@82vqq0Il401/followers
https://www.dwell.com/@82vqq0Il401/following
https://www.dwell.com/@p6LEq9eqdv
https://www.dwell.com/@p6LEq9eqdv/followers
https://www.dwell.com/@p6LEq9eqdv/following
https://www.dwell.com/@zk0tMrW7G6f
https://www.dwell.com/@zk0tMrW7G6f/followers
https://www.dwell.com/@zk0tMrW7G6f/following
https://www.dwell.com/@qQQMtvGD95
https://www.dwell.com/@qQQMtvGD95/followers
https://www.dwell.com/@qQQMtvGD95/following
https://www.dwell.com/@0AdBwY47c
https://www.dwell.com/@0AdBwY47c/followers
https://www.dwell.com/@0AdBwY47c/following
https://www.dwell.com/@Q6W8y7pxx
https://www.dwell.com/@Q6W8y7pxx/followers
https://www.dwell.com/@Q6W8y7pxx/following
https://www.dwell.com/@kPIgdvuIGWw
https://www.dwell.com/@kPIgdvuIGWw/followers
https://www.dwell.com/@kPIgdvuIGWw/following
https://www.dwell.com/@Q2E5m7G0Z
https://www.dwell.com/@Q2E5m7G0Z/followers
https://www.dwell.com/@Q2E5m7G0Z/following
https://www.dwell.com/@MrL39P7fM
https://www.dwell.com/@MrL39P7fM/followers
https://www.dwell.com/@MrL39P7fM/following
https://www.dwell.com/@6rbQN5W5N9
https://www.dwell.com/@6rbQN5W5N9/followers
https://www.dwell.com/@6rbQN5W5N9/following
https://www.dwell.com/@YQKqAsy4O9S
https://www.dwell.com/@YQKqAsy4O9S/followers
https://www.dwell.com/@YQKqAsy4O9S/following
https://www.dwell.com/@e8Dd9hbDgy4
https://www.dwell.com/@e8Dd9hbDgy4/followers
https://www.dwell.com/@e8Dd9hbDgy4/following
https://www.dwell.com/@YKQ3IAlYR
https://www.dwell.com/@YKQ3IAlYR/followers
https://www.dwell.com/@YKQ3IAlYR/following
https://www.dwell.com/@Oxr1ew7b4
https://www.dwell.com/@Oxr1ew7b4/followers
https://www.dwell.com/@Oxr1ew7b4/following
https://www.dwell.com/@FEO099piVr
https://www.dwell.com/@FEO099piVr/followers
https://www.dwell.com/@FEO099piVr/following
https://www.dwell.com/@ivV5vXoBwPw
https://www.dwell.com/@ivV5vXoBwPw/followers
https://www.dwell.com/@ivV5vXoBwPw/following
https://www.dwell.com/@1LC807Xqq
https://www.dwell.com/@1LC807Xqq/followers
https://www.dwell.com/@1LC807Xqq/following
https://www.dwell.com/@YYvhK40My32
https://www.dwell.com/@YYvhK40My32/followers
https://www.dwell.com/@YYvhK40My32/following
https://www.dwell.com/@qvdt6WO11
https://www.dwell.com/@qvdt6WO11/followers
https://www.dwell.com/@qvdt6WO11/following
https://www.dwell.com/@MUs65gFROcj
https://www.dwell.com/@MUs65gFROcj/followers
https://www.dwell.com/@MUs65gFROcj/following
https://www.dwell.com/@1Htq80ZoMU9
https://www.dwell.com/@1Htq80ZoMU9/followers
https://www.dwell.com/@1Htq80ZoMU9/following
https://www.dwell.com/@bxE8Jl36MB
https://www.dwell.com/@bxE8Jl36MB/followers
https://www.dwell.com/@bxE8Jl36MB/following
https://www.dwell.com/@Dm6ZMSO6Li
https://www.dwell.com/@Dm6ZMSO6Li/followers
https://www.dwell.com/@Dm6ZMSO6Li/following
https://www.dwell.com/@24Pu12B4q25
https://www.dwell.com/@24Pu12B4q25/followers
https://www.dwell.com/@24Pu12B4q25/following
https://www.dwell.com/@s4FcN1Pxhg
https://www.dwell.com/@s4FcN1Pxhg/followers
https://www.dwell.com/@s4FcN1Pxhg/following
https://www.dwell.com/@985yYr0O7M
https://www.dwell.com/@985yYr0O7M/followers
https://www.dwell.com/@985yYr0O7M/following
https://www.dwell.com/@XYvACeV1O0
https://www.dwell.com/@XYvACeV1O0/followers
https://www.dwell.com/@XYvACeV1O0/following
https://www.dwell.com/@gOSB620G9
https://www.dwell.com/@gOSB620G9/followers
https://www.dwell.com/@gOSB620G9/following
https://www.dwell.com/@d1XAeYr7z
https://www.dwell.com/@d1XAeYr7z/followers
https://www.dwell.com/@d1XAeYr7z/following
https://www.dwell.com/@cXREjnYWH
https://www.dwell.com/@cXREjnYWH/followers
https://www.dwell.com/@cXREjnYWH/following
https://www.dwell.com/@3li41KI2O1
https://www.dwell.com/@3li41KI2O1/followers
https://www.dwell.com/@3li41KI2O1/following
https://www.dwell.com/@Aane00sMahn
https://www.dwell.com/@Aane00sMahn/followers
https://www.dwell.com/@Aane00sMahn/following
https://www.dwell.com/@6p09MqY2s
https://www.dwell.com/@6p09MqY2s/followers
https://www.dwell.com/@6p09MqY2s/following
https://www.dwell.com/@r5xL54r5Mi
https://www.dwell.com/@r5xL54r5Mi/followers
https://www.dwell.com/@r5xL54r5Mi/following
https://www.dwell.com/@K4swDpa2il
https://www.dwell.com/@K4swDpa2il/followers
https://www.dwell.com/@K4swDpa2il/following
Golang gRPC学习(04): Deadlines超时限制相关推荐
- gRPC学习与应用(1)
gRPC学习与应用(1) 一.gRPC简介[1] 1.概述 2.使用Protocol Buffers通信 2.1 数据结构定义 2.2 gRPC服务定义 二.核心概念 1.服务定义 2.同步调用 vs ...
- Golang 基础学习
Golang 基础学习 使用vscode开发配置国内源 dep包管理器 变量 常量 基本数据类型 判断数据类型 基本数据类型转换 整型 浮点型 布尔类型 字符串(两种) array数组与切片 数组定义 ...
- gRPC学习之六:gRPC-Gateway集成swagger
欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos gRPC学习系列文章链接 在CentOS7部署和设置G ...
- Golang gRPC 示例
Golang gRPC 示例 1.安装gRPC runtime go get google.golang.org/grpc 为了自动生成Golang的gRPC代码,需要安装protocal buffe ...
- JVM学习04:类的文件结构
JVM学习04:类的文件结构 写在前面:本系列分享主要参考资料是 周志明老师的<深入理解Java虚拟机>第二版. 类的文件结构知识要点Xmind梳理 转载于:https://www.cn ...
- JQuery学习04篇(层次选择器)
直接po图和代码 <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> < ...
- 【Golang | gRPC】使用protoc编译.proto文件
环境: Golang: go1.18.2 windows/amd64 protoc:libprotoc 3.21.1 1. 安装protoc 使用protoc编译.proto文件,首先需要正确安装pr ...
- sklearn学习04——DecisionTree
sklearn学习04--DecisionTree 前言 一.决策树原理 1.1.算法基本流程 1.2.最优划分属性的选择 二.sklearn代码实践 2.1.引入库 2.2.查看数据集信息 2.3. ...
- Golang初次学习
Golang初次学习 一. Golang的Windows环境搭建和开发工具 1. Golang语言简称go,其最流行的开发工具分为以下几种: 1)Vscode +go插件Vscode可能是大家或新手接 ...
最新文章
- Halcon模板轮廓坐标点获取
- 石墨烯可将硬盘容量提高十倍,剑桥在Nature子刊发表最新研究
- OpenKruise v0.8.0 版本:K8s 社区首个规模化镜像预热能力
- 实验3 编程、编译、链接、跟踪
- SQLServer学习笔记系列5
- 另一个进程已被死锁在资源上且该事务已被选作死锁牺牲品
- html5表单提交json数据库,使用html5的FormData对象,通过 Ajax表单异步提交文件数据...
- 线程挂起 阻止有什么区别c#
- Linux安装MariaDB
- MATLAB06:数字图像处理
- React 事件处理
- 我的世界Java种子算法_Minecraft:说说“种子”的使用和原理吧
- pancake-frontend(薄饼)二次开发
- 数据结构与算法-初识树和图
- CGB2104-Day17
- shell_小技巧_掐头去尾法
- java 保存微信表情_Java微信公众号开发之用户表情存储解决方案
- 欧文分校的计算机科学,有关美国加州大学欧文分校计算机科学专业.pdf
- 绿城x华为:抢占未来社区新风口,共绘理想生活图鉴
- IMU-TL740D的运行及相关资料
热门文章
- 全球前十名CRM(客户关系管理)系统分享系列(一)
- C# partial 关键字详解
- 计算机病毒原理与防治技术
- 软件设计师考试-法律法规与多媒体部分的笔记
- (移动端)省市区三级联动
- docker push到harbor私有仓库出现的相关问题及解决办法
- xmanager连接linux桌面教程(详)
- 在Cygwin中安装pkg-config指令包
- Python+vue房屋租赁系统django在线租房系统yjn76
- 【程序人生】行动型人格意味着一个人具备积极主动、果断执行的品质,这对于个人和职业生活的成功至关重要——如何养成“行动型人格”?| 高瓴Recommend