1. 程式人生 > >Kafka scala客戶端在broker宕機對傳送請求超時問題分析與方案

Kafka scala客戶端在broker宕機對傳送請求超時問題分析與方案

現象

生產中kafka叢集一臺伺服器硬體故障下線,kafka叢集具備高可用特性,下線broker上的leader分割槽自動切換到新的broker節點,客戶端連結隨之切換至新的節點繼續提供服務,從流量上看也未發現異常情況;叢集整體執行平穩,無異常。但後續有一個業務方反饋每10分鐘就有少量介面響應時間升高導致超時,檢視日誌發現傳送訊息的介面有WARN日誌,日誌內容如下:

分析

根據服務日誌異常呼叫棧反映出的問題:業務執行緒在訊息傳送時,會觸發獲取遠端metadata的服務請求,請求發到了宕機伺服器後丟擲Exception,並且很有周期性的每10分鐘間隔發生少量異常;根據呼叫棧深入到kafka程式碼,找到發生問題的位置DefaultEventHandler.handle():

紅色方框裡的程式碼,是傳送訊息前處理的一段邏輯,topicMetadataRefreshInterval為更新metadata路由表的間隔時間,預設為600000(10分鐘)。

傳送訊息前會判斷本次傳送是否需要更新路由表,判斷依據為topicMetadataRefreshInterval指定的時間間隔, 設定不同值時執行情況如下:

topicMetadataRefreshInterval< 0

         會跳過路由表更新邏輯,直接進入到訊息傳送環節(下圖紅色方框部分),如果傳送不成功(比如partition leader切換情況),則返回結果列表outstandingProduceRequests不為空,執行緒會睡眠retryBackoffMs指定的時間,然後同步傳送brokerPartitionInfo.updateInfo()

的請求,去獲取失敗topic的路由資訊;同時本次傳送失敗,進入while迴圈判斷是否內部重試,設定了重試次數那麼內部繼續重試傳送,上一次更新了新的路由,重試後可能傳送成功,否則繼續之前的邏輯至到成功或重試次數結束返回;

topicMetadataRefreshInterval= 0

         該情況下,每次傳送訊息前都會進入到路由表更新邏輯執行brokerPartitionInfo.updateInfo(…)

topicMetadataRefreshInterval> 0

         該情況會按照topicMetadataRefreshInterval(預設值為10分鐘)

間隔的時間,執行brokerPartitionInfo.updateInfo(…),在10分鐘之內的傳送請求不會進入到該段邏輯;

上面文字描述了訊息傳送階段,在什麼條件下會執行brokerPartitionInfo.updateInfo(…)這段邏輯,而引起執行緒堵塞的真正凶手也將浮出水面,updateInfo()內部有段邏輯才是引起延遲的真凶fetchTopicMetadata():

fetchTopicMetadata方法裡,對broker列表首先做了混洗處理,然後從列表第一個broker進行遍歷並執行同步傳送metadata request請求,如果發向第一個broker獲取meta失敗,繼續第二個直到成功或者列表遍歷完畢退出;在生產案例中,一臺broker宕機(整臺機器斷電),如果請求的正好是該機器,建立TCP握手階段會出現堵塞,直到socket的connection timeout超時返回,會造成業務執行緒堵塞;有個細節還需說明,如果機器存活程序死掉的情況下,該堵塞時間會小很多,原因TCP握手成功,訪問服務程序失敗會立即返回錯誤並切換下一個broker嘗試;我們遇到的情況正好是IP不可訪問,因而引起較長的超時等待,從而導致業務介面超時,但訊息成功傳送;

在發現kafka客戶端有這樣的行為後,為了防止影響,臨時使用一臺非標準配置的機器快速加入kafka叢集解決問題(當時機房沒有kafka標準配置的機器)。

方案

針對以上情況,相關改進措施:

      1.   使用同步傳送情況下,修改topic.metadata.refresh.interval.ms 值為負數;

             a. 客戶端只有在傳送失敗的情況下(比如leader節點發生變化的分割槽)才會進行一次路由更新,不會對正常的傳送連結產生影響;

             b. 發生路由更新會出現請求時間加長的情況,成功之後不會對後續傳送產生影響;

             c. 但在partition數量擴容時,客戶端正常傳送情況下,缺乏感知分割槽變化進行動態調整;

      2.   在kafka最新java客戶端中,採用了新的執行緒模型,即使在同步傳送模式下也會採用非同步執行緒來執行訊息的傳送,更新metadata的動作不會在業務執行緒中執行,而是非同步sender執行緒來執行,並會跳過對失效節點的請求,避免網路問題引起執行緒的堵塞,同時介面層面採用了友好的超時中斷機制,讓業務更好的控制超時情況。

相關推薦

Kafka scala客戶broker傳送請求超時問題分析方案

現象 生產中kafka叢集一臺伺服器硬體故障下線,kafka叢集具備高可用特性,下線broker上的leader分割槽自動切換到新的broker節點,客戶端連結隨之切換至新的節點繼續提供服務,從流量上看也未發現異常情況;叢集整體執行平穩,無異常。但後續有一個業務方反饋每10

Alluxio客戶顯示找不到FileSystem類問題分析解決

我們發現時常在使用者郵件列表上會出現一個有關作業失敗的問題,這個失敗伴隨著錯誤訊息“java.lang.ClassNotFoundException:Class alluxio.hadoop.FileSystemnot found”。這篇部落格分析解釋了這種失敗的原因以及發生該問題時的解決方案。

解Bug之路-記一次機器後的tcp行為

# 解Bug之路-記一次對端機器宕機後的tcp行為 ## 前言 機器一般過質保之後,就會因為各種各樣的問題而宕機。而這一次的宕機,讓筆者觀察到了平常觀察不到的tcp在對端宕機情況下的行為。經過詳細跟蹤分析原因之後,發現可以通過調整核心tcp引數來減少宕機造成的影響。 ## Bug現場 筆者所在的公司用某個中介

SmartAccess禁止通過NetScaler用戶訪問虛擬桌面重定向客戶打印

edit size 分析 ces access 桌面圖標 打印機 服務 pro SmartAccess禁止通過NetScaler用戶重定向客戶端打印機 介紹 SmartAccess和SmartControl允許您根據用戶連接的方式更改ICA連接行為(例如,禁用客戶端設備映射

goldengate源意外,傳輸程序終止,導致OGG-01031報錯

伺服器宕機,沒有停止dpump程序,啟動後處於abend狀態,檢查ggserr.log報以下錯誤: 2011-04-01 11:13:19 ERROR OGG-01031 Oracle GoldenGate Capture for Oracle, dpump.prm: There is a proble

安裝kafka到window上,編寫kafka java客戶連線kafka

package com.kafka; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.concurrent.Executo

Kafka-python 客戶導致的 cpu 使用過高,且無法消費消息的問題

的確 fse get sum req 今天 als top report 今天遇到一個情況使用了 Kafka-python 1.3.3 來操作讀取 broker 1.0.1 版本的 kafka。出現了 rebalance 之後分配到了客戶端,但是 cpu 利用率很高且無法消

Java獲取客戶、本IP

獲取客戶端IP某些情況下需要或取使用者客戶端的ip,用來統計或者攔截,比如有些網站是需要遮蔽海外ip的訪問的,這就需要獲取客戶端的訪問ip。一般情況下用HttpServletRequest物件的getR

一種在客戶利用js實現資料校驗的方法

   通常為了減輕伺服器端的壓力會在客戶端利用js或其他指令碼對使用者填寫的需要提交的資料進行校驗,同時也會帶來使用者體驗的提升。下面介紹一種在客戶端利用js實現對資料進行校驗的方法,僅供參考。      現在假設使用者需要在客戶端通過後臺進行對產品類別的新增操作,利用js

kafka消費者客戶

Kafka消費者1.1 消費者與消費者組消費者與消費者組之間的關係​ 每一個消費者都隸屬於某一個消費者組,一個消費者組可以包含一個或多個消費者,每一條訊息只會被消費者組中的某一個消費者所消費。不同消費者組之間訊息的消費是互不干擾的。為什麼會有消費者組的概念​ 消費者組出現主要是出於兩個

.NET客戶實現Redis中的管道(PipeLine)事物(Transactions)

redis服務器 net 他會 端口 ocs string new equal alt 原文:.NET客戶端實現Redis中的管道(PipeLine)與事物(Transactions)序言 Redis中的管道(PipeLine)特性:簡述一下就是,Redis如何從客戶端一

redis客戶連接,最大連接數查詢設置

指定 col node 網絡 service服務 限制 style nbsp free ##redis客戶端連接數 redis通過監聽一個TCP端口或socket的方式接收來自客戶端的連接, 當與客戶端建立連接後,redis內部會進行如下操作:(1)客戶端socket會

Android外掛化開發之AMS應用程式(客戶ActivityThread、Instrumentation、Activity)通訊模型分析

今天主要分析下ActivityManagerService(服務端) 與應用程式(客戶端)之間的通訊模型,在介紹這個通訊模型的基礎上,再    簡單介紹實現這個模型所需要資料型別。         本文所介紹內容基於android2.2版本。由於Android版本的不同

客戶連線伺服器,配置出錯“連線超時”或者“無監聽程式”解決方法

這兩天在進行Oracle的客戶端配置,伺服器OS為Windows XP 64,客戶端OS為Win7 64,oracle版本為11.2。 先說下伺服器端自己的疑惑,由於自己是新手,很多都不明白是怎麼個回事。 1)關於服務端監聽程式配置時候的SID設定 我在建立資料庫的時候,設定

php 獲取客戶的真實IP地址 和 檢查客戶從什麼地方過來的請求

/* * 函式功能: 獲取客戶端的真實IP地址 * * 為什麼要用這個函式? * 因為我們線上Web伺服器絕大部分都處於Netscaler(簡稱NS)後面,客戶端訪問的地址統一由NS排程 * 由NS排程的訪問其實就是NS做了一層代理, 這期間就有一個問題, 因為真實

Android客戶採用Http 協議Post方式請求服務進行資料互動

本示例以Servlet為例,演示Android與Servlet的通訊。 眾所周知,Android與伺服器通訊通常採用HTTP通訊方式和Socket通訊方式,而HTTP通訊方式又分get和post兩種方式。至於Socket通訊會在以後的博文中介紹。 HTTP協議簡介:

華為×××客戶SecoClient報錯“接受返回碼超時”故障解決

重啟 硬件 ima 上線 防火墻 選擇 查看 強制 管理器 問題:客戶新上了一臺華為USG系列防火墻,配置完成後發現自帶的有SSL V-P-N服務,隨機把該功能配置啟用作為外出員工查看公司部分資源的接入通道,上線運行幾個月一直使用正常。突然有一天客戶說有員工連不上,提示“接

客戶瀏覽器向伺服器發起http請求的全過程

http協議的參考:http://blog.csdn.net/hefeng6500/article/details/75081047 (1)瀏覽器先搜尋自身的DNS快取 (2)作業系統搜尋自身的DNS快取(瀏覽器沒有找到快取或者快取已經失效) (3)讀取本地的HOST檔案