最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

生產(chǎn)環(huán)境NoHttpResponseException異常排查解決記錄分析

 更新時間:2023年10月12日 08:58:53   作者:敲得碼黛  
這篇文章主要為大家介紹了生產(chǎn)環(huán)境NoHttpResponseException異常排查解決記錄分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪

業(yè)務背景

公司最近正在準備為郵儲銀行開展一個營銷活動,活動規(guī)則是:用戶使用郵儲銀行卡在線上支付一分錢,就可以領取50元現(xiàn)金券,卡券領取完畢后,系統(tǒng)會自動退還消費者的1分錢。(相當于免費給郵儲用戶發(fā)放50元現(xiàn)金券),因為發(fā)券的入口要做在小程序里面,于是這個需求就落到了C端這邊(公司的另一個業(yè)務小組),而我主要負責B端支付模塊。經(jīng)過我們商討后,初步制定的業(yè)務邏輯為:用戶打開C端小程序進行支付、然后C端將支付請求轉給B端支付模塊、B端支付模塊向微信下單、等待消費者完成支付后B端支付模塊通知C端交易完成并返回其支付方式、C端判斷支付方式是否為郵儲銀行卡(是郵儲銀行卡則發(fā)券)、然后C端調用B端支付模塊進行退款。為了方便大家理解,我嘔心瀝血的畫出了系統(tǒng)調用的時序圖。

生產(chǎn)環(huán)境發(fā)現(xiàn)的問題

1、NoHttpResponseException導致退款失敗

功能上線后,我便開始監(jiān)控B端支付模塊的交易數(shù)據(jù),前兩天的數(shù)據(jù)并沒有什么異常,支付完成的訂單都已經(jīng)退款完成。然后在第三天快下班時,我又統(tǒng)計了一遍數(shù)據(jù),發(fā)現(xiàn)竟然存在一筆沒退款的訂單,我整個人一下子就支棱了起來(不會又寫了個Bug吧~),我先在數(shù)據(jù)庫中查到訂單號,然后找運維同事拿了一下日志,發(fā)現(xiàn)支付回調是正常的,并且下游系統(tǒng)也響應了success,但是卻沒有調用退款接口進行退款。排查到這里基本已經(jīng)可以確定不是支付模塊這邊的問題了,但問題畢竟還是要解決的,于是我聯(lián)系了C端的同事,暫時先通過接口的方式把消費者的錢進行退款。然后開始排查C端系統(tǒng)的問題,通過C端的日志發(fā)現(xiàn),在請求支付模塊進行退款時存在一個異常信息,報錯信息如下

看到這個報錯,我不禁陷入了思考:C端這個日志表明確實是發(fā)起了退款請求,但是B端支付模塊根本沒收到這個退款請求,這樣一來就比較尷尬了,雙方系統(tǒng)竟然都沒問題,那只能是網(wǎng)絡問題了(找不到人背鍋,只能推給網(wǎng)絡了~~哈哈),剛開始只有一筆,我沒怎么在意,過了幾天后,陸陸續(xù)續(xù)發(fā)現(xiàn)了好幾筆類似的情況,平均幾千筆訂單就會出現(xiàn)一筆退款失敗的,并且這些訂單之間毫無規(guī)律,搞得我這幾天是干啥啥不香,于是痛下決心要深入研究一下這個問題。

2、 異常情況分析

目前能夠提供幫助的信息并不多,只有這一個報錯日志,通過在網(wǎng)上收集到的一些相關資料,發(fā)現(xiàn)了幾篇比較有借鑒價值的文章,他們的觀點也都幾乎一致:服務端主動斷開TCP鏈接,然后客戶端使用半斷開的鏈接發(fā)起請求時,服務端響應RST包導致此異常情況的發(fā)生。 大多數(shù)文章的建議是:捕獲NoHttpResponseException異常進行重試。

3、驗證思路

既然有了上述猜想,那么下一步肯定是要做驗證的,驗證一下在這個場景下確實會出現(xiàn)此現(xiàn)象。剛開始的驗證思路比較簡單,就是在服務端通過工具模擬FIN包,然后再用HttpClient繼續(xù)請求,觀察其結果,然而抓包結果顯示Httpclient會創(chuàng)建一個新的tcp鏈接進行請求,木得辦法,解鈴還須系鈴人,恐怕要看一下HttpClient源碼才能解釋這個現(xiàn)象了。

通過閱讀HttpClient源碼,大致找到了兩個比較關鍵的邏輯點

  • HttpClient建立tcp鏈接的時機(三次握手的時機)
  • 發(fā)送http請求的時機
tip:在三次握手之前會檢查當前tcp鏈接是否處于Open狀態(tài),若處于Open狀態(tài)則復用此鏈接,若不處于Open狀態(tài)則打開一個新的tcp鏈接,這樣一來就解釋的通為什么之前HttpClient又重新創(chuàng)建了一個TCP鏈接的現(xiàn)象了。

4、NoHttpResponseException復現(xiàn)

然后接下來是要做的就是根據(jù)之前的猜想來復現(xiàn)NoHttpResponseException場景,具體的思路如下

  • 在Httpclient源碼中,等待tcp鏈接建立完成后,打上斷點
  • 等服務器主動發(fā)送FIN包斷開鏈接后,再發(fā)起請求,然后觀察結果

成功復現(xiàn)了NoHttpResponseException現(xiàn)象,抓包結果如下所示

通過抓包結果分析,可以得出"服務端主動斷開TCP鏈接,然后客戶端使用半斷開的鏈接發(fā)起請求"確實會導致NoHttpResponseException現(xiàn)象,至于服務端什么情況下會主動斷開tcp鏈接?間隔多久主動斷開tcp鏈接?這里就不再討論了,讀者可以自行了解一下keep-alive機制。分析到這里,問題基本上算是解決了,生產(chǎn)環(huán)境出現(xiàn)此問題的執(zhí)行時序應該如下所示

  • 客戶端HttpClient復用之前已經(jīng)Open的鏈接
  • 然后進行檢查(因為此時服務端還未關閉tcp鏈接,所以鏈接可用)
  • 緊接著服務端主動關閉鏈接導致鏈接不可用
  • 服務端針對客戶端的請求響應了RST包

5、解決方案

從業(yè)務層面考慮,即使修復了這個問題,也還是會有很大的風險,畢竟網(wǎng)絡是未知的,因此我建議C端同事做一個補償機制,用來處理退款失敗情況。

當然網(wǎng)絡層面該優(yōu)化的也得優(yōu)化,具體步驟是在HttpClient初始化時添加重試策略。

private static CloseableHttpClient init() {
        // 配置請求的超時設置
        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectionRequestTimeout(CONNECTION_REQUEST_TIMEOUT)
                .setConnectTimeout(CONNECT_TIMEOUT)
                .setSocketTimeout(SOCKET_TIMEOUT)
                .build();
        // 重試策略 RETRY_COUNT=3 代表NoHttpResponseException異常重試3次
        HttpRequestRetryHandler retryHandler = (exception, executionCount, context) -> {
            return executionCount <= RETRY_COUNT && exception instanceof NoHttpResponseException;
        }; 
        return HttpClients.custom()
                .setConnectionManager(new PoolingHttpClientConnectionManager())
                .setRetryHandler(retryHandler)
                .setDefaultRequestConfig(requestConfig)
                .build();
    }

6、引發(fā)的思考

  • HttpClientPool的鏈接管理策略(復用、回收等等)。
  • Keep-alive機制
  • 計算機網(wǎng)絡

以上就是生產(chǎn)環(huán)境NoHttpResponseException異常排查解決記錄分析的詳細內容,更多關于生產(chǎn)環(huán)境NoHttpResponseException的資料請關注腳本之家其它相關文章!

相關文章

  • Java的LinkedHashSet源碼深入講解

    Java的LinkedHashSet源碼深入講解

    這篇文章主要介紹了Java的LinkedHashSet源碼深入講解,LinkedHashSet是HashSet的子類,而由于HashSet實現(xiàn)了Set接口,因此LinkedHashSet也間接實現(xiàn)了Set類,LinkedHashSet類屬于java.base模塊,java.util包下,需要的朋友可以參考下
    2023-09-09
  • 什么是RESTful?API,有什么作用

    什么是RESTful?API,有什么作用

    提到RESTful?API大家勢必或多或少聽說過,但是什么是RESTful?API??如何理解RESTful?API?呢?今天咱們就來聊聊這個RESTful?API
    2023-11-11
  • 一文教你如何使用原生的Feign

    一文教你如何使用原生的Feign

    Feign使得 Java HTTP 客戶端編寫更方便,Feign 靈感來源于Retrofit、JAXRS-2.0和WebSocket,這篇文章主要給大家介紹了如何使用原生的Feign的相關資料,需要的朋友可以參考下
    2021-10-10
  • Java 通過 二三法 巧解前端數(shù)據(jù)顯示

    Java 通過 二三法 巧解前端數(shù)據(jù)顯示

    實踐來源于理論,做開發(fā)前肯定要先了解相關的規(guī)則和原理,看到標題或許你會好奇什么是二三法。本篇文章帶你深入了解,需要的朋友可以參考下
    2021-10-10
  • springMVC導出word模板的方法

    springMVC導出word模板的方法

    這篇文章主要為大家詳細介紹了springMVC導出word模板的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • POI導出Excel報錯No such file or directory的解決方法

    POI導出Excel報錯No such file or directory的解決方法

    這篇文章主要為大家詳細介紹了POI導出Excel報錯No such file or directory的解決方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • spring+hibernate 兩種整合方式配置文件的方法

    spring+hibernate 兩種整合方式配置文件的方法

    本篇文章主要介紹了spring+hibernate 兩種整合方式配置文件的方法,主要有兩種方式 1、注解方式 2、xml方式實現(xiàn),有興趣的可以了解一下。
    2017-04-04
  • 在SpringBoot中整合使用Netty框架的詳細教程

    在SpringBoot中整合使用Netty框架的詳細教程

    這篇文章主要介紹了在SpringBoot中整合使用Netty框架的教程,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-06-06
  • Java中BM(Boyer-Moore)算法的圖解與實現(xiàn)

    Java中BM(Boyer-Moore)算法的圖解與實現(xiàn)

    本文主要介紹了兩個大的部分,第一部分通過圖解的方式講解BM算法,第二部分則代碼實現(xiàn)一個簡易的BM算法,感興趣的小伙伴可以學習一下
    2022-05-05
  • 一個簡單的java學生寢室查詢系統(tǒng)

    一個簡單的java學生寢室查詢系統(tǒng)

    這篇文章主要為大家詳細介紹了一個簡單的java學生寢室查詢系統(tǒng),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2017-10-10

最新評論

托里县| 大宁县| 宁陕县| 延寿县| 图们市| 西畴县| 荔波县| 即墨市| 即墨市| 兰考县| 通化市| 玉树县| 天台县| 甘泉县| 吕梁市| 潜山县| 得荣县| 盖州市| 屏山县| 托里县| 区。| 南召县| 佳木斯市| 晋城| 沅陵县| 镇赉县| 将乐县| 金川县| 昭苏县| 沂源县| 宁城县| 云梦县| 郑州市| 宁波市| 乌兰察布市| 郧西县| 江陵县| 东港市| 湄潭县| 新邵县| 昔阳县|