深刻剖析OkHttp系列(一) 来自官方的OkHttp设计思想(中英互译)

本文译自OkHttp官方Wiki文档git

The HTTP client’s job is to accept your request and produce its response. This is simple in theory but it gets tricky in practice.github

Callsweb

该HttpClient的做用是接收你的请求并生成响应。 这在理论上来讲是很简单的, 可是在实践上, 却很棘手。算法

Requests缓存

Each HTTP request contains a URL, a method (like GET or POST), and a list of headers. Requests may also contain a body: a data stream of a specific content type.服务器

每一个Http请求都包含一个URL, 一个方法(如GET或POST), 还有一系列的header。 Request中可能会包含一个Body: 一个特定类型的数据流。cookie

Responses网络

The response answers the request with a code (like 200 for success or 404 for not found), headers, and its own optional body.app

Response会以一个返回码(像请求成功的200 或 找不到请求的404), 一系列的请求头,以及它自身的body来响应你的请求。 less

Rewriting Requests

When you provide OkHttp with an HTTP request, you’re describing the request at a high-level: “fetch me this URL with these headers.” For correctness and efficiency, OkHttp rewrites your request before transmitting it.

当你经过OkHttp发起一个Http请求时, 其实你是在一个high-level上描述一个请求: “经过这些请求头访问这个URL”。 为了确保准确性和高效性, Okhttp会再请求传输以前, 重写你的请求。

OkHttp may add headers that are absent from the original request, including Content-Length, Transfer-Encoding, User-Agent, Host, Connection, and Content-Type. It will add an Accept-Encoding header for transparent response compression unless the header is already present. If you’ve got cookies, OkHttp will add a Cookie header with them.

OkHttp可能会再原始请求中添加缺乏的请求头, 包含Content-Length, Transfer-Encoding, User-Agent, Host, Connection, 和 Content-Type。 OkHttp将会为透明压缩响应添加一个Accept-Encoding请求头, 除非该请求头已经有了。若是你要获取cookies, OkHttp会添加一个Cookie请求头。

Some requests will have a cached response. When this cached response isn’t fresh, OkHttp can do a conditional GET to download an updated response if it’s newer than what’s cached. This requires headers like If-Modified-Since and If-None-Match to be added.

有些请求将会缓存响应。当这个缓存响应不是最新时, OkHttp会额外的执行一次Get请求去下载更新的响应, 若是这个响应比缓存的更新的话。这就须要像 If-Modified-Since and If-None-Match这样的请求头的添加。

Rewriting Responses

If transparent compression was used, OkHttp will drop the corresponding response headers Content-Encoding and Content-Length because they don’t apply to the decompressed response body.

若是要使用透明压缩, OkHttp将会删除相应的响应头Content-Encoding 和 Content-Length, 由于这些请求头是不适用于压缩响应体的。

If a conditional GET was successful, responses from the network and cache are merged as directed by the spec.

若是一个Get请求成功了, 网络和缓存的响应会直接按规范合并。

Follow-up Requests

When your requested URL has moved, the webserver will return a response code like 302 to indicate the document’s new URL. OkHttp will follow the redirect to retrieve a final response.

当你的请求URL被移动了, 服务器将会返回一个code, 如302,来指向文档的新URL。 OkHttp会遵循重定向来修正最终的响应。

If the response issues an authorization challenge, OkHttp will ask the Authenticator (if one is configured) to satisfy the challenge. If the authenticator supplies a credential, the request is retried with that credential included.

若是响应发出受权申请,OkHttp将会询问验证器(若是配置了的话)来响应申请。若是验证器提供了一个凭证, 此次请求会带着凭证从新请求。

Retrying Requests

Sometimes connections fail: either a pooled connection was stale and disconnected, or the webserver itself couldn’t be reached. OkHttp will retry the request with a different route if one is available.

有时链接失败: 池链接失效并断开链接, 或 服务器自己没法被访问。 OkHttp会经过不一样的有效路由重试请求。

Calls

With rewrites, redirects, follow-ups and retries, your simple request may yield many requests and responses. OkHttp uses Call to model the task of satisfying your request through however many intermediate requests and responses are necessary. Typically this isn’t many! But it’s comforting to know that your code will continue to work if your URLs are redirected or if you failover to an alternate IP address.

经过重写,重定向,后续追踪和重试, 你的简单的请求可能会产生不少请求和响应。OkHttp使用Call来模拟知足你请求的任务, 然而不少中间的请求和响应是必需的。一般这种状况不是不少!可是, 若是你的URL被重定向, 或者故障被转移到备用的IP地址,你的代码将依然有效的执行,这一点很棒!

Calls are executed in one of two ways:

Synchronous: your thread blocks until the response is readable. Asynchronous: you enqueue the request on any thread, and get called back on another thread when the response is readable.

Calls can be canceled from any thread. This will fail the call if it hasn’t yet completed! Code that is writing the request body or reading the response body will suffer an IOException when its call is canceled.

Calls能够被如下两种方式之一执行:
同步: 你的线程会阻塞, 知道响应返回。
异步: 你能够将请求加入任何线程, 并在响应返回时, 在其余线程回调

Calls能够任意线程被取消。 这将会在请求尚未完成时,使其失败。 在Call被取消后,正在写请求体或读响应体的代码将会抛出IO异常。

Dispatch

For synchronous calls, you bring your own thread and are responsible for managing how many simultaneous requests you make. Too many simultaneous connections wastes resources; too few harms latency.

For asynchronous calls, Dispatcher implements policy for maximum simultaneous requests. You can set maximums per-webserver (default is 5), and overall (default is 64).

对于同步请求, 你能够本身建立线程并负责管理同时发出的请求数。 同时发出太多请求会浪费资源, 太少会存在延迟的弊端。 对于异步请求, Dispatcher实现了最大同时请求的策略。 你能够设置每一个服务器的最大链接数(默认是5), 和总链接数(默认是64)。


Connections

Although you provide only the URL, OkHttp plans its connection to your webserver using three types: URL, Address, and Route.

尽管你只提供URL, OkHttp使用三种形式链接服务器:URL, 地址 和 路由。

URLS

URLs (like github.com/square/okht…) are fundamental to HTTP and the Internet. In addition to being a universal, decentralized naming scheme for everything on the web, they also specify how to access web resources.

URL是Http和网络的基础。除了用来在Web上做为一个统一的, 分散的命名方案外,它们还指明了如何来访问网络资源。

URLs are abstract:

They specify that the call may be plaintext (http) or encrypted (https), but not which cryptographic algorithms should be used. Nor do they specify how to verify the peer's certificates (the HostnameVerifier) or which certificates can be trusted (the SSLSocketFactory). They don't specify whether a specific proxy server should be used or how to authenticate with that proxy server.

URL是抽象的:
它们指明了call能够是明文或密文, 可是没有指明应该使用哪些加密算法。
它们没指明怎么去验证对方的证书, 或哪些证书能够被信任。
它们没有指明一个指定的代理服务是否能够被使用,或如何使用代理服务进行身份验证。

They're also concrete: each URL identifies a specific path (like /square/okhttp) and query (like ?q=sharks&lang=en). Each webserver hosts many URLs.

URL也是具体的:
每一个URL指定了一个特定的路径(如like/square/okhttp)和查询(如?q=sharks&lang=en)。每一个服务器持有不少URLS。

Addresses

Addresses specify a webserver (like github.com) and all of the static configuration necessary to connect to that server: the port number, HTTPS settings, and preferred network protocols (like HTTP/2 or SPDY).

Addresses指定了一个Web服务器和链接到这个服务器所需的全部静态配置: 端口号, HTTPS设置和相关的网络协议(如HTTP/2 或 SPDY)。

URLs that share the same address may also share the same underlying TCP socket connection. Sharing a connection has substantial performance benefits: lower latency, higher throughput (due to TCP slow start) and conserved battery. OkHttp uses a ConnectionPool that automatically reuses HTTP/1.x connections and multiplexes HTTP/2 and SPDY connections.

共享相同地址的URLs可能也会共享相同的底层TCP套接字链接。 共享链接具备显著的性能优点:
更低的延迟
更高的吞吐量(因为TCP的慢启动)
节省电源
OkHttp使用链接池, 自动重用 HTTP/1.x链接 并多路复用HTTP/2和SPDY链接。

In OkHttp some fields of the address come from the URL (scheme, hostname, port) and the rest come from the OkHttpClient.

在OkHttp中, Address的某些字段来自于URL(方案, 主机名, 端口) , 其他字段来自OkHttpClient。

Routes

Routes supply the dynamic information necessary to actually connect to a webserver. This is the specific IP address to attempt (as discovered by a DNS query), the exact proxy server to use (if a ProxySelector is in use), and which version of TLS to negotiate (for HTTPS connections).

路由提供了实际链接到Web服务器所需的动态信息。这是要尝试的特定IP地址(由DNS查询发现), 要使用的确切的代理服务器(若是使用了ProxySelector), 以及要协定的TLS版本(对于HTTPS链接而言)。

There may be many routes for a single address. For example, a webserver that is hosted in multiple datacenters may yield multiple IP addresses in its DNS response.

单个地址可能会有不少路由。 好比, 一个托管在多个数据中心的Web服务器, 可能会在DNS响应中产生多个IP地址。

Connections

When you request a URL with OkHttp, here's what it does:

It uses the URL and configured OkHttpClient to create an address. This address specifies how we'll connect to the webserver. It attempts to retrieve a connection with that address from the connection pool. If it doesn't find a connection in the pool, it selects a route to attempt. This usually means making a DNS request to get the server's IP addresses. It then selects a TLS version and proxy server if necessary. If it's a new route, it connects by building either a direct socket connection, a TLS tunnel (for HTTPS over an HTTP proxy), or a direct TLS connection. It does TLS handshakes as necessary. It sends the HTTP request and reads the response. If there's a problem with the connection, OkHttp will select another route and try again. This allows OkHttp to recover when a subset of a server's addresses are unreachable. It's also useful when a pooled connection is stale or if the attempted TLS version is unsupported.

当你使用OkHttp访问一个URL时, 它作了什么:
它使用URL和配置的OkHttpClient建立一个地址。 该地址指明了咱们如何链接Web服务器。它尝试经过这个地址从链接池中恢复这个链接。若是再链接池中没有找到链接,它会选择一个路由去尝试。这一般意味着发出一个DNS请求来获取服务端的IP地址。 而后若是须要, 它会选择一个TLS版本和代理服务。若是它是一个新的路由, 它会经过直接构建一个新的socket链接, 一个TLS通道(对于HTTP代理的HTTPS), 或者一个直接的TLS链接, 并根据须要进行TLS握手。

它发送一个HTTP请求并读取响应。

若是链接有问题, OkHttp会选择其余路由并从新尝试。这使得OkHttp当在一个服务器的地址的子集没法访问时,进行恢复。当池化链接失效, 或尝试的TLS版本不支持时, 也是有用的。

Once the response has been received, the connection will be returned to the pool so it can be reused for a future request. Connections are evicted from the pool after a period of inactivity.

一旦响应到达, 链接会返回到链接池中, 这样在之后的请求中就能够复用了。 一段时间不活跃后, 链接会从链接池中被移除。
相关文章
相关标签/搜索