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

加Log就卡?不加Log就瞎?”——這個插件治好了我的精神內耗

開發 開發工具
在分布式系統日益復雜的今天,日志管理已從簡單的信息記錄演進為系統可觀測性的核心支柱。本文揭示的日志阻塞與策略困境,折射出現代化服務在穩定性與可維護性之間的深層博弈。

1.現有日志打印情況

??日志作為軟件工程實踐中的重要基礎設施,在系統監控、異常診斷及行為追溯等關鍵環節發揮著不可替代的作用。Apache Log4j2作為當前主流的日志框架,憑借其模塊化架構和高度可擴展的特性,為開發者提供了靈活的多維度日志管理方案。然而若未能深入理解其異步日志機制、緩沖區策略等核心原理,或存在配置參數與業務場景匹配度不足等問題,則可能導致日志I/O阻塞、內存資源過度消耗等負面效應,甚至引發嚴重的服務性能瓶頸。因此,在實際工程實踐中需遵循科學合理的使用準則,通過日志分級管理、輸出格式優化、滾動策略定制等手段,方能充分發揮其技術優勢,有效規避潛在風險。

1)日志阻塞

??日志導致線程Block的問題,相信你或許已經遇到過,對此應該深有體會;或許你還沒遇到過,但不代表沒有問題,只是可能還沒有觸發而已。常見的現象是出現大量的block線程,查看jstack常常是下圖現象:圖片

2)從調試到生產,日志策略的抉擇

??在軟件項目的全生命周期中,從開發階段到生產環境的演進過程中,日志管理往往面臨著微妙的平衡。開發階段我們傾向于采用詳盡的日志策略:業務接口的入參出參被完整記錄,跨系統的調用鏈路被清晰標注,甚至非核心邏輯的輔助性信息也得以留存——這些詳實的日志如同開發者的雙目,為聯調排障與功能驗證提供了不可或缺的洞察。

??然而當服務邁向生產環境時,過度日志帶來的問題便逐漸顯現。冗余的調試信息不僅會影響系統性能,更可能淹沒真正關鍵的業務軌跡。盡管我們嘗試在上線前進行日志裁剪,但總存在令人躊躇的灰色地帶:某些開發期輔助日志是否暗含未來的診斷價值?那些看似非核心的流程記錄會否在某個異常場景下成為關鍵線索?這種取舍的困境,本質上反映了我們對系統可觀測性與運行效能之間永續的權衡。

2.問題出現原因

2.1 日志打印原理分析

??在我們使用的log4j的應用中采用的是異步日志配置,簡單的說明一下一條日志打印在log4j中的處理流程如下圖所示:

圖片圖片

??簡單點來說,就是多線程通過 log4j2 的門面類進行日志的打印,日志經過一系列的處理(過濾,包裝)后放入到Disruptor的環形 buffer 中,在服務器的消費端會單啟一個線程進行這些日志的消費,最終放入到我們指定的文件中。

2.2 log4j2 Disruptor 的初始化

??當LoggerContext啟動時,所有AsyncLoggerConfig會通過start()方法初始化其Disruptor:

圖片圖片

??其中Disruptor 是一個環形 buffer,官方做了很多的性能優化,這里有興趣的可以了解其實現原理,這里不進行深入的討論,其中在我們的應用log4j.xml配置中,沒對RingBuffer進行自定義的配置,使用的是默認的大小256K。

2.3 隊列滿導致日志阻塞

??Disruptor 的 RingBuffer 是一個固定大小的環形隊列,其發布邏輯:

圖片圖片

??隊列滿時的默認行為:AsyncLoggerConfig.SynchronizeEnqueueWhenQueueFull=true,此時會等待著消費出下一個可以生產的環形 buffer 槽;此時所有打印日志的線程會嘗試獲取全局鎖。此時會阻塞線程,也就是我們上述堆棧中看到的異常。

2.4 產生的根本原因

??生產者速度 > 消費者速度:

??AsyncAppender 的后臺線程從隊列中取出事件并交給實際 Appender(如 FileAppender)處理,如果實際 Appender 的寫入速度慢(如磁盤 I/O 高),消費者線程無法及時清空隊列,導致隊列積壓。其實log4j消費時會調用多次 flush,這些flush的調用根本在文件寫入的 native 調用,當這種native調用太多時,系統寫入不過來。

3 應對方案

3.1 方案選擇

??上述問題情況解決,大致分成兩個方向:生產者方向&消費者方向,具體行為如下圖簡述:

圖片圖片

??在應對日志管理的挑戰時,除了調整日志隊列容量等基礎優化(需警惕OOM風險),更核心的問題在于如何平衡日志的詳實性與系統穩定性。開發者往往陷入兩難:若詳盡記錄日志,可能引發阻塞風險;若過度精簡,則排查問題時如盲人摸象,難溯根源。

為此,可考慮將日志劃分為兩類:

功能日志(必須):如埋點數據、核心流程記錄,確保業務可觀測性;

業務排查日志(非必須):如RPC入參/出參、調試斷點等,按需動態啟停;

??通過這種分層策略,既能在高并發場景下保障核心日志的穩定輸出,又能靈活控制輔助日志的打印量,使系統整體具備更強的適應性與可控性。如此,我們既能從容應對生產環境的嚴苛要求,又能在需要時快速激活詳盡的診斷信息,實現運維效率與系統性能的兼得。

3.2 技術選擇

??在日志打印的精細化控制中,核心在于靈活性與精準度的平衡。傳統的全局級別過濾(如INFO/WARN/ERROR)雖能粗放管理,卻難以適配復雜多變的業務場景。理想的方案應突破層級限制,實現行級細粒度控制——無論是核心鏈路的關鍵節點,還是特定業務場景的臨時調試,均可針對單行日志動態啟停。

??這種設計賦予開發者更高的自主權:業務視角:按需捕獲特定模塊的完整上下文;鏈路視角:精準聚焦某次調用的全生命周期軌跡;應急場景:即時激活深層診斷日志,無需重啟或改碼。

??通過將控制粒度細化至代碼行,我們既能維持生產環境的日志精簡,又能隨時按業務訴求“點亮”關鍵路徑,使系統可觀測性兼具嚴謹與彈性。

3.2.1 區分必要日志和非必要日志打印:

?自定義封裝日志打印的方式如下圖所示:

圖片圖片

3.2.2 如何對非必要日志進行行級別控制

?1)自定義Appender中的filter:

??在實現行級日志控制時,若需精確控制特定代碼行(如第133行)的日志輸出,采用自定義Appender過濾機制是一種可行方案。其核心思路在于:通過解析日志調用的堆棧信息,動態判斷當前行號是否符合預設的打印條件,若不符合則直接過濾。

??然而,該方案存在若干固有局限: 堆棧解析的可靠性問題:Lambda表達式中的日志調用往往難以準確獲取行號信息,即使通過堆棧緩存優化,仍存在定位失準的風險;性能損耗隱患:頻繁的堆棧遍歷操作會引入不可忽視的性能開銷,在高并發場景下可能成為新的瓶頸;分類管理缺失:該機制難以與既有的日志分級體系(必需/非必需日志)形成有機協同,增加了運維復雜度。

?2)在打印日志前獲取日志的行信息:

??最簡單的方式是人工的形式,在寫日志的時候同時將日志的行信息寫入進去,比如:圖片這種方式在可擴展性和可觀測性維度存在設計缺陷。

?3)在編譯的時候獲取日志的行信息:

??我們想使用LogUtils.debug(()->log.info("業務日志"));這種方式,但是我們不會在代碼中明顯的寫入,可以在代碼編譯期間將行信息獲取到后使用字節碼修改這行代碼,利用Java的重寫。將它轉變成 LogUtils.debug("類+行",()->log.info("業務日志")); 然后再這個方法執行中進行條件判斷。

字節碼技術選擇:

圖片圖片

??在本次實現中需要更靈活的方式操作字節碼,還要考慮性能的問題,以及對應用框架的支持, 我們選擇ASM的形式。

4)如何隨心控制開啟和關閉:

??這里我們采用的是ider插件的方式,有idea插件上報我們的對這行日志的控制行為,如下圖所示:

圖片圖片

3.3 落地實現

3.3.1 Maven編譯插件

??目的:獲取日志所在的類和行信息。

??運行時獲取的方式:在 Logger 配置中啟用 includeLocation,代碼從 LogEvent通過堆棧分析獲取行號。這種方式存在很大的弊端,堆棧跟蹤生成開銷很大,每次調用 getStackTrace() 時,JVM 需要遍歷當前線程的調用棧,生成完整的堆棧信息,這是一個 同步且耗時 的操作(尤其在深調用鏈中),如果每秒有數萬次日志調用,頻繁生成堆棧跟蹤可能導致 CPU 使用率飆升,直接影響吞吐量。

?? Maven的process-classes階段獲取:通過Maven編譯之后獲取到字節碼文件時,對字節碼文件進行修改,存放日志的類和行信息。對運行期間無額外消耗。處理邏輯如下圖所示:

圖片圖片

3.3.2 Idea插件

??目的:精準的控制某一行日志是否進行打印。

??利用Idea的插件能力,將我們對某一行日志的開啟和關閉狀態進行上報,整個過程不阻塞主線程,保持Idea操作流暢性。提供定時能力,保障線上我們可以更靈活的控制日志是否打印的狀態。處理邏輯如下圖所示;

圖片圖片

3.3.3 整體流程

??使用方式:通過在項目中使用上述Maven插件對項目進行編譯部署,使用Idea插件對目標日志的是否開啟打印狀態進行上報,存儲狀態采用的Apollo的能力,通過自定義打印工具類中對Apollo配置內容的分析,進一步做判斷邏輯,最終將日志進行打印或者不打印。處理邏輯如下圖所示:

圖片圖片

4.總結

??在分布式系統日益復雜的今天,日志管理已從簡單的信息記錄演進為系統可觀測性的核心支柱。本文揭示的日志阻塞與策略困境,折射出現代化服務在穩定性與可維護性之間的深層博弈。通過剖析Log4j2異步日志機制的內在原理,我們識別出隊列積壓導致線程阻塞的關鍵癥結,并由此展開對日志治理體系的深度重構。

??本次優化方案突破傳統日志分級思維的桎梏,創新性地提出雙軌制日志管理體系:將日志劃分為功能型與診斷型兩類,前者確保核心業務脈絡的持續可見,后者實現按需動態管控。通過編譯期字節碼增強技術,我們實現代碼行級別的精準控制,配合IDE插件的可視化操作,使開發人員能夠像調試斷點般自由啟停日志輸出。這種"外科手術式"的日志管理,既避免了傳統方案"一刀切"的弊端,又賦予系統在高負載場景下的彈性適應能力。

關于作者:蔡夢輝 平臺技術部后端

責任編輯:武曉燕 來源: 轉轉技術
相關推薦

2023-07-10 09:53:59

console開發插件

2022-09-17 08:10:20

HSV飽和度圖像

2022-01-06 14:05:07

Vue代碼前端

2022-08-31 15:57:11

程序員

2018-09-10 09:18:30

程序員領導加班

2023-06-14 09:41:32

2010-05-20 10:47:23

周鴻祎

2020-10-23 07:43:37

Log配置性能

2024-03-11 15:27:41

開發前端

2021-05-28 11:18:50

MySQLbin logredo log

2019-08-12 10:27:34

前端程序員網絡

2013-10-31 15:52:11

2022-05-10 07:24:19

PythonCollection模塊

2025-02-12 10:36:06

2021-06-15 06:56:17

安卓系統應用手機卡頓

2020-05-09 08:09:36

中臺阿里平臺

2024-06-11 00:00:02

MySQL數據庫系統

2022-08-09 15:38:55

Linux

2015-12-30 10:36:59

2021-04-21 07:53:12

Java限流器管理
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 中文字幕亚洲视频 | 国产精品一区在线观看 | 国产成人jvid在线播放 | 完全免费在线视频 | 黄色av网站在线观看 | 日韩免费av一区二区 | 国产精品一区在线观看 | 欧美福利精品 | 亚洲精品视频免费 | 欧美黄色一区 | 91精品国产91久久久久游泳池 | www.日韩系列 | 国产在线一区二区三区 | 综合久久综合久久 | 国产免费让你躁在线视频 | 亚洲 欧美 日韩 在线 | 午夜视频一区二区 | 国产日韩欧美电影 | 国产精品成人69xxx免费视频 | 91久久久久久久久 | 亚洲视频一区二区三区 | 国产伦精品一区二区三区精品视频 | 欧美精品成人一区二区三区四区 | 久久91 | 91精品一区二区三区久久久久久 | 在线看av网址 | 久久精品av麻豆的观看方式 | 国产99精品 | av电影一区 | 久久99视频精品 | 日韩在线一区二区 | 免费午夜视频在线观看 | 亚洲精品日韩在线 | 久久日本 | 国产欧美精品一区 | 不卡一二区 | 日韩在线电影 | 亚洲一区综合 | 怡红院成人在线视频 | 热re99久久精品国产99热 | 在线观看www |