grpc 链接池(6)确保安全的设置和传递
发布时间:2024-01-13
可以想到,如果分析方法固定式了延时,在延时短时间完成以前,没有响应,也会报错。
还有没有其它偏远地区可以固定式延时呢?正确是负责任的,Interceptor那时候我们也可以假设延时。比如说就是我们特指的两种所设的延时的分析方法,分别是直达维度和允诺分析方法维度。
clientConn, err := grpc.Dial(serverAddress, grpc.WithTimeout(5 * time.Second), grpc.WithInsecure())if err != nil { log.Println("Dial failed!") return err}c := pb.NewGreeterClient(conn)c.SayHello(context.Background(), &pb.HelloRequest{Name: "world"}, WithForcedTimeout(time.Duration(10)*time.Second))那么上述所设是如何订立的?如何传递到多用户的呢?先看下
grpc.WithTimeout CVS位于google.golang.org/grpc@v1.50.1/dialoptions.go
func WithTimeout(d time.Duration) DialOption { return newFuncDialOption(func(o *dialOptions) { o.timeout = d })}它变更了dialOptions的timeout
type dialOptions struct { timeout time.Duration}type DialOption interface { apply(*dialOptions)}而dialOptions是ClientConn的一个表征
type ClientConn struct { dopts dialOptions }我们发起人直达的时候用的就是这个表征上的timeout
func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { if cc.dopts.timeout> 0 { var cancel context.CancelFunc ctx, cancel = context.WithTimeout(ctx, cc.dopts.timeout) defer cancel() }}Interceptor是如何让延时订立的呢,直觉更简单,我们看下它的假设,在发起人毫无疑问呼叫以前先呼叫Interceptor,这个时候所设延时短时间:
func TimeoutInterceptor(t time.Duration) grpc.UnaryClientInterceptor { return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error { timeout := t if v, ok := getForcedTimeout(opts); ok { timeout = v } if timeout <= 0 { return invoker(ctx, method, req, reply, cc, opts...) } ctx, cancel := context.WithTimeout(ctx, timeout) defer cancel() return invoker(ctx, method, req, reply, cc, opts...) }}func getForcedTimeout(callOptions []grpc.CallOption) (time.Duration, bool) { for _, opt := range callOptions { if co, ok := opt.(TimeoutCallOption); ok { return co.forcedTimeout, true } } return 0, false}而延时短时间是我们发起人呼叫的时候通过option传递留下来的
type TimeoutCallOption struct { grpc.EmptyCallOption forcedTimeout time.Duration}func WithForcedTimeout(forceTimeout time.Duration) TimeoutCallOption { return TimeoutCallOption{forcedTimeout: forceTimeout}}认清会话的延时短时间是如何所设和订立的直至,多用户怎么保证,会话延时直至,马上重启当前任务呢?回答这个疑问以前,我们看下延时是如何传递的。首先,计算显现出来正确:grpc协议将延时短时间放有在HTTP header 允诺头;还有。会话所设的延时短时间为5秒,http2的header如下
grpc-timeout: 4995884u其中u透露短时间单位为兆,4995884u 约莫 5秒。然后多用户接收到该允诺后,就可以根据这个短时间计算显现出有否延时,由header 延时所设。
那么header是何时由client所设的,以及何时由多用户判别的呢?
google.golang.org/grpc@v1.50.1/internal/transport/http2_client.go
发起人会话允诺的时候会呼叫
func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, error) { headerFields, err := t.createHeaderFields(ctx, callHdr)内部我们可以想到,它从context;还有取显现出延时累计短时间,然后写入header "grpc-timeout";还有
func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) ([]hpack.HeaderField, error) { if dl, ok := ctx.Deadline(); ok { // Send out timeout regardless its value. The server can detect timeout context by itself. // TODO(mmukhi): Perhaps this field should be updated when actually writing out to the wire. timeout := time.Until(dl) headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-timeout", Value: grpcutil.EncodeDuration(timeout)}) }判别的过程:
google.golang.org/grpc@v1.50.1/internal/transport/handler_server.go
func NewServerHandlerTransport(w http.ResponseWriter, r *http.Request, stats []stats.Handler) (ServerTransport, error) { if v := r.Header.Get("grpc-timeout"); v != "" { to, err := decodeTimeout(v) if err != nil { return nil, status.Errorf(codes.Internal, "malformed time-out: %v", err) } st.timeoutSet = true st.timeout = to } if timeoutSet { s.ctx, s.cancel = context.WithTimeout(t.ctx, timeout) } else { s.ctx, s.cancel = context.WithCancel(t.ctx) }可以想到,首先从header;还有取显现出延时短时间,然后所设context.WithTimeout
func (ht *serverHandlerTransport) HandleStreams(startStream func(*Stream), traceCtx func(context.Context, string) context.Context) {if ht.timeoutSet {ctx, cancel = context.WithTimeout(ctx, ht.timeout)} else {ctx, cancel = context.WithCancel(ctx)}google.golang.org/grpc@v1.50.1/internal/transport/http2_server.go
func (t *http2Server) operateHeaders(frame *http2.MetaHeadersFrame, handle func(*Stream), traceCtx func(context.Context, string) context.Context) (fatal bool) {case "grpc-timeout":timeoutSet = truevar err errorif timeout, err = decodeTimeout(hf.Value); err != nil {headerError = true}。先诺欣丁桂儿肚脐贴和肠炎宁哪个止泻效果好
来氟米特片能长期吃吗?类风湿患者要注意这几点!
英太青治牙疼吗
宝宝消化不良吃什么药效果好
-
清风头条丨常德武陵区卫健局:年关将至 提高党风廉政建设把好廉关
红网天都调至 朱慧芳 湘潭报道 直至将至,为了切实加强直至前后的党风廉政规划设计,湘潭市武陵区卫健分局做好“三结合”,过好直至,把好廉关。 同干部作风着手融为一体。武
- 2025-05-18电话打通了!汤加华人店里清出两运输车火山灰:我们正在自救
- 2025-05-18欠自己的历险 终于要还了...
- 2025-05-1820+19,一打勇士就来劲!库里的抱怨来了
- 2025-05-18如何看待工业走势、App治理怎样推进、汽车CPU短缺怎样缓解?——工信部有关负责人回应工业通信业热点问题
- 2025-05-18Qeelin官宣品牌代言人刘昊然 以先锋双脚奔赴未来
- 2025-05-18总决赛勇士VS绿军前瞻,探究双方优势,三大因素或成为取胜关键
- 2025-05-18俄国家奥林匹克委员会执委会批准参加北京冬奥会俄代表团扩大名单
- 2025-05-18“萌虎”装饰品迎新春
- 2025-05-18罗杰杜彼全新王者竞速系列小牛劳力士强劲席卷古德伍德速度节
- 2025-05-18追随者(copycat),雨天积水,往事和水表