亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

生產(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端調(diào)用B端支付模塊進行退款。為了方便大家理解,我嘔心瀝血的畫出了系統(tǒng)調(diào)用的時序圖。

生產(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)支付回調(diào)是正常的,并且下游系統(tǒng)也響應了success,但是卻沒有調(diào)用退款接口進行退款。排查到這里基本已經(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異常排查解決記錄分析的詳細內(nèi)容,更多關于生產(chǎn)環(huán)境NoHttpResponseException的資料請關注腳本之家其它相關文章!

相關文章

  • Spring整合Quartz定時任務并在集群、分布式系統(tǒng)中的應用

    Spring整合Quartz定時任務并在集群、分布式系統(tǒng)中的應用

    這篇文章主要介紹了Spring整合Quartz定時任務并在集群、分布式系統(tǒng)中的應用,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-04-04
  • Java設計模式之橋接模式詳解(Bridge Pattern)

    Java設計模式之橋接模式詳解(Bridge Pattern)

    橋接模式是一種結構型設計模式,旨在將抽象部分與其實現(xiàn)部分分離,從而使兩者可以獨立地變化,橋接模式通過組合關系代替繼承關系,將抽象和實現(xiàn)解耦,使代碼更具擴展性和維護性
    2025-02-02
  • Spring?JPA之find拓展方法示例詳解

    Spring?JPA之find拓展方法示例詳解

    這篇文章主要為大家介紹了Spring?JPA之find拓展方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • 解析Java虛擬機中類的初始化及加載器的父委托機制

    解析Java虛擬機中類的初始化及加載器的父委托機制

    這篇文章主要介紹了Java虛擬機中類的初始化及加載器的父委托機制,包括命名空間等深層次的知識點講解,需要的朋友可以參考下
    2015-11-11
  • Java實現(xiàn)克魯斯卡爾算法的示例代碼

    Java實現(xiàn)克魯斯卡爾算法的示例代碼

    克魯斯卡爾算法是一種用于求解最小生成樹問題的貪心算法。這篇文章主要為大家詳細介紹了Java實現(xiàn)克魯斯卡爾算法的方法,需要的可以參考一下
    2023-04-04
  • SpringBoot應用jar包啟動原理詳解

    SpringBoot應用jar包啟動原理詳解

    本文主要介紹了SpringBoot應用jar包啟動原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-03-03
  • java必學必會之方法的重載(overload)

    java必學必會之方法的重載(overload)

    java必學必會之方法的重載,介紹了方法的重載、構造方法的重載,想要學好java方法的重載的朋友一定要好好閱讀這篇文章
    2015-12-12
  • Java單例模式分析

    Java單例模式分析

    這篇文章主要給大家介紹了關于Java單例模式,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2021-09-09
  • java使用poi在excel單元格添加超鏈接設置字體顏色的方法

    java使用poi在excel單元格添加超鏈接設置字體顏色的方法

    這篇文章主要介紹了java使用poi在excel單元格添加超鏈接,設置字體顏色,poi功能還是很強大的,基本能想到的功能都能通過poi實現(xiàn),本文結合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下
    2023-09-09
  • 詳解Spring如何解析占位符

    詳解Spring如何解析占位符

    Spring一直支持將屬性定義到外部的屬性的文件中,并使用占占位符的形式為使用"${}"包裝的屬性名稱,為了使用屬性占位符,我們必須配置一個PropertyPlaceholderConfigurer或PropertySourcesPlaceholderConfigurer實例,本文將介紹如何解析占位符
    2021-06-06

最新評論