Apache HTTPClient Tutorial 深度學習(二) 對於HTTP連接的管理
2.1. Connection persistence(連接持久性)
從一個主機到另一個主機之間建立連接的過程相當複雜並且涉及到兩個端點之間的多個包交換,這可能相當耗時的開銷。特別是對於小型HTTP消息,握手連接可能是很重要的。如果可以實現一個重新使用開放連接來執行多個請求,那麼就會有更高的數據吞吐量。
HTTP/1.1 聲明HTTP連接可以在每次默認的多個請求中被重用。HTTP
/ 1.0兼容的端點還可以使用一種機制來顯式地表達它們的首選項連接到多個請求,並使用它。HTTP代理還可以保持空閒連接的存在在特定的時間段內,對於後續請求,需要連接到相同的目標主機。保持連接的能力通常被稱爲連接持。HttpClient完全支持連接的持久性。
2.2. HTTP connection routing(HTTP連接路由)
HttpClient 可以直接或通過路由建立到目標主機的連接可能涉及多箇中間連接,也稱爲躍點。HttpClient
區別一條路線連接到一條平坦、隧道和分層的道路。
多中間代理的使用與目標主機的隧道連接被稱爲代理鏈接。
普通路由是通過連接到目標或第一個和唯一的代理來建立的。挖過的路線通過連接到第一個和隧道,通過連接到目標的一系列代理來建立。路線沒有代理,就不能被隧道掘進。分層路由是通過在一個協議之上建立一個協議來建立的。現有的連接。協議只能通過隧道到達目標,或者直接連接到目標上。沒有代理。
2.2.1. Route computation(路由估算)
RouteInfo接口表示關於目標主機的確定路由的信息一個或多箇中間步驟或躍點。HttpRoute是RouteInfo的具體實現,不能改變的(是不可變的)。HttpTracker是一個可變的RouteInfo實現在內部,HttpClient可以跟蹤剩餘的跳線到最終的路由目標。HttpTracker可以在成功執行下一跳到路由目標之後。HttpRouteDirector是一個助手類,可用於計算路由中的下一個步驟。這個類是在內部使用的HttpClient。
HttpRoutePlanner是一個接口,它表示一個策略,用於計算給定目標的完整路由基於執行上下文。HttpClient附帶兩個默認的http自豪計劃實現。SystemDefaultRoutePlanner基於java.net.ProxySelector。默認情況下,它會接收到JVM的代理設置,要麼來自系統屬性,要麼來自運行應用程序的瀏覽器。DefaultProxyRoutePlanner實現不使用任何Java系統屬性,也沒有任何系統或瀏覽器代理設置。它總是通過相同的默認代理計算路由。
2.2.2. Secure HTTP connections(安全的HTTP連接)
如果在兩個連接之間傳輸的信息,HTTP連接可以被認爲是安全的端點不能被未經授權的第三方讀取或篡改。SSL
/ TLS協議是用於確保HTTP傳輸安全性的最廣泛使用的技術。然而,其他加密技術也可以被運用。通常,HTTP傳輸是通過ssl/tls加密的連接。
2.3. HTTP connection managers(HTTP連接管理)
HTTP連接是複雜的、有狀態的、線程不安全的對象,需要正確地管理這些對象正確的函數。HTTP連接只能一次被一個執行線程使用。HttpClient使用一個特殊的實體來管理訪問HTTP連接管理器的HTTP連接管理器和由HttpClientConnectionManager接口。HTTP連接的目的管理器將作爲新的HTTP連接的工廠,管理持久性的生命週期連接和同步連接到持久連接,確保只有一個線程可以一次訪問連接。內部HTTP連接管理器與實例一起工作ManagedHttpClientConnection作爲代表一個真正的連接管理連接狀態並控制執行的輸入/輸出操作。如果一個託管連接被釋放或被顯式關閉通過它的使用者,底層連接從代理中分離,並返回到經理。儘管服務使用者仍然持有代理實例的引用,但它已不再能夠執行任何的輸入/輸出操作或改變真實連接的狀態無意中。
這是一個從連接管理器獲取連接的例子:
連接請求可以通過調用ConnectionRequest cancel()來提前終止。必要的。這將解開ConnectionRequest
get()方法中阻塞的線程。
2.3.2. Simple connection manager
BasicHttpClientConnectionManager是一個簡單的連接管理器,保持只有一個一次連接。儘管這個類是線程安全的,但它應該被一個執行線程使用只有。BasicHttpClientConnectionManager將爲後續努力重用連接使用相同路徑的請求。但是,它將關閉現有的連接並重新打開它給定路由,如果持久連接的路由與連接請求的路徑不匹配。如果連接已經被分配了,然後是java.lang。IllegalStateException拋出。該連接管理器實現應該在EJB容器內使用。
2.3.3. Pooling connection manager(連接池管理)
PoolingHttpClientConnectionManager是一個更復雜的實現管理池客戶端連接,並且能夠從多個執行線程中服務連接請求。連接在每個路由基礎上被彙集起來。對經理已經擁有的一條路線的請求
池中可用的持久連接將通過從池中租賃連接來服務而不是建立一個全新的聯繫。
PoolingHttpClientConnectionManager保持最大限度的連接每個路線基礎和總計。在默認情況下,該實現將創建不超過2個併發連接每個給定的路由,總共不超過20個連接。對於許多實際應用程序來說,這些限制可能會被證明過於約束,特別是當他們使用HTTP作爲他們的服務的傳輸協議時。
這個例子展示瞭如何調整連接池參數:
2.3.4. Connection manager shutdown(釋放連接)
當HttpClient實例不再需要並且即將退出時,關閉它是很重要的關閉它的連接管理器以確保管理器的所有連接都被關閉這些連接分配的系統資源被釋放。
2.4. Multithreaded request execution
當配備一個池PoolingClientConnectionManager等連接管理器,HttpClient可以被用來同時執行多個請求,同時使用多個線程執行。
根據其配置PoolingClientConnectionManager將分配連接。如果所有一個給定路由的連接已經被租借,一個連接的請求將被阻塞。直到連接被釋放到池中。可以確保連接管理器不會通過設置http.connmanager.超時,在連接請求操作中無限期地阻塞。一個積極的價值。如果在給定的時間段內不能對連接請求進行服務就會拋出onnectionPoolTimeoutException。
雖然HttpClient實例是線程安全的,並且可以在多個執行線程之間共享,強烈建議每個線程維護自己專用的HttpContext實例。
2.5. Connection eviction policy
經典阻塞輸入/輸出模型的主要缺點之一是網絡套接字可以對其進行響應只有在一個輸入/輸出操作中阻塞時纔會發生。當一個連接被釋放到經理的時候,它可以被保存,但是它不能監控套接字的狀態並對任何輸入/輸出事件作出反應。如果連接在服務器端關閉,則客戶端連接無法檢測到更改在連接狀態(並在結束時關閉套接字)。
HttpClient試圖通過測試連接是否“過時”來緩解這個問題,這是不存在的因爲它在服務器端關閉,在使用連接執行之前一個HTTP請求。過期的連接檢查不是100%可靠的。唯一可行的解決方案對於空閒連接來說,每個套接字模型都不涉及一個線程,這是一個專用的監視器線程用來清除由於長時間不活動而被認爲過期的連接。監控線程可以週期性地調用ClientConnectionManager關閉補償連接()方法關閉所有過期連接,並將關閉連接從池中清除。它還可以可選地調用ClientConnectionManager近端()方法來關閉所有連接在給定的一段時間內,這些都是閒置的。
2.6. Connection keep alive strategy
HTTP規範沒有指定持久連接可能存在多長時間,應該保持多長時間活着。一些HTTP服務器使用非標準的保持-活着的頭來與客戶端通信在幾秒鐘內,他們打算將連接保持在服務器端。HttpClient使如果有的話,可以使用這些信息。如果沒有在響應中出現keep活着的頭部,那麼HttpClient就會出現假設連接可以無限地存活。但是,通常使用的許多HTTP服務器在特定的一段時間不活動之後,配置爲減少持久連接,以便保存系統資源,經常不通知客戶。如果默認策略是過於樂觀的人可能會想要提供一種自定義的維持生命的策略。
2.7. Connection socket factories
HTTP連接在內部使用java.net.socket對象來處理數據的傳輸。過線。但是,它們依賴於ConnectionSocketFactory接口來創建、初始化和連接的套接字。這使HttpClient的用戶能夠提供特定於應用程序的套接字在運行時初始化代碼。PlainConnectionSocketFactory是默認爲創建和工廠初始化(加密)套接字。
創建套接字的過程和將其連接到主機的過程是解耦的,所以這個套接字在連接操作中被阻塞時,可以關閉。
2.7.1. Secure socket layering
LayeredConnectionSocketFactory ConnectionSocketFactory接口的一個擴展。分層套接字工廠能夠在現有的普通插座上創建套接字。套接字分層主要用於通過代理創建安全的套接字。HttpClient附帶實現ssl/tls分層的SSLSocketFactory。請注意,HttpClient不使用任何定製加密功能。它完全依賴於標準的Java加密(JCE)和安全套接字(JSEE)擴展。
2.7.2. Integration with connection manager
自定義連接套接字工廠可以與特定的協議方案相關聯,如HTTP或者HTTPS,然後用來創建一個自定義連接管理器。
2.7.3. SSL/TLS customization
HttpClient利用SSLConnectionSocketFactory創建SSL連接。SSLConnectionSocketFactory允許高度的定製。它可以舉一個例子作爲一個參數使用javax.ssl.sslcontext,並使用它創建自定義配置的SSL連接。
2.7.4. Hostname verification
除了在SSL上執行的信任驗證和客戶端身份驗證之外TLS協議級別,HttpClient可以選擇性地驗證目標主機名是否與此匹配存儲在服務器x中的名稱。當連接建立後,證書。這種驗證可以爲服務器信任材料的真實性提供額外的保證。javax.net.ssl.HostnameVerifier接口代表主機名驗證的策略。HttpClient附帶兩javax.net.ssl.HostnameVerifier實現。重要的是:主機名驗證不應與SSL信任驗證混淆。
- DefaultHostnameVerifier:HttpClient 使用的默認實現是符合RFC
2818。主機名必須匹配由該名稱指定的任何其他名稱證書,或者在沒有其他名稱的情況下,給出證書主題的最特定的CN。通配符可以在CN中出現,也可以在任何主項中出現。
- NoopHostnameVerifier:
這個主機名驗證器實際上是將主機名驗證關閉。接受任何SSL會話是有效的,並匹配目標主機。
在默認情況下,HttpClient使用DefaultHostnameVerifier實現。可以指定一個如果需要,不同的主機名驗證器實現
可以使用空matcher來禁用對公共列表的驗證。
2.8. HttpClient proxy configuration
儘管HttpClient知道複雜的路由方案和代理鏈接,但它只支持簡單的直接或單跳的代理連接。
要讓HttpClient通過代理連接到目標主機,最簡單的方法是設置缺省值代理參數:
您還可以指示HttpClient使用標準的JRE代理選擇器來獲取代理信息:
或者,您可以提供定製的RoutePlanner實現來完成一個完整的任務對HTTP路由計算過程的控制: