精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

張開濤:超時與重試機制(1)

開發(fā) 開發(fā)工具
本文主要從Web應(yīng)用/服務(wù)化應(yīng)用的角度出發(fā)介紹如何設(shè)置超時與重試。

在實際開發(fā)過程中,筆者見過太多故障是因為超時沒有設(shè)置或者設(shè)置的不對而造成的。而這些故障都是因為沒有意識到超時設(shè)置的重要性而造成的。如果應(yīng)用不設(shè)置超時,則可能會導(dǎo)致請求響應(yīng)慢,慢請求累積導(dǎo)致連鎖反應(yīng),甚至應(yīng)用雪崩。而有些中間件或者框架在超時后會進行重試(如設(shè)置超時重試兩次),讀服務(wù)天然適合重試,但寫服務(wù)大多不能重試(如寫訂單,如果寫服務(wù)是冪等,則重試是允許的),重試次數(shù)太多會導(dǎo)致多倍請求流量,即模擬了DDoS攻擊,后果可能是災(zāi)難,因此,務(wù)必設(shè)置合理的重試機制,并且應(yīng)該和熔斷、快速失敗機制配合。在進行代碼Review時,一定記得Review超時與重試機制。

本文主要從Web應(yīng)用/服務(wù)化應(yīng)用的角度出發(fā)介紹如何設(shè)置超時與重試(系統(tǒng)層面的超時設(shè)置本文沒有涉及),而Web應(yīng)用需要在如下鏈條中設(shè)置超時與重試機制。

超時與重試機制

從上圖來看,在整個鏈條中的每一個點都要考慮設(shè)置超時與重試機制。而其中最重要的超時設(shè)置是網(wǎng)絡(luò)連接/讀/寫的超時時間設(shè)置。

本文將按照如下分類進行超時與重試機制的講解。

  • 代理層超時與重試:如Haproxy、Nginx、Twemproxy,這些組件實現(xiàn)代理功能,如Haproxy和Nginx可以實現(xiàn)請求的負(fù)載均衡。而Twemproxy可以實現(xiàn)Redis的分片代理。需要設(shè)置代理與后端真實服務(wù)器之間的網(wǎng)絡(luò)連接/讀/寫超時時間。
  • Web容器超時:如Tomcat、Jetty等,提供HTTP服務(wù)運行環(huán)境的。需要設(shè)置客戶端與容器之間的網(wǎng)絡(luò)連接/讀/寫超時時間,和在此容器中默認(rèn)Socket網(wǎng)絡(luò)連接/讀/寫超時時間。
  • 中間件客戶端超時與重試:如JSF(京東SOA框架)、Dubbo、JMQ(京東消息中間件)、CXF、Httpclient等,需要設(shè)置客戶的網(wǎng)絡(luò)連接/讀/寫超時時間與失敗重試機制。
  • 數(shù)據(jù)庫客戶端超時:如Mysql、Oracle,需要分別設(shè)置JDBC Connection、Statement的網(wǎng)絡(luò)連接/讀/寫超時時間。事務(wù)超時時間,獲取連接池連接等待時間。
  • NoSQL客戶端超時:如Mongo、Redis,需要設(shè)置其網(wǎng)絡(luò)連接/讀/寫超時時間,獲取連接池連接等待時間。
  • 業(yè)務(wù)超時:如訂單取消任務(wù)、超時活動關(guān)閉。還有如通過Future#get(timeout,unit)限制某個接口的超時時間。
  • 前端Ajax超時:瀏覽器通過Ajax訪問時的網(wǎng)絡(luò)連接/讀/寫超時時間。

從如上分類可以看出,其中最重要的超時設(shè)置是網(wǎng)絡(luò)相關(guān)的超時設(shè)置。

一、代理層超時與重試

對于代理層我們以Nginx和Twemproxy案例來講解。首先,看下Nginx的相關(guān)超時設(shè)置。

1. Nginx

Nginx主要有四類超時設(shè)置:客戶端超時設(shè)置、DNS解析超時設(shè)置、代理超時設(shè)置,如果使用ngx_lua,則還有l(wèi)ua相關(guān)的超時設(shè)置。

(1) 客戶端超時設(shè)置

對于客戶端超時主要設(shè)置有讀取請求頭超時時間、讀取請求體超時時間、發(fā)送響應(yīng)超時時間、長連接超時時間。通過客戶端超時設(shè)置避免客戶端惡意或者網(wǎng)絡(luò)狀況不佳造成連接長期占用,影響服務(wù)端的可處理的能力。

  • client_header_timeout time:設(shè)置讀取客戶端請求頭超時時間,默認(rèn)為60s,如果在此超時時間內(nèi)客戶端沒有發(fā)送完請求頭,則響應(yīng)408(RequestTime-out)狀態(tài)碼給客戶端。
  • client_body_timeout time:設(shè)置讀取客戶端內(nèi)容體超時時間,默認(rèn)為60s,此超時時間指的是兩次成功讀操作間隔時間,而不是發(fā)送整個請求體的超時時間,如果在此超時時間內(nèi)客戶端沒有發(fā)送任何請求體,則響應(yīng)408(RequestTime-out)狀態(tài)碼給客戶端。
  • send_timeout time:設(shè)置發(fā)送響應(yīng)到客戶端的超時時間,默認(rèn)為60s,此超時時間指的也是兩次成功寫操作間隔時間,而不是發(fā)送整個響應(yīng)的超時時間。如果在此超時時間內(nèi)客戶端沒有接收任何響應(yīng),則Nginx關(guān)閉此連接。
  • keepalive_timeout timeout [header_timeout]:設(shè)置HTTP長連接超時時間,其中,第一個參數(shù)timeout是告訴Nginx長連接超時時間是多少,默認(rèn)為75s。第二個參數(shù)header_timeout是用于設(shè)置響應(yīng)頭“Keep-Alive: timeout=time”,即告知客戶端長連接超時時間。兩個參數(shù)可以不一樣,“Keep-Alive:timeout=time”響應(yīng)頭可以在Mozilla和Konqueror系列瀏覽器起作用,而MSIE長連接默認(rèn)大約為60s,而不會使用“Keep-Alive: timeout=time”。如Httpclient框架會使用“Keep-Alive: timeout=time”響應(yīng)頭的超時(如果不設(shè)置默認(rèn),則認(rèn)為是永久)。如果timeout設(shè)置為0,則表示禁用長連接。

此參數(shù)要配合keepalive_disable 和keepalive_requests一起使用。keepalive_disable 表示禁用哪些瀏覽器的長連接,默認(rèn)值為msie6,即禁用一些老版本的MSIE的長連接支持。keepalive_requests參數(shù)作用是一個客戶端可以通過此長連接的請求次數(shù),默認(rèn)為100。

首先,瀏覽器在請求時會通過如下請求頭告知服務(wù)器是否支持長連接。

http/1.0默認(rèn)是關(guān)閉長連接的,需要添加HTTP請求頭“Connection:Keep-Alive”才能啟用。而http/1.1默認(rèn)啟用長連接,需要添加HTTP請求頭“Connection: close”才關(guān)閉。

接著,如果Nginx設(shè)置keepalive_timeout 5s,則瀏覽器會收到如下響應(yīng)頭。

下圖是wireshark抓包,可以看到后兩次請求沒有三次握手。

wireshark抓包

如果Nginx設(shè)置keepalive_timeout 10s 10s,則瀏覽器會收到如下響應(yīng)頭。

服務(wù)器端會在10s后發(fā)送FIN主動關(guān)閉連接。

如果Nginx設(shè)置keepalive_timeout為75s 30s。

如下是Chrome瀏覽器的Wireshark抓包,在45秒時,Chrome發(fā)送了TCPKeep-Alive來保活TCP連接,在第57秒時,瀏覽器又發(fā)出了一次請求。而132秒時,Nginx發(fā)出了FIN來關(guān)閉連接(75秒連接沒活躍了)。

Chrome瀏覽器的Wireshark抓包

如下是IE瀏覽器抓包數(shù)據(jù),在請求后第65秒左右時,瀏覽器重置了連接。

IE瀏覽器抓包數(shù)據(jù)

可以看出不同瀏覽器超時處理方式不一樣,而HTTP響應(yīng)頭“Keep-Alive: timeout=30”對Chrome和IE都沒有起作用。

接著,如果keepalive_timeout 0,則瀏覽器會收到如下響應(yīng)頭。

對于客戶端超時設(shè)置,要根據(jù)實際場景來決定,如果是短連接服務(wù),則可以考慮設(shè)置的短一些,如果是文件上傳,則需要考慮設(shè)置的時間長一些。另外,筆者見過很多人長連接并沒有配置正確,建議配置完成后通過抓包查看長連接是否起作用了。keepalive_timeout和keepalive_requests是控制長連接的兩個維度,只要其中一個到達(dá)設(shè)置的閾值連接就會被關(guān)閉。

(2) DNS解析超時設(shè)置

resolver_timeout 30s:設(shè)置DNS解析超時時間,默認(rèn)為30s。其配合resolver address ... [valid=time]進行DNS域名解析。當(dāng)在Nginx中使用域名時,就需要考慮設(shè)置這兩個參數(shù)。在社區(qū)版Nginx中采用如下配置。

  1. upstream backend { 
  2.     server c0.3.cn; 
  3.     server c1.3.cn; 

如上兩個域名會在Nginx解析配置文件的階段被解析成IP地址并記錄到upstream上,當(dāng)這兩個域名對應(yīng)的IP地址發(fā)生變化時,該upstream不會更新。Nginx商業(yè)版是支持動態(tài)更新的。

一種簡單辦法是使用如下方式,每次都會動態(tài)解析域名,這種情況在多域名情況下比較麻煩,實現(xiàn)就不優(yōu)雅了。

  1. location /test { 
  2.    proxy_pass http://c0.3.cn; 

如果使用Openresty,則可以通過Lua庫lua-resty-dns進行DNS解析。

  1. localresolver = require "resty.dns.resolver" 
  2.   local r, err = resolver:new{ 
  3.       nameservers = {"8.8.8.8",{"8.8.4.4", 53} }, 
  4.       retrans = 5,  -- 5 retransmissions on receive timeout 
  5.       timeout = 2000,  -- 2 sec 
  6.   } 

當(dāng)使用Nginx 1.5.8、1.7.4及遇到

  1. could not be resolved(110:Operation timed out); 

或者

  1. wrong ident 37278 response for ***.jd.local, expected 33517 
  2. unexpected response for ***.jd.local 

可能是遇到了如下BUG(http://nginx.org/en/CHANGES-1.6、http://nginx.org/ en/CHANGES-1.8)。

  1. Bugfix: requests might hang if resolver was usedand a timeout 
  2.       occurred during a DNS request. 

請考慮升級到Nginx 1.6.2、1.7.5或者在Nginx本機部署dnsmasq提升DNS解析性能。

(3) 代理超時設(shè)置

Nginx配置如下所示。

  1. upstream backend_server { 
  2.     server 192.168.61.1:9080 max_fails=2 fail_timeout=10s weight=1
  3.     server 192.168.61.1:9090 max_fails=2 fail_timeout=10s weight=1
  4. server { 
  5.     …… 
  6.     location /test { 
  7.        proxy_connect_timeout 5s; 
  8.        proxy_read_timeout 5s; 
  9.        proxy_send_timeout 5s; 
  10.   
  11.        proxy_next_upstream error timeout; 
  12.        proxy_next_upstream_timeout 0; 
  13.        proxy_next_upstream_tries 0; 
  14.   
  15.        proxy_pass http://backend_server; 
  16.        add_header upstream_addr $upstream_addr; 
  17.     } 

backend_server定義了兩個上游服務(wù)器192.168.61.1:9080(返回hello)和192.168.61.1:9090(返回hello2)。

如上指令主要有三組配置:網(wǎng)絡(luò)連接/讀/寫超時設(shè)置、失敗重試機制設(shè)置、upstream存活超時設(shè)置。

網(wǎng)絡(luò)連接/讀/寫超時設(shè)置。

  • proxy_connect_timeout time:與后端/上游服務(wù)器建立連接的超時時間,默認(rèn)為60s,此時間不超過75s。
  • proxy_read_timeout time:設(shè)置從后端/上游服務(wù)器讀取響應(yīng)的超時時間,默認(rèn)為60s,此超時時間指的是兩次成功讀操作間隔時間,而不是讀取整個響應(yīng)體的超時時間,如果在此超時時間內(nèi)上游服務(wù)器沒有發(fā)送任何響應(yīng),則Nginx關(guān)閉此連接。
  • proxy_send_timeout time:設(shè)置往后端/上游服務(wù)器發(fā)送請求的超時時間,默認(rèn)為60s,此超時時間指的是兩次成功寫操作間隔時間,而不是發(fā)送整個請求的超時時間,如果在此超時時間內(nèi)上游服務(wù)器沒有接收任何響應(yīng),則Nginx關(guān)閉此連接。

對于內(nèi)網(wǎng)高并發(fā)服務(wù),請根據(jù)需要調(diào)整這幾個參數(shù),比如內(nèi)網(wǎng)服務(wù)TP999為1s,可以將連接超時設(shè)置為100~500毫秒,而讀超時可以為1.5~3秒左右。

失敗重試機制設(shè)置。

  1. proxy_next_upstream error | timeout | invalid_header | http_500 | http_502 | http_503 | http_504 |http_403 | http_404 | non_idempotent | off ...: 

配置什么情況下需要請求下一臺上游服務(wù)器進行重試。默認(rèn)為“errortimeout”。error表示與上游服務(wù)器建立連接、寫請求或者讀響應(yīng)頭出錯。timeout表示與上游服務(wù)器建立連接、寫請求或者讀響應(yīng)頭超時。invalid_header表示上游服務(wù)器返回空的或錯誤的響應(yīng)頭。http_XXX表示上游服務(wù)器返回特定的狀態(tài)碼。non_idempotent表示RFC-2616定義的非冪等HTTP方法(POST、LOCK、PATCH),也可以在失敗后重試下一臺上游服務(wù)器(即默認(rèn)冪等方法GET、HEAD、PUT、DELETE、OPTIONS、TRACE才可以重試)。off表示禁用重試。

重試不能無限制進行,因此,需要如下兩個指令控制重試次數(shù)和重試超時時間。

  • proxy_next_upstream_tries number:設(shè)置重試次數(shù),默認(rèn)0表示不限制,注意此重試次數(shù)指的是所有請求次數(shù)(包括第一次和之后的重試次數(shù)之和)。
  • proxy_next_upstream_timeout time:設(shè)置重試最大超時時間,默認(rèn)0表示不限制。

即在proxy_next_upstream_timeout時間內(nèi)允許proxy_next_upstream_tries次重試。如果超過了其中一個設(shè)置,則Nginx也會結(jié)束重試并返回客戶端響應(yīng)(可能是錯誤碼)。

如下配置表示當(dāng)error/timeout時重試upstream中的下一臺上游服務(wù)器,如果重試的總時間超出了6s或者重試了1次,則表示重試失敗(因為之前已經(jīng)請求一次了,所以還能重試一次),Nginx結(jié)束重試并返回客戶端響應(yīng)。

  1. proxy_next_upstream error timeout; 
  2. proxy_next_upstream_timeout 6s; 
  3. proxy_next_upstream_tries 2; 

(4) upstream存活超時設(shè)置

max_fails和fail_timeout:配置什么時候Nginx將上游服務(wù)器認(rèn)定為不可用/不存活。當(dāng)上游服務(wù)器在fail_timeout時間內(nèi)失敗了max_fails次,則認(rèn)為該上游服務(wù)器不可用/不存活。并在接下來的fail_timeout時間內(nèi)從upstream摘掉該節(jié)點(即請求不會轉(zhuǎn)發(fā)到該上游服務(wù)器)。

什么情況下被認(rèn)定為失敗呢?其由 proxy_next_upstream定義,不過,不管 proxy_next_upstream如何配置,error, timeout and invalid_header 都將被認(rèn)為是失敗。

如server 192.168.61.1:9090max_fails=2 fail_timeout=10s;表示在10s內(nèi)如果失敗了2次,則在接下來的10s內(nèi)認(rèn)定該節(jié)點不可用/不存活。這種存活檢測機制是只有當(dāng)訪問該上游服務(wù)器時,采取惰性檢查,可以使用ngx_http_upstream_check_module配置主動檢查。

max_fails設(shè)置為0表示不檢查服務(wù)器是否可用(即認(rèn)為一直可用),如果upstream中僅剩一臺上游服務(wù)器時,則該服務(wù)器是不會被摘除的,將從不被認(rèn)為不可用。

(5) ngx_lua超時設(shè)置

當(dāng)我們使用ngx_lua時,也請考慮設(shè)置如下網(wǎng)絡(luò)連接/讀/寫超時。

  1. lua_socket_connect_timeout  100ms; 
  2. lua_socket_send_timeout    200ms; 
  3. lua_socket_read_timeout    500ms; 

在使用lua時,我們會按照如下策略進行重試。

  1. if (status == 502 or status == 503 or status ==504) and request_time < 200 then 
  2.     resp =capture(proxy_uri) 
  3.     status =resp.status 
  4.     body =resp.body 
  5.    request_timerequest_time = request_time + tonumber(var.request_time) * 1000 
  6. end 

即如果狀態(tài)碼是500/502/503/504時,并且該次請求耗時在200毫秒以內(nèi),則我們進行一次重試。

2. Twemproxy

Twemproxy是Twitter開源的Redis和Memcache代理中間件,其目的是減少與后端緩存服務(wù)器的連接數(shù)。

  • timeout:表示與后端服務(wù)器建立連接、接收響應(yīng)的超時時間,默認(rèn)永不超時。
  • server_retry_timeout和server_failure_limit:當(dāng)開啟auto_eject_hosts,即當(dāng)后端服務(wù)器不可用時自動摘除這些節(jié)點并在一定時間后進行重試。server_failure_limit設(shè)置連續(xù)失敗多少次后將節(jié)點臨時摘除,server_retry_timeout設(shè)置摘除節(jié)點后等待多久進行重試,從而保證不永久性的將節(jié)點摘除。

二、Web容器超時

筆者生產(chǎn)環(huán)境用的Java Web容器是Tomcat,本部分將以Tomcat8.5作為例子進行講解。

  • connectionTimeout:配置與客戶端建立連接超時時間,從接收到連接后在配置的時間內(nèi)還沒有接收到客戶端請求行時,將被認(rèn)定為連接超時,默認(rèn)為60000(60s)。
  • socket.soTimeout:從客戶端讀取請求數(shù)據(jù)的超時時間,默認(rèn)同connectionTimeout,NIO and NIO2 支持該配置。
  • asyncTimeout:Servlet 3異步請求的超時時間,默認(rèn)為30000(30s)。
  • disableUploadTimeout 和connectionUploadTimeout:當(dāng)配置disableUploadTimeout為false時(默認(rèn)為true,和connectionTimeout一樣),文件上傳將使用connectionUploadTimeout作為超時時間。
  • keepAliveTimeout和maxKeepAliveRequests:和Nginx配置類似。keepAliveTimeout默認(rèn)為connectionTimeout,配置-1表示永不超時。maxKeepAliveRequests默認(rèn)為100。

三、中間件客戶端超時與重試

JSF是京東自研的SOA框架,主要有三個組件:注冊中心、服務(wù)提供端、服務(wù)消費端。

  • 首先是服務(wù)提供端/消費端與注冊中心之間的進行服務(wù)注冊/發(fā)現(xiàn)時可以配置timeout(調(diào)用注冊中心超時時間,默認(rèn)為5s)和connectTimeout(連接注冊中心的超時時間,默認(rèn)為20s)。
  • 服務(wù)提供端可以配置timeout(服務(wù)端調(diào)用超時,默認(rèn)為5s)。
  • 服務(wù)消費端可以配置timeout(調(diào)用端調(diào)用超時時間,默認(rèn)為5s),connectTimeout(建立連接超時時間,默認(rèn)為5s),disconnectTimeout(斷開連接/等待結(jié)果超時時間,默認(rèn)為10s),reconnect(調(diào)用端重連死亡服務(wù)端的間隔,配置小于0表示不重連,默認(rèn)為10s),heartbeat(調(diào)用端往服務(wù)端發(fā)心跳包間隔,配置小于0代表不發(fā)送,默認(rèn)為30s),retries(失敗后重試次數(shù),默認(rèn)0不重試)。

Dubbo也有類似的配置,在此就不闡述了。

JMQ是京東消息中間件,主要有四個組件:注冊中心、Broker(JMQ的服務(wù)端實例,生產(chǎn)和消費消息都跟它交互)、生產(chǎn)者、消費者。

  • 首先是生產(chǎn)者/消費者與Broker進行發(fā)送/接收消息時可以配置connectionTimeout(連接超時)、sendTimeout(發(fā)送超時)、soTimeout(讀超時)。
  • 生產(chǎn)者可以配置retryTimes(發(fā)送失敗后的重試次數(shù),默認(rèn)為2次)。
  • 消費者可以配置pullTimeout(長輪詢超時時間,即拉取消息超時時間)、maxRetrys(最大重試次數(shù),對于消費者要允許無限制重試,即一直拉取消息)、retryDelay(重試延遲,通過exponential配置延遲增加倍數(shù)一直增加到maxRetryDelay)、maxRetryDelay(最大重試延遲)。消費者還需要配置應(yīng)答超時時間(服務(wù)端需要等待客戶端返回應(yīng)答才能移除消息,如果沒有應(yīng)答返回,則會等待應(yīng)答超時,在這段時間內(nèi)鎖定的消息不能被消費,必須等待超時后才能被消費)。

對于消息中間件我們實際應(yīng)用中關(guān)注超時配置會少一些,因為生產(chǎn)者默認(rèn)配置了重試次數(shù),可能會存在重復(fù)消息,消費者需要進行去重處理。

CXF可以通過如下方式配置CXF客戶端連接超時、等待響應(yīng)超時和長連接。

  1. HTTPClientPolicy httpClientPolicy = new HTTPClientPolicy(); 
  2. httpClientPolicy.setConnectionTimeout(30000);//默認(rèn)為30s 
  3. httpClientPolicy.setReceiveTimeout(60000); //默認(rèn)為60s 
  4. httpClientPolicy.setConnection(ConnectionType.KEEP_ALIVE);//默認(rèn)為Keep- Alive 
  5. ((HTTPConduit)client.getConduit()).setClient(httpClientPolicy); 

Httpclient 4.2.x可以通過如下代碼配置網(wǎng)絡(luò)連接、等待數(shù)據(jù)超時時間。

  1. HttpParams params = new BasicHttpParams(); 
  2. //設(shè)置連接超時時間 
  3. Integer CONNECTION_TIMEOUT = 2 * 1000;    //設(shè)置請求超時2秒鐘 
  4. Integer SO_TIMEOUT = 2 * 1000;        //設(shè)置等待數(shù)據(jù)超時時間2秒鐘 
  5. Long CONN_MANAGER_TIMEOUT = 1L * 1000;        //定義了當(dāng)從ClientConnectionManager中檢索ManagedClientConnection實例時使用的毫秒級的超時時間 
  6. params.setIntParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,CONNECTION_TIMEOUT); 
  7. params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT,SO_TIMEOUT); 
  8. //在提交請求之前,測試連接是否可用 
  9. params.setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK,true); 
  10. //這個參數(shù)期望得到一個java.lang.Long類型的值。如果這個參數(shù)沒有被設(shè)置,則連接請求就不會超時(無限大的超時時間) 
  11. params.setLongParameter(ClientPNames.CONN_MANAGER_TIMEOUT,CONN_MANAGER_TIMEOUT); 
  12. PoolingClientConnectionManager conMgr = new PoolingClientConnectionManager(); 
  13. conMgr.setMaxTotal(200);//設(shè)置最大連接數(shù) 
  14. //是路由的默認(rèn)最大連接(該值默認(rèn)為2),限制數(shù)量實際使用DefaultMaxPerRoute并非MaxTotal 
  15. //設(shè)置過小,無法支持大并發(fā)(ConnectionPoolTimeoutException: Timeout waiting for connection frompool),路由是對maxTotal的細(xì)分 
  16. conMgr.setDefaultMaxPerRoute(conMgr.getMaxTotal());//(目前只有一個路由,因此讓他等于最大值) 
  17.   
  18. //設(shè)置訪問協(xié)議 
  19. conMgr.getSchemeRegistry().register(new Scheme("http",80, PlainSocketFactory. getSocketFactory())); 
  20. conMgr.getSchemeRegistry().register(new Scheme("https",443, SSLSocketFactory. getSocketFactory())); 
  21. httpClient = newDefaultHttpClient(conMgr, params); 
  22. httpClient.setHttpRequestRetryHandler(newDefaultHttpRequestRetryHandler(0, false)); 

因為我們使用http connection連接池,所以需要配置CONN_MANAGER_TIMEOUT,表示從連接池獲取http connection的超時時間。

此處還通過httpClient.setHttpRequestRetryHandler(newDefaultHttpRequestRetry Handler(0, false))配置了請求重試策略(默認(rèn)重試3次)。當(dāng)執(zhí)行請求時遇到異常時會調(diào)用retryRequest來判斷是否進行重試,而retryRequest在以下情況不會進行重試:達(dá)到重試次數(shù)、服務(wù)器不可達(dá)、連接被拒絕、連接終止、請求已發(fā)送。而冪等HTTP方法的請求、requestSentRetryEnabled=true且請求還未成功發(fā)送時可以重試。

如果響應(yīng)是503錯誤狀態(tài)碼時,如上重試機制是不可用的,則可以考慮使用AutoRetryHttpClient客戶端,其可以配置ServiceUnavailableRetryStrategy,默認(rèn)實現(xiàn)為DefaultServiceUnavailableRetryStrategy,可以配置重試次數(shù)maxRetries和重試間隔retryInterval。每次重試之前都會等待retryInterval毫秒時間。

假設(shè)我們服務(wù)有多個機房提供,其中一個機房服務(wù)出現(xiàn)問題時應(yīng)該自動切到另一個機房,可以考慮使用如下方法。

  1. public static String get(List<String> apis, Object[] args, String encoding,Header[] headers, Integer timeout) throws Exception { 
  2.     Stringresponse = null
  3.     for(String api : apis) { 
  4.         String uri =UriComponentsBuilder.fromHttpUrl(api).buildAndExpand(args). toUriString(); 
  5.        response = HttpClientUtils.getDataFromUri(uri, encoding, headers,timeout); 
  6.         //如果失敗了,重試一次 
  7.         if(Objects.equal(response, HTTP_ERROR)){ 
  8.             continue; 
  9.         } 
  10.         //如果域名解析失敗重試 
  11.         if(Objects.equal(response,HTTP_UNKNOWN_HOST_ERROR)) { 
  12.            response = HTTP_ERROR; //掉用方根據(jù)這個判斷是否有問題 
  13.             continue; 
  14.         } 
  15.         if(Objects.equal(response,HTTP_SOCKET_TIMEOUT_ERROR)) { 
  16.            response = HTTP_ERROR; //調(diào)用方根據(jù)這個判斷是否有問題 
  17.             continue; 
  18.         } 
  19.         return response; 
  20.     } 
  21.     return response; 

參數(shù)傳入不同機房的API即可,當(dāng)其中一個不可用自動重試另一個機房的API。

【本文是51CTO專欄作者“張開濤”的原創(chuàng)文章,作者微信公眾號:開濤的博客( kaitao-1234567)】

戳這里,看該作者更多好文

責(zé)任編輯:趙寧寧 來源: 51CTO專欄
相關(guān)推薦

2017-07-02 16:50:21

2017-06-04 16:24:27

線程線程池中斷

2017-05-18 16:07:23

回滾數(shù)據(jù)庫代碼

2024-09-25 08:32:05

2022-11-14 08:19:59

重試機制Kafka

2025-09-10 07:15:45

2022-05-06 07:44:10

微服務(wù)系統(tǒng)設(shè)計重試機制

2017-05-10 11:40:29

緩存Nginx HTTP

2017-05-01 17:03:01

Java緩存分布式

2021-02-20 10:02:22

Spring重試機制Java

2020-07-19 15:39:37

Python開發(fā)工具

2025-02-26 10:49:14

2017-04-18 14:49:38

應(yīng)用層API代碼

2025-01-03 08:44:37

kafka消息發(fā)送策略

2023-10-27 08:20:12

springboot微服務(wù)

2023-11-27 07:44:59

RabbitMQ機制

2017-04-21 08:51:42

API緩存分布式

2023-11-06 08:00:38

接口高可用機制

2025-05-28 01:15:00

Golang重試機制

2017-05-05 10:13:03

應(yīng)用級緩存緩存代碼
點贊
收藏

51CTO技術(shù)棧公眾號

黑人巨大精品欧美一区二区| 国产精品自拍网站| 最近2019中文字幕一页二页 | wwwav国产| 欧美亚视频在线中文字幕免费| 91黄视频在线| 国产精品免费看久久久无码| 日韩av视屏| 国产一区二区三区不卡在线观看| 4388成人网| 91香蕉一区二区三区在线观看| 国产精品男女| 欧美久久一区二区| 国内外成人激情视频| 麻豆影视在线观看_| 97久久精品人人爽人人爽蜜臀| 国产精品一区=区| 国产精品黄色网| 99久久www免费| 亚洲欧美成人网| 少妇精品无码一区二区| 国产精品黄色片| 一本大道久久a久久综合婷婷| 国产日韩第一页| 国模吧精品人体gogo| 成人一级黄色片| 国产在线精品播放| 久久久久久亚洲av无码专区| 亚洲国产裸拍裸体视频在线观看乱了中文| 色妞一区二区三区| 国产精品亚洲无码| 老牛精品亚洲成av人片| 日韩欧美美女一区二区三区| 午夜免费看毛片| 外国电影一区二区| 欧美性色19p| 久久久久久久久久网| 欧美wwww| 一区二区三区在线观看网站| 国产精品av免费| 在线激情网站| 日本一区二区三区久久久久久久久不| 久久久神马电影| 色丁香婷婷综合久久| 国产精品一区二区久久不卡 | 国产精品久久久久久免费| 国产一区导航| 2019亚洲男人天堂| 欧美激情黑白配| 国产日韩欧美三区| 77777亚洲午夜久久多人| 精品处破女学生| 亚洲国产精品第一区二区| 欧美激情欧美激情在线五月| 青青草激情视频| 午夜日韩激情| 国内伊人久久久久久网站视频| 国产一级二级毛片| 黄色亚洲精品| 57pao成人永久免费视频| 久久黄色精品视频| 丝袜亚洲另类欧美| 国产成人综合精品在线| 最新黄色网址在线观看| 奇米色777欧美一区二区| 国产精品一久久香蕉国产线看观看| 中文字幕观看视频| 韩国v欧美v亚洲v日本v| 亚洲综合中文字幕68页| 亚洲av综合色区无码一二三区| 国产精品影音先锋| 国产精品免费一区二区三区观看| 四虎影视精品成人| 久久久久久99久久久精品网站| 日韩少妇中文字幕| 精品国产丝袜高跟鞋| 亚洲精品中文在线观看| 免费高清一区二区三区| 狠狠操一区二区三区| 色婷婷一区二区| 小明看看成人免费视频| 7777精品| 亚洲日本中文字幕| 黄色录像免费观看| 极品日韩av| 国产精品久久久久久亚洲调教| 一级aaaa毛片| 暴力调教一区二区三区| 日本不卡高清视频一区| av文字幕在线观看| 精品国产1区2区| 91高清国产视频| 麻豆精品少妇| 日韩中文字幕精品| 亚洲欧美在线视频免费| 美日韩一级片在线观看| 国产精品一区二区欧美黑人喷潮水 | 日韩欧美国产精品一区| 美女久久久久久久久久| 永久91嫩草亚洲精品人人| 7777免费精品视频| 国产免费一区二区三区最新不卡| 91在线观看下载| 欧美精品久久96人妻无码| 自拍在线观看| 日韩女同互慰一区二区| japanese中文字幕| 国产精品av久久久久久麻豆网| 日韩美女主播视频| 性生活黄色大片| 中文字幕av一区二区三区高| 黄色一级片在线看| 亚洲影视资源| 亚洲视频在线看| 国产精品自拍视频一区| 久久99蜜桃精品| 日本不卡二区| 亚洲黄色免费av| 91精品国产色综合久久不卡电影| 亚洲综合网在线观看| 国产综合自拍| 91亚洲精品在线| h网站视频在线观看| 精品毛片网大全| 亚洲免费观看在线| 亚洲va在线| 国产精品中文字幕在线| 国产在线视频福利| 色狠狠桃花综合| www.超碰97| 一区免费在线| 成人黄色片视频网站| 国产美女福利在线| 欧美日韩一区二区三区四区五区| 亚洲制服丝袜在线播放| 亚洲黄色精品| 成人91视频| 四虎影视国产在线视频| 欧美一区二区美女| av在线播放中文字幕| 日韩国产在线观看一区| 欧美精品一区二区三区在线四季| av中文在线资源| 精品动漫一区二区三区在线观看 | 亚洲一区二区三区四区五区中文| 激情文学亚洲色图| 日韩毛片视频| 国产中文字幕91| 国产淫片在线观看| 91精品国产综合久久久久久漫画| 羞羞在线观看视频| 经典三级在线一区| 在线一区高清| 韩国三级大全久久网站| 久久亚洲国产精品成人av秋霞| 在线免费av网| 亚洲男同性视频| 精品人妻一区二区三区免费| 欧美二区视频| 国产免费一区| 丝袜诱惑一区二区| 国产亚洲一区二区在线| 一二区在线观看| 一个色妞综合视频在线观看| 成人做爰69片免费| 一区二区国产精品| 欧美一区免费视频| 欧美在线一级| 九色精品免费永久在线| 手机看片一区二区| 福利微拍一区二区| 人妻大战黑人白浆狂泄| 七七婷婷婷婷精品国产| 超碰97在线看| 欧美男人操女人视频| 青青草成人在线| 91在线高清| 欧美一区二区三区在线观看 | 在线成人av网站| 久久综合激情网| 久久久久久久久伊人| the porn av| 国内久久精品| 欧美一区激情视频在线观看| 国产精品日韩精品在线播放| 97免费视频在线| 91caoporm在线视频| 精品奇米国产一区二区三区| 亚洲毛片一区二区三区| 亚洲少妇屁股交4| 无码h肉动漫在线观看| 狠狠色丁香九九婷婷综合五月| av免费看网址| 国产精品毛片久久| 久久久福利视频| 精品中文在线| 欧美中文字幕在线播放| 久操免费在线| 国产一区二区三区免费视频| 高h震动喷水双性1v1| 欧美亚洲一区二区三区四区| 国产在线视频99| 国产精品国产三级国产aⅴ中文| 美国黄色一级视频| 精品一区二区久久| 日本精品www| 亚洲黄色大片| 91国在线高清视频| 日韩精品一区二区三区免费观影 | 视频在线在亚洲| 国产精品日韩三级| 三上亚洲一区二区| 蜜桃麻豆91| 成人免费在线电影网| 国产情人节一区| 是的av在线| 九九热最新视频//这里只有精品 | 国内精品视频在线观看| 国产精品视频入口| 国产乱码精品一区二区三区亚洲人 | 国产乱子轮精品视频| 成年网站在线播放| 性一交一乱一区二区洋洋av| 成人免费播放器| 你懂的视频一区二区| 一区二区在线高清视频| 欧美三级美国一级| 欧美日韩国产三区| 欧美一区 二区| 国产精品久久久久久免费观看| 精品91福利视频| 成人a视频在线观看| 精品国产黄a∨片高清在线| 国产精品久久久久久久久影视 | 色94色欧美sute亚洲线路二 | 国产3级在线观看| 欧美激情一区三区| 国产视频三区四区| 日本一区二区三区国色天香| 精品无码国产污污污免费网站| 26uuu精品一区二区在线观看| 熟女人妻在线视频| 91亚洲永久精品| 不卡一区二区在线观看| 久久无码av三级| 韩国三级hd中文字幕| 欧美高清在线一区| аⅴ天堂中文在线网| 国产精品久久免费看| 国产精品suv一区二区88| 国产精品久久久久久久久免费樱桃| 欧美一区二区三区粗大| 国产精品青草久久| 午夜国产福利视频| 综合自拍亚洲综合图不卡区| 亚洲一级生活片| 一区av在线播放| 日韩精品一区二区不卡| 欧美日韩人人澡狠狠躁视频| 国产精品久久久久久久久久久久久久久久久 | 日本精品在线中文字幕| 国产精品久久久久久中文字| 日本一区二区三区中文字幕| 亚洲在线观看视频网站| 大奶一区二区三区| 久久资源av| 成人在线丰满少妇av| 三年中文高清在线观看第6集| 欧美韩日精品| 日本中文字幕片| 麻豆精品新av中文字幕| 香蕉视频xxxx| 99久久精品99国产精品| 亚洲AV无码成人精品区明星换面| 亚洲欧洲三级电影| 麻豆国产尤物av尤物在线观看| 狠狠色香婷婷久久亚洲精品| 中文字幕日产av| 精品国产一区二区精华| 国产中文字幕在线| 色综合久综合久久综合久鬼88 | 欧美日韩影院| 日韩精品一区中文字幕| 国产在线麻豆精品观看| www.免费av| 亚洲免费观看在线视频| 国产精品国产三级国产专区52| 欧美日韩一区国产| 日本激情一区二区| 色午夜这里只有精品| 爱看av在线| 国产日韩欧美自拍| 久久人人爽人人爽人人片av不| 日韩国产在线一区| 狠狠综合久久| 毛片毛片毛片毛| 26uuu国产一区二区三区| 国产探花在线播放| 欧美自拍丝袜亚洲| 日韩在线视频观看免费| 中文字幕一区日韩电影| 在线观看涩涩| 国产99午夜精品一区二区三区| 久久一本综合| 黄在线观看网站| 粉嫩av一区二区三区| 日本黄区免费视频观看| 精品久久久久久久久久久久久| 国产欧美日韩成人| 在线观看国产成人av片| 三级在线看中文字幕完整版| 114国产精品久久免费观看| 奇米影视亚洲| 成年人小视频网站| 成人性生交大合| 少妇aaaaa| 欧美精品在线一区二区| 黄色在线播放| 欧洲亚洲在线视频| 久久久免费毛片| 久久国产午夜精品理论片最新版本| 精品亚洲porn| 综合 欧美 亚洲日本| 91高清视频在线| 日韩一区二区三区中文字幕| 久久人人爽人人爽人人片av高请 | 激情av综合网| 国产探花视频在线| 在线欧美一区二区| 美女毛片在线看| 欧美壮男野外gaytube| 久久男人av| av高清在线免费观看| 成人性色生活片| 国产真实夫妇交换视频| 欧美sm美女调教| 日本三级在线观看网站| 99精彩视频| 亚洲无线一线二线三线区别av| 免费高清视频在线观看| 伊人婷婷欧美激情| 精品人妻av一区二区三区| 久久在线免费观看视频| 欧美日本三级| 欧美国产综合在线| 波多野结衣视频一区| 九九热国产视频| 日韩av中文在线| 亚洲欧美电影| 日韩欧美国产二区| 捆绑调教一区二区三区| 国产三级aaa| 日韩三级视频在线看| 色呦呦视频在线观看| 精品国产乱码一区二区三区四区| 在线视频免费在线观看一区二区| 亚洲精品女人久久久| 欧洲日韩一区二区三区| 美女羞羞视频在线观看| 2019国产精品视频| 99国产精品久久久久久久成人热| 日本黄色录像片| 色婷婷精品大视频在线蜜桃视频| 国产对白叫床清晰在线播放| 国产男女猛烈无遮挡91| 一级毛片免费高清中文字幕久久网| 伊人影院在线观看视频| 婷婷久久综合九色综合绿巨人| 欧美巨乳在线| 91久热免费在线视频| 樱桃成人精品视频在线播放| 国产成人无码一区二区在线观看| 欧美吻胸吃奶大尺度电影| 永久免费网站在线| 韩国一区二区三区美女美女秀| 丝袜亚洲另类欧美| 国产一区二区播放| 亚洲精品xxxx| 欧洲午夜精品| 欧洲精品一区二区三区久久| 国产三级一区二区| 亚洲精品成人电影| 热re91久久精品国99热蜜臀| 国产大片一区| 99久久人妻精品免费二区| 欧美日韩小视频| 9lporm自拍视频区在线| 亚洲精品在线视频观看| 成人精品一区二区三区四区| 天天干天天操天天操| 欧美成人全部免费| 国产一区不卡| 野战少妇38p| 欧美日韩久久一区二区| 国产ktv在线视频| 成年人黄色在线观看| 久久久三级国产网站| av手机免费看| 国产欧美精品xxxx另类| 国产九九精品|