整体流程走完之后,我们回顾一下两个比较重要的结构体:persistConn和Transport的成员
// persistConn wraps a connection, usually a persistent one // (but may be used for non-keep-alive requests as well) type persistConn struct { // alt optionally specifies the TLS NextProto RoundTripper. // This is used for HTTP/2 today and future protocols later. // If it's non-nil, the rest of the fields are unused. alt RoundTripper t *Transport cacheKey connectMethodKey // 当前连接对应的key, 也是idleConns map中的key conn net.Conn // 被封装的conn对象 tlsState *tls.ConnectionState br *bufio.Reader // from conn // bufio.Reader 对象,封装conn bw *bufio.Writer // to conn // bufio.Writer 对象,封装conn nwrite int64 // bytes written // 记录写入的长度 reqch chan requestAndChan // written by roundTrip; read by readLoop // rountTrip在创建一个请求的时候会讲请求通过该chenel发送给readLoop, readLoop后面解释 writech chan writeRequest // written by roundTrip; read by writeLoop // writeTrop 从中读取写入请求并执行写入 closech chan struct{} // closed when conn closed // 连接关闭的时候从该channle通信 isProxy bool sawEOF bool // whether we've seen EOF from conn; owned by readLoop readLimit int64 // bytes allowed to be read; owned by readLoop // writeErrCh passes the request write error (usually nil) // from the writeLoop goroutine to the readLoop which passes // it off to the res.Body reader, which then uses it to decide // whether or not a connection can be reused. Issue 7569. writeErrCh chan error // writeLoopDone chan struct{} // closed when write loop ends // Both guarded by Transport.idleMu: idleAt time.Time // time it last become idle idleTimer *time.Timer // holding an AfterFunc to close it mu sync.Mutex // guards following fields numExpectedResponses int //表示当期期望的返回response数目 closed error // set non-nil when conn is closed, before closech is closed canceledErr error // set non-nil if conn is canceled broken bool // an error has happened on this connection; marked broken so it's not reused. reused bool // whether conn has had successful request/response and is being reused. // mutateHeaderFunc is an optional func to modify extra // headers on each outbound request before it's written. (the // original Request given to RoundTrip is not modified) mutateHeaderFunc func(Header) } type Transport struct { idleMu sync.Mutex // 互斥锁,用于保护下面空闲连接池 wantIdle bool // user has requested to close all idle conns// 标识是否idle idleConn map[connectMethodKey][]*persistConn // most recently used at end // 空闲连接池 idleConnCh map[connectMethodKey]chan *persistConn // 用于在groutine中间传递空闲的连接,一般用于当连接池中没有连接,但是还有请求需要处理,当连接池中出现空闲连接时通过该channel通知 idleLRU connLRU reqMu sync.Mutex reqCanceler map[*Request]func(error) altMu sync.Mutex // guards changing altProto only altProto atomic.Value // of nil or map[string]RoundTripper, key is URI scheme connCountMu sync.Mutex connPerHostCount map[connectMethodKey]int connPerHostAvailable map[connectMethodKey]chan struct{} // Proxy specifies a function to return a proxy for a given // Request. If the function returns a non-nil error, the // request is aborted with the provided error. // // The proxy type is determined by the URL scheme. "http", // "https", and "socks5" are supported. If the scheme is empty, // "http" is assumed. // // If Proxy is nil or returns a nil *URL, no proxy is used. Proxy func(*Request) (*url.URL, error) // DialContext specifies the dial function for creating unencrypted TCP connections. // If DialContext is nil (and the deprecated Dial below is also nil), // then the transport dials using package net. // // DialContext runs concurrently with calls to RoundTrip. // A RoundTrip call that initiates a dial may end up using // a connection dialed previously when the earlier connection // becomes idle before the later DialContext completes. DialContext func(ctx context.Context, network, addr string) (net.Conn, error)// 用于新建连接时使用 // Dial specifies the dial function for creating unencrypted TCP connections. // // Dial runs concurrently with calls to RoundTrip. // A RoundTrip call that initiates a dial may end up using // a connection dialed previously when the earlier connection // becomes idle before the later Dial completes. // // Deprecated: Use DialContext instead, which allows the transport // to cancel dials as soon as they are no longer needed. // If both are set, DialContext takes priority. Dial func(network, addr string) (net.Conn, error) // DialTLS specifies an optional dial function for creating // TLS connections for non-proxied HTTPS requests. // // If DialTLS is nil, Dial and TLSClientConfig are used. // // If DialTLS is set, the Dial hook is not used for HTTPS // requests and the TLSClientConfig and TLSHandshakeTimeout // are ignored. The returned net.Conn is assumed to already be // past the TLS handshake. DialTLS func(network, addr string) (net.Conn, error) // TLSClientConfig specifies the TLS configuration to use with // tls.Client. // If nil, the default configuration is used. // If non-nil, HTTP/2 support may not be enabled by default. TLSClientConfig *tls.Config // TLSHandshakeTimeout specifies the maximum amount of time waiting to // wait for a TLS handshake. Zero means no timeout. TLSHandshakeTimeout time.Duration // DisableKeepAlives, if true, disables HTTP keep-alives and // will only use the connection to the server for a single // HTTP request. // // This is unrelated to the similarly named TCP keep-alives. DisableKeepAlives bool // DisableCompression, if true, prevents the Transport from // requesting compression with an "Accept-Encoding: gzip" // request header when the Request contains no existing // Accept-Encoding value. If the Transport requests gzip on // its own and gets a gzipped response, it's transparently // decoded in the Response.Body. However, if the user // explicitly requested gzip it is not automatically // uncompressed. DisableCompression bool // MaxIdleConns controls the maximum number of idle (keep-alive) // connections across all hosts. Zero means no limit. MaxIdleConns int // MaxIdleConnsPerHost, if non-zero, controls the maximum idle // (keep-alive) connections to keep per-host. If zero, // DefaultMaxIdleConnsPerHost is used. MaxIdleConnsPerHost int // MaxConnsPerHost optionally limits the total number of // connections per host, including connections in the dialing, // active, and idle states. On limit violation, dials will block. // // Zero means no limit. // // For HTTP/2, this currently only controls the number of new // connections being created at a time, instead of the total // number. In practice, hosts using HTTP/2 only have about one // idle connection, though. MaxConnsPerHost int // IdleConnTimeout is the maximum amount of time an idle // (keep-alive) connection will remain idle before closing // itself. // Zero means no limit. IdleConnTimeout time.Duration // ResponseHeaderTimeout, if non-zero, specifies the amount of // time to wait for a server's response headers after fully // writing the request (including its body, if any). This // time does not include the time to read the response body. ResponseHeaderTimeout time.Duration // ExpectContinueTimeout, if non-zero, specifies the amount of // time to wait for a server's first response headers after fully // writing the request headers if the request has an // "Expect: 100-continue" header. Zero means no timeout and // causes the body to be sent immediately, without // waiting for the server to approve. // This time does not include the time to send the request header. ExpectContinueTimeout time.Duration // TLSNextProto specifies how the Transport switches to an // alternate protocol (such as HTTP/2) after a TLS NPN/ALPN // protocol negotiation. If Transport dials an TLS connection // with a non-empty protocol name and TLSNextProto contains a // map entry for that key (such as "h2"), then the func is // called with the request's authority (such as "example.com" // or "example.com:1234") and the TLS connection. The function // must return a RoundTripper that then handles the request. // If TLSNextProto is not nil, HTTP/2 support is not enabled // automatically. TLSNextProto map[string]func(authority string, c *tls.Conn) RoundTripper // ProxyConnectHeader optionally specifies headers to send to // proxies during CONNECT requests. ProxyConnectHeader Header // MaxResponseHeaderBytes specifies a limit on how many // response bytes are allowed in the server's response // header. // // Zero means to use a default limit. MaxResponseHeaderBytes int64 // nextProtoOnce guards initialization of TLSNextProto and // h2transport (via onceSetNextProtoDefaults) nextProtoOnce sync.Once h2transport h2Transport // non-nil if http2 wired up }golang http/transport 代码分析 (4)
内容版权声明:除非注明,否则皆为本站原创文章。