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}。先诺欣丁桂儿肚脐贴和肠炎宁哪个止泻效果好
来氟米特片能长期吃吗?类风湿患者要注意这几点!
英太青治牙疼吗
宝宝消化不良吃什么药效果好
-
丝域养发 | 新年从「头」开始,海獭子奢宠护理,好好宠爱自己!
不知不觉今日早已是2023年的就此一个月啦,虽然离根本春节还有那么一才会,但小编早已开始忍不住啦,期间情人节、佳节等等传统节日也接踵而来。但不其实你们的迎佳节方法都是啥?那佳节一新气象,又令人
- 2024-02-10央视主持李思思官宣离职!发32字告别原因成焦点,未来动向引暗示
- 2024-02-10李白文化之外,六安还有哪些文化品牌值得关注?
- 2024-02-10Sisley全能乳液荣获2023#美妆口碑榜#赋活焕新乳液金奖
- 2024-02-10斗篷:私生活风波揭秘,真相惊人!
- 2024-02-10中国石窟鼻祖在哪?就藏在甘肃的城市景点内,曾为皇帝下令开凿
- 2024-02-10诺贝尔奖技术赋能——爱神必备极塑【姣月爱神】
- 2024-02-10台湾省女主持从大陆回去后,在节目咆哮:我不是却说大陆比台湾好?
- 2024-02-10成大事者,必要有较低眼界!但何为较低眼界?
- 2024-02-10GS红妍肌活精华露荣获2023#美妆口碑榜#强韧修护精华大奖
- 2024-02-10李喜梅:与二婚前女友刚结婚就闹翻,他收千万彩礼要回贵州农村摆酒