Kafka——Kafka控制器

引言

在Kafka集群中,有一個組件堪稱"隱形的指揮官"——它默默協調著Broker的加入與退出,管理著主題的創建與刪除,掌控著分區領導者的選舉,它就是控制器(Controller)。想象一個擁有100臺Broker的大型Kafka集群:當某臺Broker突然宕機,誰來檢測并觸發分區領導者切換?當管理員創建新主題時,誰來分配分區并同步元數據到所有節點?答案正是控制器。

控制器是Kafka集群的核心協調組件,它通過ZooKeeper實現分布式協調,確保集群在各種場景下(如Broker故障、主題變更)都能有序運行。每個Kafka集群在任意時刻有且僅有一個活躍控制器,這一特性既是其設計的精妙之處,也暗藏單點故障的風險——為此,Kafka設計了完善的故障轉移機制,確保控制器失效時能快速恢復。

ZooKeeper:控制器的"分布式數據庫"

Kafka控制器重度依賴ZooKeeper實現分布式協調,理解ZooKeeper的核心功能是掌握控制器工作原理的前提。

ZooKeeper的核心功能

ZooKeeper是一個高可用的分布式協調服務,為Kafka提供以下關鍵能力:

  1. 樹形數據模型 ZooKeeper的存儲結構類似文件系統,以"/"為根目錄,每個節點(znode)可存儲少量元數據(默認最大1MB)。Kafka在ZooKeeper中創建了大量znode,用于存儲集群元數據,如/brokers/ids存儲所有Broker的ID,/topics存儲主題信息,/controller標識當前控制器等。

  2. znode的持久性分類

    • 持久性znode:創建后永久存在,除非手動刪除(如/topics/test存儲主題test的元數據)。

    • 臨時znode:與創建者的會話綁定,會話結束后自動刪除(如/brokers/ids/0代表Broker 0,若其宕機,該節點會被自動刪除)。

  3. Watch通知機制 客戶端可注冊監聽znode的變更(創建、刪除、數據修改),當事件發生時,ZooKeeper會實時通知客戶端。控制器正是通過Watch機制感知集群變化,如監聽/brokers/ids節點發現新Broker加入,監聽/controller節點檢測控制器故障。

Kafka在ZooKeeper中的關鍵節點

Kafka在ZooKeeper中創建了多個關鍵節點,控制器通過這些節點實現集群管理:

節點路徑功能描述存儲內容示例備注
Broker 相關
/brokers/ids注冊 Broker 信息,記錄每個 Broker 的網絡地址、端口等子節點為 broker.id,內容如:{"host":"10.0.0.1","port":9092,"jmx_port":9999}Broker 啟動時創建,通過心跳維持;下線后節點自動刪除。
/brokers/topics存儲所有 Topic 的元數據(分區、副本分布)子節點為 topic 名稱,下含 partitions/[partition-id]/replicas(副本列表)Topic 創建時生成,刪除時遞歸刪除子節點;記錄分區的副本分布。
Controller 相關
/controller記錄當前集群的 Controller Broker ID(集群核心協調者)內容為數字(如 "2",對應 Broker.id=2)Controller 選舉后更新;是集群元數據、分區 leader 等的核心管理者。
/controller_epochController 的紀元(版本號),防止舊 Controller 的無效操作內容為數字(如 "5",每次 Controller 變更時紀元 +1)配合 /controller 實現“腦裂”防護:舊紀元的請求會被忽略。
Consumer 相關(舊版架構)
/consumers/<group_name>/offsets(舊版)存儲消費者組的消費偏移量(新版已遷移到 Kafka 內部主題 __consumer_offsets子節點為 {topic}-{partition},內容為偏移量(如 "12345"新版 Kafka 建議禁用該方式,改用內部主題存儲偏移(更可靠、可擴展)。
/consumers/<group_name>/ids(舊版)存儲消費者組內每個消費者實例的信息子節點為消費者實例 ID,內容如:{"client_id":"consumer-1","host":"10.0.0.2"}消費者加入組時注冊,離開時刪除;屬于舊版 Consumer Group 架構(已被取代)。
/consumers/<group_name>/owners(舊版)記錄消費者組中各分區的所有者(哪個消費者實例消費該分區)子節點為 {topic}-{partition},內容為消費者實例 ID(如 "consumer-1-1"消費分配(如 Range、RoundRobin)后更新;舊版協調器(ZooKeeper-based)使用。
配置相關
/config存儲 主題/ Broker /用戶 的自定義配置(支持動態更新)子節點 topics/[topic-name],內容如:{"retention.ms":"86400000"}配置變更時,會觸發 /config/changes 的通知。
/config/changes配置變更的通知節點,用于監聽配置變化事件可能存儲變更版本(如 "v1")或作為 Watcher 觸發標記(空節點)Kafka 組件(如 Broker)通過 Watcher 感知配置變化,實現動態更新。
管理操作相關
/admin/delete_topics標記待刪除的主題,觸發 Controller 的主題刪除流程子節點為 topic 名稱(如 "test-topic"),內容為空或標記時間提交刪除請求后創建,Controller 處理完刪除邏輯后移除該節點。
/admin/reassign_partitions存儲 分區重分配任務(手動/自動 Rebalance)內容為 JSON,如:{"partitions":[{"topic":"test","partition":0,"replicas":[1,2]}}管理員提交任務后創建,任務完成后由 Controller 清理。
/admin/preferred_replica_selection存儲 優先副本選舉任務(平衡 Leader 負載,切到優先副本)內容為 JSON,如:{"partitions":[{"topic":"test","partition":0}]}提交后由 Controller 處理,選舉完成后刪除節點。
變更通知相關
/air_change_notification集群狀態變更通知(如 Topic 創建、Broker 上下線、配置變更等)可能存儲事件序列(如 "event-1")或作為 Watcher 觸發節點(空節點)Kafka 組件(如 Broker、Controller)監聽該節點,感知集群狀態變化。

這些節點構成了Kafka集群的"元數據中心",控制器通過讀寫這些節點實現對集群的協調管理。

控制器的選舉:從"競選"到"就職"

Kafka集群啟動時,控制器并非天生存在,而是通過"競選"產生。這一過程依賴ZooKeeper的分布式鎖特性,確保最終只有一個Broker成為控制器。

選舉機制:誰先創建節點誰當選

控制器的選舉邏輯簡潔而高效:

  1. 競選觸發:每個Broker啟動時,會嘗試向ZooKeeper創建/controller臨時節點。

  2. 競爭結果:由于ZooKeeper保證節點的唯一性,第一個成功創建/controller節點的Broker將成為控制器。

  3. 身份確認:成功創建節點的Broker會將自己的ID寫入節點數據(如{"brokerid":3,"epoch":0}),其他Broker發現/controller已存在,會放棄競選并監聽該節點的變化。

這種"先到先得"的機制確保了選舉的高效性,通常在集群啟動后幾秒內即可完成。

紀元(Epoch):避免"腦裂"的安全機制

為防止舊控制器故障后仍發送指令(即"腦裂"),Kafka引入控制器紀元(Controller Epoch)

  • 每次選舉產生新控制器時,紀元值遞增(如從0→1→2)。

  • 控制器發送的所有指令都攜帶紀元值,其他Broker只接受紀元值大于當前已知值的指令。

  • 紀元值存儲在/controller_epoch節點,確保集群全局一致。

例如,若舊控制器(紀元1)在故障后仍發送指令,新控制器(紀元2)已將紀元值同步給所有Broker,舊指令會因紀元值過小被忽略,避免混亂。

控制器的五大核心職責:集群的"管理員"

控制器是Kafka集群的"大管家",承擔著主題管理、集群成員維護等關鍵職責,這些職責的正常履行直接決定了集群的可用性。

主題管理:創建、刪除與分區擴容

當用戶執行kafka-topics.sh腳本創建主題時,實際工作由控制器完成:

  1. 創建主題:控制器接收請求后,在ZooKeeper的/brokers/topics下創建主題節點,寫入分區數、副本數等配置。

  2. 分配分區:根據副本分配策略(如機架感知),將分區的副本分配到不同Broker。

  3. 同步元數據:通過LeaderAndIsr請求通知相關Broker創建分區目錄,并將元數據同步到所有Broker。

刪除主題和增加分區的流程類似:控制器監聽/admin/delete_topics節點觸發刪除,或直接更新主題節點數據觸發分區擴容,再同步給全集群。

分區重分配:負載均衡的"調度師"

當集群中Broker負載不均時,管理員可通過kafka-reassign-partitions.sh腳本觸發分區重分配,這一過程由控制器主導:

  1. 接收任務:控制器讀取/admin/reassign_partitions節點中的重分配計劃。

  2. 協調遷移:向涉及的Broker發送指令,先創建新副本,同步數據,再切換領導者,最后刪除舊副本。

  3. 更新元數據:重分配完成后,更新ZooKeeper中的分區副本信息,并同步給所有Broker。

這一機制確保了分區遷移過程中服務不中斷,是Kafka彈性擴縮容的核心支撐。

Preferred領導者選舉:負載均衡的"平衡器"

Kafka創建分區時,會將第一個副本設為"Preferred領導者"(優先領導者)。若因故障導致領導者切換為其他副本,可能造成Broker負載不均。控制器通過Preferred領導者選舉修復這一問題:

  1. 觸發條件:管理員執行kafka-preferred-replica-election.sh腳本,或控制器檢測到負載失衡。

  2. 選舉流程:控制器向目標分區的Preferred領導者副本發送LeaderAndIsr請求,將其切換為領導者(前提是該副本在ISR中)。

  3. 同步結果:更新分區元數據,并通知所有Broker。

這一功能確保了長期運行后,領導者副本仍能均勻分布在集群中。

集群成員管理:Broker的"花名冊"

控制器通過監聽ZooKeeper的/brokers/ids節點,實時掌握集群成員變化:

  • 新Broker加入:新Broker啟動時會在/brokers/ids下創建臨時節點,控制器通過Watch機制感知后,將其加入集群,并分配現有主題的副本。

  • Broker主動關閉:Broker關閉前會刪除自身在/brokers/ids下的節點,控制器收到通知后,觸發受影響分區的領導者重選舉。

  • Broker宕機:Broker與ZooKeeper的會話超時后,臨時節點被自動刪除,控制器檢測到后,立即啟動故障轉移(如將宕機Broker上的領導者副本切換到其他存活副本)。

這一機制確保了集群在Broker動態變化時仍能保持可用性。

數據服務:元數據的"分發中心"

控制器保存著集群最完整的元數據,并定期同步給其他Broker:

  • 元數據內容:所有主題的分區信息(領導者、ISR集合)、Broker列表、運維任務(如正在重分配的分區)等。

  • 同步機制:其他Broker定期向控制器發送Metadata請求,獲取最新元數據并更新本地緩存。

  • 主動推送:當元數據發生重大變更(如領導者切換),控制器會主動向相關Broker發送通知。

這一機制確保了全集群元數據的一致性,是生產者和消費者正確工作的前提。

控制器的"記憶":數據存儲與初始化

控制器之所以能高效履行職責,得益于其緩存的完整元數據。這些數據既來自ZooKeeper,也包含運行時的動態信息。

核心數據內容

控制器的緩存(ControllerContext)包含以下關鍵信息:

  • 主題與分區數據:所有主題的列表、每個分區的副本分布、領導者副本ID、ISR集合等。

  • Broker信息:存活Broker的ID、地址、端口,以及正在關閉的Broker列表。

  • 運維任務狀態:正在進行重分配的分區、正在執行Preferred選舉的分區等。

  • ZooKeeper節點緩存:部分znode的內容緩存,減少對ZooKeeper的直接訪問。

這些數據構成了控制器管理集群的"決策依據"。

數據項名稱功能描述存儲/維護方式核心作用與關聯機制
Broker 狀態類
當前存活 Broker 列表記錄集群中活躍 Broker(通過心跳維持,未超時)內存維護,基于 Broker 心跳包更新(超時則移除)Controller 決策(如選舉 leader、分配副本)的“可用節點池”,排除故障 Broker。
正在關閉中 Broker 列表標記主動優雅關閉的 Broker(非崩潰,需安全遷移副本)Broker 發起關閉請求時創建標記,副本遷移完成后清除區別于崩潰 Broker,優先觸發副本遷移,保證數據不丟失(如 Broker.shutdown 流程)。
分區與副本類
分配給每個分區的副本列表每個分區的 AR(Assigned Replicas):該分區的所有副本所在 Broker ID 集合存儲于分區元數據(如 [1,2,3],對應 Broker ID)副本分配的基準(創建 Topic 時確定),故障時從 AR 中選舉新 leader,重分配時參考。
每個分區的 leader 和 ISR 信息分區的 主副本(leader) + 同步副本(ISR,In-Sync Replicas)leader 是單個 Broker ID,ISR 是 Broker ID 列表(實時更新,基于副本同步狀態)讀寫路由:僅 leader 處理客戶端請求;選舉約束:故障時僅從 ISR 中選新 leader(保證數據一致)。
某個 Broker 上的所有分區反向索引:某 Broker 承載的所有分區<topic>-<partition> 集合)內存映射表(Broker ID → 分區列表),基于分區的 leader/副本分布動態更新負載均衡分析(如 Broker 負載過高觸發重分配),故障轉移時快速定位受影響分區。
某組 Broker 上的所有副本統計指定 Broker 組承載的所有副本(跨 Topic、分區)動態計算(遍歷所有分區的 AR,篩選屬于目標 Broker 組的副本)副本遷移規劃(如 Broker 擴容/縮容時,確定源和目標 Broker 的副本分布)。
某個 Topic 的所有副本該 Topic 下所有分區的 AR 集合(每個分區的副本列表)遍歷該 Topic 的分區元數據,收集每個分區的 AR 數組Topic 級副本管理(如修改副本數、檢查分布均衡性),批量操作的基礎。
某個 Topic 的所有分區該 Topic 的分區集合(含分區 ID、leader、ISR、AR 等元數據)Topic 元數據中維護分區列表,關聯每個分區的詳細信息讀寫請求路由(定位分區 leader),分區級操作(重分配、選舉)的入口。
當前存活的所有副本篩選所在 Broker 存活的副本(排除 Broker 下線的副本)動態計算(基于“存活 Broker 列表”過濾副本的所在 Broker)選舉新 leader 時,僅從存活副本中選擇(避免選到故障 Broker 的副本,提升可靠性)。
某組分區下的所有副本指定分區集合(如某 Topic 的部分分區)的 AR 集合遍歷目標分區,收集每個分區的 AR 數組批量操作(如批量重分配、批量選舉)時,高效獲取副本分布,減少重復計算。
任務與生命周期類
正在進行 preferred leader 選舉的分區記錄正在執行優先副本選舉的分區(將 leader 切回 AR 第一個副本,平衡負載)<topic>-<partition> 為鍵,存儲選舉任務狀態(如開始時間、目標副本)確保選舉過程原子性(避免重復觸發),完成后更新 leader 信息,平衡集群負載。
正在進行重分配的分區列表標記處于副本重分配任務的分區(如擴縮容、副本遷移)存儲重分配的目標 AR(如 {"new_replicas": [2,3,4]}保證重分配過程的一致性(避免中斷或重復操作),完成后更新分區的 AR 和 ISR。
Topic 列表集群中所有存在的 Topic 元數據(含分區數、配置、狀態等)基于 ZooKeeper(舊版)或 KRaft 日志(新版)同步,內存維護Controller 處理 Topic 創建、刪除、配置變更的核心依據,關聯所有分區操作。
移除某個 Topic 的所有信息標記待刪除的 Topic,觸發元數據清理(分區、副本、配置等)臨時標記(如 ZooKeeper 的 /admin/delete_topics 節點)或 KRaft 刪除日志觸發遞歸清理:刪除分區元數據、通知 Broker 卸載數據、更新 Topic 列表。

數據初始化流程

當控制器首次啟動或故障轉移后,需要從ZooKeeper加載元數據初始化緩存,流程如下:

  1. 讀取基礎節點:從/brokers/ids獲取所有存活Broker,從/brokers/topics獲取所有主題和分區信息。

  2. 構建分區映射:為每個分區記錄副本分布、當前領導者和ISR(從/brokers/topics/<topic>節點讀取)。

  3. 加載運維任務:從/admin/reassign_partitions等節點讀取正在執行的任務。

  4. 同步到本地緩存:將所有信息整合到ControllerContext,供后續操作使用。

初始化完成后,控制器即可正常履行職責,這一過程通常耗時幾秒(取決于集群規模)。

故障轉移:控制器的"自愈"能力

盡管控制器是單點,但Kafka通過故障轉移機制確保其高可用——當控制器宕機,集群能在幾十秒內自動選舉新控制器,恢復正常運行。

故障檢測:ZooKeeper的"心跳"

控制器與ZooKeeper保持長連接,其存活狀態通過以下機制檢測:

  1. 臨時節點關聯:控制器創建的/controller節點是臨時節點,與控制器的ZooKeeper會話綁定。

  2. 會話超時檢測:若控制器宕機,ZooKeeper會在會話超時后(默認6秒)刪除/controller節點。

  3. Watch通知:所有Broker都監聽/controller節點,當節點被刪除,它們會立即感知到控制器故障。

新控制器選舉與初始化

控制器故障后,故障轉移流程自動啟動:

  1. 重新競選:所有存活Broker檢測到/controller節點被刪除,立即嘗試創建該節點,第一個成功的成為新控制器。

  2. 紀元更新:新控制器將/controller_epoch的值加1(如從1→2),確保舊控制器的指令失效。

  3. 元數據加載:新控制器從ZooKeeper讀取所有元數據,初始化本地緩存(流程同5.2節)。

  4. 通知集群:新控制器向所有Broker發送UpdateMetadata請求,宣告自己的身份并同步最新元數據。

整個過程通常在10-30秒內完成,期間集群可能暫時無法處理主題創建、分區重分配等操作,但已有的生產者和消費者不受影響(依賴本地緩存的元數據)。

內部設計演進:從"混亂"到"有序"

Kafka控制器的內部設計經歷了重大重構,從多線程同步模型演進為單線程事件驅動模型,顯著提升了穩定性和性能。

0.11版本前:多線程模型的困境

早期控制器采用多線程設計,存在明顯缺陷:

  • 線程泛濫:為每個Broker創建專屬通信線程,為主題刪除、分區重分配等任務創建獨立線程,集群規模大時線程數激增。

  • 線程安全風險:多線程共享ControllerContext緩存,需大量使用ReentrantLock同步,導致性能低下且易出現死鎖。

  • ZooKeeper同步操作:所有ZooKeeper讀寫都是同步的,當元數據變更頻繁時,ZooKeeper易成為瓶頸。

這些問題導致早期版本控制器Bug頻發,如主題刪除卡住、重分配失敗等。

0.11版本后:單線程+事件隊列的革新

為解決多線程的弊端,0.11版本重構了控制器設計:

  1. 單線程事件處理:引入一個事件處理線程,所有集群變更(如Broker加入、主題創建)都被建模為事件,放入事件隊列由該線程串行處理。

  2. 異步ZooKeeper操作:將ZooKeeper的同步API改為異步API,避免線程阻塞,寫入性能提升10倍。

  3. 無鎖設計:由于事件串行處理,ControllerContext緩存僅被一個線程訪問,無需鎖機制,消除了死鎖風險。

這一設計顯著提升了控制器的穩定性,社區報告的控制器相關Bug數量大幅減少。

2.2版本后:請求優先級的區分

Kafka 2.2版本進一步優化了控制器請求的處理:

  • 請求分類:將控制器發送的指令(如StopReplica刪除副本、LeaderAndIsr切換領導者)標記為高優先級。

  • 獨立處理通道:高優先級請求繞過普通請求隊列,直接進入專門的處理流程,避免被普通請求(如Produce)阻塞。

例如,刪除主題時,控制器發送的StopReplica請求會被優先處理,避免主題已刪除但仍有消息寫入的荒誕場景。

實戰運維:控制器的監控與問題排查

控制器的穩定性直接決定集群可用性,掌握其監控與故障處理技巧是Kafka運維的核心能力。

關鍵監控指標

通過JMX或Prometheus監控以下指標,實時掌握控制器狀態:

  • activeControllerCount:集群中活躍控制器的數量,正常應為1。若大于1,表明出現"腦裂",需立即處理。

  • controllerEpoch:當前控制器紀元值,應單調遞增(每次故障轉移后+1)。

  • controllerZooKeeperRequestRate:控制器向ZooKeeper的請求速率,突增可能意味著元數據頻繁變更。

  • partitionCount:控制器管理的分區總數,間接反映集群負載。

常見問題與解決方案

問題1:控制器故障后集群無法自動恢復

現象:控制器宕機后,新控制器選舉失敗,activeControllerCount為0。 可能原因

  • ZooKeeper集群異常,Broker無法創建/controller節點。

  • 網絡分區,部分Broker無法訪問ZooKeeper。

解決方案

  1. 檢查ZooKeeper健康狀態(zkServer.sh status)。

  2. 查看Broker日志,確認是否有ZooKeeper連接超時錯誤。

  3. 手動刪除/controller節點(zkCli.sh rmr /controller),觸發重新選舉。

問題2:主題刪除卡住

現象:執行kafka-topics.sh --delete后,主題長期處于"標記刪除"狀態。 可能原因

  • 控制器未收到刪除通知(/admin/delete_topics節點未被正確創建)。

  • 部分Broker未響應StopReplica請求,導致刪除流程阻塞。

解決方案

  1. 檢查ZooKeeper的/admin/delete_topics節點,確認目標主題是否存在。

  2. 查看控制器日志,確認是否有StopReplica請求超時。

  3. 重啟卡住的Broker,或手動觸發控制器重選舉(刪除/controller節點)。

問題3:控制器頻繁切換

現象controllerEpoch頻繁遞增,表明控制器頻繁故障轉移。 可能原因

  • 控制器所在Broker資源不足(CPU/內存過載),導致ZooKeeper會話超時。

  • 網絡不穩定,控制器與ZooKeeper的連接頻繁中斷。

解決方案

  1. 監控控制器所在Broker的資源使用率,確保CPU<70%、內存充足。

  2. 檢查網絡延遲,確保Broker與ZooKeeper的通信延遲<100ms。

  3. 手動將控制器遷移到更穩定的Broker(重啟原控制器Broker,觸發新選舉)。

控制器遷移與升級技巧

  • 平滑遷移:若需將控制器從Broker A遷移到Broker B,可重啟Broker A,觸發新選舉(確保Broker B配置正常)。

  • 版本升級:升級Kafka集群時,建議先升級非控制器Broker,最后升級控制器所在Broker,減少選舉次數。

  • 災備設計:避免將控制器與集群中負載最高的Broker部署在同一節點(如存儲大量分區領導者的Broker)。

總結

Kafka控制器是集群的"大腦",它通過ZooKeeper實現分布式協調,承擔著主題管理、集群成員維護、分區重分配等關鍵職責。其設計經歷了從多線程到單線程事件驅動的演進,穩定性和性能不斷提升。

理解控制器的工作原理,不僅能幫助開發者更好地使用Kafka(如解釋分區領導者切換的原因),更能為運維人員提供排查集群問題的思路(如通過activeControllerCount判斷腦裂)。未來,隨著ZooKeeper依賴的移除,控制器的設計將更加精簡高效,但核心職責和協調邏輯仍將保持延續。

在實際應用中,建議通過監控關鍵指標(如activeControllerCountcontrollerEpoch)實時掌握控制器狀態,結合手動觸發選舉等技巧,確保集群在控制器故障時能快速恢復,為業務提供穩定的消息服務。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/91079.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/91079.shtml
英文地址,請注明出處:http://en.pswp.cn/web/91079.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

編程與數學 03-002 計算機網絡 11_域名系統(DNS)

編程與數學 03-002 計算機網絡 11_域名系統&#xff08;DNS&#xff09;一、DNS的作用與功能&#xff08;一&#xff09;域名與IP地址的映射關系&#xff08;二&#xff09;DNS的層次結構二、DNS查詢過程&#xff08;一&#xff09;遞歸查詢與迭代查詢&#xff08;二&#xff0…

影翎Antigravity將發布全球首款全景無人機,8月開啟公測招募

7月28日&#xff0c;消費級無人機品牌「影翎Antigravity」及品牌標識官宣亮相&#xff0c;計劃推出全新品類——全球首款「全景無人機」。這一消息引發行業震動&#xff0c;消費級航拍無人機市場或將迎來顛覆性飛行體驗。影翎Antigravity官方介紹&#xff0c;引力不僅是束縛雙腳…

SpringBoot集成Quzrtz實現定時任務

一 定時任務介紹 自律是很多人都想擁有的一種能力&#xff0c;或者說素質&#xff0c;但是理想往往很美好&#xff0c;現實卻是無比殘酷的。在現實生活中&#xff0c;我們很難做到自律&#xff0c;或者說做到持續自律。例如&#xff0c;我們經常會做各種學習計劃、儲蓄計劃或減…

Java中的異常判斷以及文件中的常用方法及功能

目錄 異常 作用 異常的處理方式 JVM&#xff08;虛擬機&#xff09;默認的處理方式 自己處理&#xff08;捕獲異常&#xff09; 拋出異常&#xff08;也就是交給調用者處理&#xff09; 自定義異常 file File中常見成員方法 判斷和獲取 創建和刪除 獲取并遍歷 異常…

【C++算法】74.優先級隊列_最后一塊石頭的重量

文章目錄題目鏈接&#xff1a;題目描述&#xff1a;解法C 算法代碼&#xff1a;題目鏈接&#xff1a; 1046. 最后一塊石頭的重量 題目描述&#xff1a; 解法 每次取出最重的兩塊石頭進行碰撞&#xff0c;將剩余的石頭重新放入堆中。 C 算法代碼&#xff1a; class Solution …

中興云電腦W101D2-晶晨S905L3A-2G+8G-安卓9-線刷固件包

中興云電腦W101D2-晶晨S905L3A-2G8G-WIFI-藍牙5.0-3個USB2.0-線刷包線刷方法&#xff1a;1、準備好一根雙公頭USB線刷刷機線&#xff0c;長度30-50CM長度最佳&#xff0c;同時準備一臺電腦&#xff1b;2、電腦上安裝好刷機工具Amlogic USB Burning Tool 軟件 →打開軟件 →文件…

Android OkHttp 底層原理和實戰完全教程(責任鏈模式詳解)

目錄 1. OkHttp 入門:從一個請求開始 1.1 基本 GET 請求:三步走 1.2 同步 vs 異步:選擇你的風格 1.3 為什么選 OkHttp? 2. 配置 OkHttpClient:打造你的專屬網絡引擎 2.1 超時設置:別讓請求卡死 2.2 添加攔截器:窺探請求全過程 2.3 緩存:讓請求更快更省流量 3. …

【RK3588部署yolo】算法篇

簡歷描述收集并制作軍事偽裝目標數據集&#xff0c;包含真實與偽裝各種類型軍事目標共計60余類。其中&#xff0c;包含最新戰場充氣偽裝軍事裝備30余類&#xff0c;并為每一張圖片制作了詳細的標注。針對軍事偽裝目標的特點&#xff0c;在YOLOv8的Backbone與Neck部分分別加…

【Spring Boot 快速入門】一、入門

目錄Spring Boot 簡介Web 入門Spring Boot 快速入門HTTP 協議概述請求協議響應協議解析協議TomcatSpring Boot 簡介 Spring Boot 是由 Pivotal 團隊&#xff08;后被 VMware 收購&#xff09;開發的基于 Spring 框架的開源項目&#xff0c;于 2014 年首次發布。其核心目標是簡…

如何調整服務器的內核參數?-哈爾濱云前沿

調整服務器內核參數是一項較為專業的操作&#xff0c;不同的操作系統調整方式略有不同&#xff0c;以下以常見的 Linux 系統為例&#xff0c;介紹一些調整服務器內核參數的一般步驟和常用參數&#xff1a;一般步驟 備份當前配置&#xff1a;在修改內核參數之前&#xff0c;先備…

C++基礎:模擬實現queue和stack。底層:適配器

引言模擬實現queue和stack&#xff0c;理解適配器&#xff0c;實現起來非常簡單。一、適配器 適配器是一種能讓原本不兼容的接口協同工作的設計模式或者組件。它的主要作用是對一個類的接口進行轉換&#xff0c;使其符合另一個類的期望接口&#xff0c;進而實現適配和復用。&am…

OI 雜題

OI 雜題字符串括號匹配例 1&#xff1a;與之前的類似&#xff0c;就是講一點技巧&#xff0c;但是比較亂&#xff0c;湊合著看吧。 字符串 括號匹配 幾何意義&#xff1a;考慮令 ( 為 111 變換&#xff0c;令 ) 為 ?1-1?1 變換&#xff0c;然后對這個 1/?11/-11/?1 構成…

【論文閱讀】Safety Alignment Should Be Made More Than Just a Few Tokens Deep

Safety Alignment Should Be Made More Than Just a Few Tokens Deep原文摘要問題提出現狀與漏洞&#xff1a;當前LLMs的安全對齊機制容易被攻破&#xff0c;即使是簡單的攻擊&#xff08;如對抗性后綴攻擊&#xff09;或良性的微調也可能導致模型越獄。核心論點&#xff1a; 作…

Generative AI in Game Development

如有侵權或其他問題&#xff0c;歡迎留言聯系更正或刪除。 出處&#xff1a;CHI 20241. 一段話總結本研究通過對來自 Reddit 和 Facebook 群組的 3,091 條獨立游戲開發者的在線帖子和評論進行定性分析&#xff0c;探討了他們對生成式 AI在游戲開發中多方面作用的認知與設想。研…

【C++算法】72.隊列+寬搜_二叉樹的最大寬度

文章目錄題目鏈接&#xff1a;題目描述&#xff1a;解法C 算法代碼&#xff1a;題目鏈接&#xff1a; 662. 二叉樹最大寬度 題目描述&#xff1a; 解法 這里的寬度指的是一層的最右邊的非空節點到一層的最左邊的非空節點&#xff0c;一共的節點數。 解法一&#xff1a;硬來&am…

什么是3DVR?VR技術有哪些應用場景?

VR與3D技術解析及應用在高科技領域&#xff0c;VR和3D是兩個常被提及的名詞。那么&#xff0c;這兩者之間究竟存在著怎樣的區別與聯系呢&#xff1f;簡而來說&#xff0c;VR技術是3D技術的一種高級延展和深化應用。3D技術&#xff0c;即將二維設計圖轉化為立體、逼真的視覺效果…

棧與隊列:數據結構核心解密

棧和隊列的基本 棧(Stack)是一種后進先出(LIFO, Last In First Out)的數據結構。元素的插入和刪除操作只能在棧頂進行。常見的操作包括壓棧(push)和彈棧(pop)。 隊列(Queue)是一種先進先出(FIFO, First In First Out)的數據結構。元素的插入在隊尾進行,刪除在隊…

《C++初階之STL》【list容器:詳解 + 實現】

【list容器&#xff1a;詳解 實現】目錄前言------------標準接口介紹------------標準模板庫中的list容器是什么樣的呢&#xff1f;1. 常見的構造2. 迭代器操作std::list::beginstd::list::endstd::list::rbeginstd::list::rend3. 容量的操作std::list::sizestd::list::empty…

【灰度實驗】——圖像預處理(OpenCV)

目錄 1 灰度圖 2 最大值法 3 平均值法 4 加權均值法 5 兩個極端的灰度值 將彩色圖轉為灰度圖地過程稱為灰度化。 灰度圖是單通道圖像&#xff0c;灰度化本質就是將彩色圖的三通道合并成一個通道的過程。三種合并方法&#xff1a;最大值法&#xff0c;平均值法和加權均值法…

【linux驅動開發】編譯linux驅動程序報錯:ERROR: Kernel configuration is invalid.

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄一、報錯二、解決方法1.先編譯linux內核源碼2.再重新編譯驅動程序一、報錯 在編譯驅動程序過程中&#xff0c;經常碰到的一個小問題&#xff1a; make -C /home/lu…