成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

使用HTTP Client踩到的一個坑,你一定要避免

網絡 網絡管理
在實踐的過程中,我們經常會遇到一些莫名其妙的問題,而這些問題導致的原因可能是實踐經驗不足,也可能是對API的使用不夠熟練。

前言

作為軟件開發者,我們知道一切看似正常的系統,不知埋藏著多少坑。今天跟大家分享一個實戰過程中遇到的HTTP Client使用不當導致的坑。

筆者通過問題的表象一路追蹤下去,最終找到導致問題的根源:HTTP Client。結論很簡單,先賣個關子,但分析的過程值得你借鑒。

問題現象

場景:幾乎每個系統都有異步調用三方服務的功能,所負責的系統基于阻塞隊列實現了一個消息隊列,來調用三方服務。為了確保冪等性,隊列是順序消費。這就導致一個問題,一旦其中一個消息被阻塞,后面的消息就無法消費。當隊列滿時,也無法向隊列中添加消息。

看似:極其偶發的場景下,消息隊列被阻塞十多分鐘。這是什么鬼?

下面就開始了問題的逐步排查。

問題排查

首先想到的是,是不是消息隊列實現的底層機制有問題。比如消息隊列是通過while(true)輪訓+sleep睡眠來實現生產者和消費者的持續存取數據。

既然消息被阻塞,是否是因為sleep(睡)過頭了?后來一想,即使CPU進行了分片處理,也不至于睡眠那么就不會被喚醒。同時也不太可能是線程被interrupted掉。因為,如被interrupted掉了,整個隊列就掛了,不會延遲后恢復正常。

在此處困惑了很久,看了消息隊列實現的源碼很久,沒有突破。于是,與朋友探討了一下,一句話提醒了我:可能不是睡眠的問題,而是生產者或消費者的問題。

于是仔細扒日志,發現還真是的:生產者向隊列中丟了一次數據,持續很長時間沒有再丟數據;消費者在生產者向隊列丟數據之后幾分鐘還有消費的日志。很明顯,生產者是被消費者阻塞了。

初步結論:消費者消費時間過長,導致隊列滿了,生產者向隊列添加數據時被阻塞。

經驗性猜測:消費者中有HTTP請求,HTTP請求可能長時間持有連接未釋放。

問題根源

當分析定位到是HTTP請求的原因,就很好解決了。首先分析了日志,發現的確有一個HTTP請求,請求前打印了請求參數,但始終沒看到返回結果的打印。扒日志終于看到,返回結果的日志是在15分鐘之后打印出來的,日志內容為對方服務異常。

再看看代碼,發現HTTP請求是基于HTTP Client實現的,而當初寫這段代碼的人并沒有設置超時時間。為了保持業務脫敏,找了一段類似的代碼:

public static String doPostWithJSON(String url, String json) throws Exception {
CloseableHttpClient client = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
httpPost.setHeader("Content-Type","application/json;charset=UTF-8");
StringEntity se = new StringEntity(json, Charset.forName("UTF-8"));
se.setContentType("application/json");
httpPost.setEntity(se);
CloseableHttpResponse response = client.execute(httpPost);
HttpEntity entity = response.getEntity();
String result = EntityUtils.toString(entity, "UTF-8");
return result;
}

像上述代碼一樣,設置了請求參數,但未指定HttpPost的超時時間。看似正常的代碼,隱藏著一個巨大的坑,導致的結果就是HTTP請求一直等待。

筆者所遇到的情況還好,對方設置的超時時間為15分鐘,還給返回了結果。如果對方未設置超時時間,可能就一直等待了,當業務量比較大時,會導致災難的發生!

HTTP Client的超時設置

找問題往往是最難,當找到問題時,解決起來就容易多了。HTTP Client的不同版本有不同的設置超時時間的方式,這也算是HTTP Client的又一大弊端吧,API版本變動太大。

4.3版本的配置:

httpClient.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT,10000);
httpClient.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT,10000);

4.3以后版本的配置:

RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(10000).setConnectTimeout(10000).build();
httpGet.setConfig(requestConfig);

其中,setConnectTimeout為連接超時時間,單位為毫秒。

setSocketTimeout為請求獲取數據的超時時間,單位毫秒。如果訪問一個接口,指定時間內無法返回數據,就直接放棄此次調用。

其他版本的使用,建議參考一下相關的API說明了。

小結

在實踐的過程中,我們經常會遇到一些莫名其妙的問題,而這些問題導致的原因可能是實踐經驗不足,也可能是對API的使用不夠熟練。而經驗來自哪里?來自像本文這樣一個個問題的排查、總結、積累而獲得。

比如,讀完本篇文章,你已經知道了:當使用HTTP Client時一定要設置超時時間。同時,你肯定也能舉一反三,凡是在HTTP調用時都需要考慮一下超時時間及對應的異常處理。

責任編輯:武曉燕 來源: 程序新視界
相關推薦

2017-10-16 12:52:51

2024-03-21 15:01:44

2017-06-08 09:19:35

2020-10-28 15:07:01

Arthas

2018-10-25 15:04:22

編程程序員陷阱

2018-08-23 16:25:29

HadoopHDFS存儲

2022-06-13 09:26:41

Promise前端代碼

2019-12-24 14:00:36

運維Linux測試

2024-11-20 10:30:00

AI架構

2018-09-07 23:27:53

AI開源學習框架

2020-12-03 10:17:25

Kubernetes架構微服務

2018-08-29 11:04:05

2022-03-22 18:12:26

網絡攻擊數據安全安全威脅

2024-09-09 00:00:00

2016-11-24 15:54:06

androidJSONObject

2021-03-15 12:00:19

Kubernetes微服務架構

2024-04-23 10:23:34

WPFMVVMPrism

2020-04-14 08:46:47

Java對象編譯器

2022-09-30 14:00:50

JavaScrip新特性代碼

2019-08-21 19:49:21

機器學習人工智能
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 韩日一区| 国产一区二区在线观看视频 | 天天插天天舔 | 久久久精品一区 | 欧美视频在线播放 | 亚洲精品一二三区 | 色综合色综合色综合 | 日韩在线中文字幕 | 一级黄色片网址 | 久久久蜜臀国产一区二区 | 成年人在线视频 | 国产精品久久久久久久久免费桃花 | 91在线精品视频 | 成人妇女免费播放久久久 | 久久99精品久久久久久秒播九色 | 伊人伊人伊人 | 天天操天天射天天舔 | 欧美久久久久久久久中文字幕 | 国产男人的天堂 | 久久一起草 | 国产精品揄拍一区二区 | 九九99九九精彩46 | 国产精品免费一区二区三区四区 | 91精品国产综合久久精品 | 亚洲精品成人在线 | 久久中文网 | 亚洲午夜久久久 | 久久国内精品 | 欧美在线视频一区二区 | 成人午夜免费在线视频 | 亚洲精品日韩综合观看成人91 | 日韩免费视频一区二区 | 亚洲成人综合在线 | 日韩午夜 | 日本三级播放 | 国产999精品久久久久久 | 欧美日韩国产一区二区三区 | 欧美成人免费在线视频 | 欧美日韩视频一区二区 | 欧美综合久久 | 欧美日韩视频在线 |