国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Go Flight Recorder 終于來了,線上問題可以“回放”了!

開發(fā) 前端
簡單來說,F(xiàn)light Recorder(飛行記錄器)就像是給你的程序裝了個行車記錄儀,出了事故可以回放錄像。比起傳統(tǒng)的 trace 方式,既節(jié)省資源,又能精準定位問題。這個特性在 Go1.25 正式可用了,配合之前幾個版本對 tracing 的優(yōu)化(Go1.21 降低了開銷,Go1.22 改進了 trace 格式),整個診斷工具鏈越來越成熟了。

不知道大家在生產(chǎn)環(huán)境排查問題的時候,有沒有遇到過這樣的窘境:服務突然慢了,等你反應過來想抓個 trace 看看,問題已經(jīng)過去了。就像開車遇到異響,等你停下來檢查,聲音又沒了。

今天給大家分享 Go1.25 的一個重磅特性:Flight Recorder(飛行記錄器)。這玩意兒真的是救命神器,能讓你在問題發(fā)生后,回溯幾秒鐘前的執(zhí)行狀態(tài)。

圖片圖片

背景

先說說為什么需要這個東西。

Go 的 execution trace 功能其實一直都有,通過runtime/trace包就能收集程序執(zhí)行時的各種事件。

這對于調(diào)試延遲問題特別有用,能清楚地看到 goroutine 什么時候在執(zhí)行,更重要的是,什么時候沒在執(zhí)行。

但問題來了。

對于短期運行的程序,比如測試、基準測試或者命令行工具,你可以從頭到尾收集完整的 trace。但對于長期運行的 Web 服務,這就不現(xiàn)實了。服務器可能要運行好幾天甚至幾周,你總不能一直開著 trace 收集數(shù)據(jù)吧?那數(shù)據(jù)量得多恐怖。

更尷尬的是,往往是某個請求超時了,或者健康檢查失敗了,等你意識到問題,想調(diào)用trace.Start()的時候,早就晚了。

有人說,那我隨機采樣不就行了?這個思路是對的,但需要一大堆基礎設施支撐。你得存儲、分類、處理海量的 trace 數(shù)據(jù),而且大部分數(shù)據(jù)其實都沒啥用。更關(guān)鍵的是,當你想排查某個具體問題的時候,這種方式基本幫不上忙。

Flight Recorder 是什么

這就是 Flight Recorder 要解決的問題。

核心思路很簡單:程序通常能感知到出問題了,但根因可能早就發(fā)生了。Flight Recorder 讓你能收集問題發(fā)生前幾秒鐘的 trace 數(shù)據(jù)。

它的工作原理是這樣的:正常收集 trace 數(shù)據(jù),但不是寫到文件或 socket 里,而是在內(nèi)存里緩存最近幾秒的數(shù)據(jù)。

一旦程序檢測到問題,隨時可以把緩沖區(qū)的內(nèi)容快照下來,精準定位到問題窗口。

實戰(zhàn)案例

我們用一個實際例子來看看怎么用。

假設有這么一個 HTTP 服務,實現(xiàn)了一個"猜數(shù)字"的游戲。它暴露了一個/guess-number端點,接收一個整數(shù),告訴調(diào)用者猜得對不對。

同時還有個 goroutine 每分鐘發(fā)送一次統(tǒng)計報告。

核心代碼大概是這樣:

type bucket struct {
    mu      sync.Mutex
    guesses int
}

func main() {
    buckets := make([]bucket, 100)

    // 每分鐘發(fā)送報告
    gofunc() {
        forrange time.Tick(1 * time.Minute) {
            sendReport(buckets)
        }
    }()

    answer := rand.Intn(len(buckets))

    http.HandleFunc("/guess-number", func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()

        guess, err := strconv.Atoi(r.URL.Query().Get("guess"))
        if err != nil || !(0 <= guess && guess < len(buckets)) {
            http.Error(w, "invalid 'guess' value", http.StatusBadRequest)
            return
        }

        b := &buckets[guess]
        b.mu.Lock()
        b.guesses++
        b.mu.Unlock()

        fmt.Fprintf(w, "guess: %d, correct: %t", guess, guess == answer)

        log.Printf("HTTP request: endpoint=/guess-number guess=%d duratinotallow=%s",
            guess, time.Since(start))
    })

    log.Fatal(http.ListenAndServe(":8090", nil))
}

發(fā)送報告的函數(shù)是這樣寫的:

func sendReport(buckets []bucket) {
    counts := make([]int, len(buckets))

    for index := range buckets {
        b := &buckets[index]
        b.mu.Lock()
        defer b.mu.Unlock()

        counts[index] = b.guesses
    }

    b, err := json.Marshal(counts)
    if err != nil {
        log.Printf("failed to marshal report data: error=%s", err)
        return
    }

    url := "http://localhost:8091/guess-number-report"
    if _, err := http.Post(url, "application/json", bytes.NewReader(b)); err != nil {
        log.Printf("failed to send report: %s", err)
    }
}

上線后,用戶開始反饋有些請求特別慢。

看日志發(fā)現(xiàn),大部分請求都是微秒級的,但偶爾會有超過 100 毫秒的:

2025/09/19 16:52:02 HTTP request: endpoint=/guess-number guess=69 duratinotallow=625ns
2025/09/19 16:52:02 HTTP request: endpoint=/guess-number guess=42 duratinotallow=1.417μs
2025/09/19 16:52:02 HTTP request: endpoint=/guess-number guess=86 duratinotallow=115.186167ms
2025/09/19 16:52:02 HTTP request: endpoint=/guess-number guess=0 duratinotallow=127.993375ms

問題來了,能看出哪里有 bug 嗎?

用 Flight Recorder 排查

先別急著看答案,我們用 Flight Recorder 來排查。

首先,在 main 函數(shù)里配置并啟動 recorder:

// 配置Flight Recorder
fr := trace.NewFlightRecorder(trace.FlightRecorderConfig{
    MinAge:   200 * time.Millisecond,
    MaxBytes: 1 << 20, // 1 MiB
})
fr.Start()

這里 MinAge 設置為 200 毫秒,大概是問題窗口的 2 倍。

MaxBytes 限制緩沖區(qū)大小,避免內(nèi)存爆炸。一般來說,每秒會產(chǎn)生幾 MB 的 trace 數(shù)據(jù),繁忙的服務可能達到 10MB/s。

接下來寫個輔助函數(shù)來捕獲快照:

var once sync.Once

func captureSnapshot(fr *trace.FlightRecorder) {
    once.Do(func() {
        f, err := os.Create("snapshot.trace")
        if err != nil {
            log.Printf("opening snapshot file %s failed: %s", f.Name(), err)
            return
        }
        defer f.Close()

        _, err = fr.WriteTo(f)
        if err != nil {
            log.Printf("writing snapshot to file %s failed: %s", f.Name(), err)
            return
        }

        fr.Stop()
        log.Printf("captured a flight recorder snapshot to %s", f.Name())
    })
}

然后在請求處理函數(shù)里,當響應時間超過 100 毫秒時觸發(fā)快照:

if fr.Enabled() && time.Since(start) > 100*time.Millisecond {
    go captureSnapshot(fr)
}

重新運行服務,等到觸發(fā)慢請求,我們就能拿到快照文件了。

分析 trace

拿到 trace 文件后,用 Go 自帶的工具分析:

go tool trace snapshot.trace

這個工具會啟動一個本地 Web 服務器,然后在瀏覽器里打開。點擊"View trace by proc"可以看到時間線視圖。

在這個視圖里,我們能看到 goroutine 的執(zhí)行情況。重點關(guān)注右側(cè)那個巨大的空白期——大概 100 毫秒,啥都沒干!

圖片圖片

放大這個區(qū)域后,可以看到很多 goroutine 都在等待一個特定的 goroutine。點擊這個 goroutine,查看它的棧信息,發(fā)現(xiàn)它在執(zhí)行sendReport函數(shù)。

圖片圖片

再仔細看那些"Outgoing flow"事件,它們都指向了sendReport里的Unlock操作。

圖片圖片

問題找到了!

看這段代碼:

for index := range buckets {
    b := &buckets[index]
    b.mu.Lock()
    defer b.mu.Unlock()

    counts[index] = b.guesses
}

我們本想給每個 bucket 加鎖,拷貝完值就解鎖。但defer的執(zhí)行時機是函數(shù)返回時,不是循環(huán)結(jié)束時。

所以這些鎖一直被持有,直到整個 HTTP 請求完成后才釋放。

這就是典型的 defer 誤用場景。正確的寫法應該是:

for index := range buckets {
    b := &buckets[index]
    b.mu.Lock()
    counts[index] = b.guesses
    b.mu.Unlock()
}

總結(jié)

Flight Recorder 真的是個好東西。它讓我們能在問題發(fā)生后,回過頭去看發(fā)生了什么,而不需要一直開著 trace 收集海量數(shù)據(jù)。

簡單來說,它就像是給你的程序裝了個行車記錄儀,出了事故可以回放錄像。比起傳統(tǒng)的 trace 方式,既節(jié)省資源,又能精準定位問題。

這個特性在 Go1.25 正式可用了,配合之前幾個版本對 tracing 的優(yōu)化(Go1.21 降低了開銷,Go1.22 改進了 trace 格式),整個診斷工具鏈越來越成熟了。

如果你經(jīng)常需要排查生產(chǎn)環(huán)境的性能問題,強烈建議試試這個新特性。

責任編輯:武曉燕 來源: 腦子進煎魚了
相關(guān)推薦

2023-11-02 08:43:08

protocgo兼容

2021-12-13 20:09:33

GoElasticsearJava

2021-07-29 20:29:36

Linux c 代碼Java

2024-07-16 16:53:09

2021-04-19 11:45:31

Pythonswitch編程語言

2021-04-16 15:02:38

Python 開發(fā)編程語言

2025-06-06 08:13:47

2021-08-10 09:02:37

NumPy視圖內(nèi)存

2025-12-19 08:50:04

2021-04-20 08:03:26

單播協(xié)議TCP

2024-08-15 11:37:05

2013-07-12 09:59:58

Android 5.0

2017-04-17 09:01:39

科技新聞早報

2009-10-22 08:50:33

Windows 7上市新聞

2023-05-29 08:38:56

popover控制懸浮層

2025-10-31 09:01:37

2024-03-12 09:10:21

GoarenaAPI

2022-11-08 08:29:43

Goslog 庫工具

2021-01-24 08:20:55

微信微信8.0.1移動應用

2024-07-17 10:16:21

點贊
收藏

51CTO技術(shù)棧公眾號

国产福利不卡| a∨色狠狠一区二区三区| 亚洲国产小视频| 999国产精品视频| 色女孩综合网| 在线国产亚洲欧美| 日韩电影一区| a天堂中文在线官网| 欧美成人精品三级在线观看| 琪琪一区二区三区| 成人福利网站| 精品久久中出| 7777精品伊人久久久大香线蕉| 希岛爱理一区二区三区| 99精品欧美一区二区三区综合在线| yiren22亚洲综合伊人22| 成人免费午夜电影| 色狠狠桃花综合| 亚洲视频高清| 色在线视频网| 咪咪色在线视频| 亚洲精品在线免费观看视频| 性欧美videos另类喷潮| 中文字幕在线播放网址| 日韩欧美在线观看一区二区三区| 亚洲婷婷在线| 久久av色综合| 国产精品333| 欧美一乱一性一交一视频| 亚洲国产美国国产综合一区二区| 黄页网站大全在线观看| 亚洲欧美国内爽妇网| av不卡在线观看| 婷婷精品视频| 超碰免费公开在线| 国产成人a亚洲精v品无码| 97久久精品人搡人人玩| 欧美电影免费观看| 亚洲日本成人| 北岛玲heyzo一区二区| 999精品网站| 不卡区在线中文字幕| 91成人入口| 不卡在线视频| 免费观看国产精品视频| 国产精品久久久久免费a∨| 欧美午夜不卡在线观看免费| 免费一区二区视频| 欧美日韩一区二区三区在线电影| 欧美激情第一页xxx| 一区二区高清视频在线观看| 日韩av一区二区三区四区| 北条麻妃在线一区二区免费播放| 中文字幕一区二区三区四区在线视频| 成人av电影免费| 国产色综合一区| 狠久久av成人天堂| 亚洲资源在线| 国产三级电影在线播放| 性视频在线播放| 热99这里只有精品| 久久久久久精| 国产成人高清激情视频在线观看| 日韩精品在线影院| 亚洲视频免费看| 成人免费高清在线观看| 麻豆网站在线| 国产美女三级视频| 日本一区二区在线| 国产精品视频26uuu| 久久久中精品2020中文| 亚洲精品国产品国语在线| 欧美日韩一区二区电影| 91综合久久爱com| 成人片免费看| 18视频在线观看| 久做在线视频免费观看| 真不卡电影网| 天堂资源在线观看| 影音先锋导航| 快色在线观看| 香蕉521av成人网| 一区二区三区网址| 91av在线免费播放| jizzjizzxxxx| www污污在线| 日韩亚洲不卡在线| 综合色天天鬼久久鬼色| 红桃视频在线观看一区二区| 成人在线视频成人| 黄网站色视频免费观看| 欧美亚州在线观看| yellow中文字幕久久| 成人国产精品av| 国产h视频在线播放| 成人免费网址| 日产午夜精品一线二线三线| 日韩高清在线一区| 亚洲地区一二三色| 美女999久久久精品视频| 日韩动漫在线观看| 黄色一级片在线观看| 精品一区电影| 亚洲欧美中日韩| 色婷婷综合久久久久| 天堂资源在线亚洲资源| 草碰在线视频| 黄色av一区| 欧美系列日韩一区| 亚洲va电影大全| 麻豆传媒在线播放| 一区二区美女| 亚洲免费在线观看视频| 欧美精品videos性欧美| 日本十八禁视频无遮挡| 色综合桃花网| 国产毛片一区二区| 亚洲天堂av在线免费观看| 国产高潮呻吟久久久| 麻豆国产在线| 国产suv一区二区三区88区| 亚洲欧美综合区自拍另类| 国产一二三四区在线观看| 欧美久久久久久| 亚洲人成网址| 欧美成人影院| 国精产品一区一区三区mba视频| 51久久夜色精品国产麻豆| 国产理论在线| 欧美jizz19性欧美| 青青草视频在线观看| 国产伦精品一区二区三区四区视频_| 国产精品亚洲精品| 亚洲精品日韩欧美| 亚洲激情成人在线| 亚洲三级电影网站| 国产亚洲视频系列| 国产精品一区二区在线观看网站| 亚洲人体在线| 好了av在线| 美国一级片在线免费观看视频| 国产69精品久久久久久久| 精品国产无码在线| 国产九色91| y111111国产精品久久婷婷| 国产成人精品在线播放| 久久夜色撩人精品| 91av免费观看91av精品在线| 91麻豆精品国产91久久久久| 国产福利一区二区三区视频 | 日韩精品免费观看视频| 亚洲作爱视频| 日韩一级二级三级| 国产免费亚洲高清| 熟妇人妻无乱码中文字幕真矢织江| 国产欧美日韩91| 国产欧美一区二区三区在线| 这里只有精品视频在线| 在线成人高清不卡| 欧美性猛交xxxx免费看漫画| 91成人免费在线| 亚洲偷欧美偷国内偷| 精品久久久久久乱码天堂| 影音先锋另类| 欧美日韩有码| 图片区日韩欧美亚洲| 国产精品人成电影在线观看| 黑料吃瓜在线观看| 色中色综合网| 91精品国产aⅴ一区二区| 日本一区二区视频| 国产1区2区3区在线| 亚洲男人都懂第一日本| 国产精品成人免费| 国产精品成人aaaaa网站| 伊人发布在线| 久久久久久久久免费| 日韩视频免费中文字幕| 欧美日韩在线一二三| 日本wwwwww| 91超碰免费在线| 亚洲图片小说区| 欧美a级片视频| 另类中文字幕网| 欧美系列在线观看| 日韩欧美资源站| 久久偷看各类女兵18女厕嘘嘘| 亚洲一区二区三区乱码aⅴ| 国产高清视频在线观看| 日本在线不卡一区| 欧美在线视频一区| 亚洲电影视频在线| 老熟妇仑乱视频一区二区| 亚洲免费毛片| 亚洲美女福利视频网站| 中文字幕视频在线免费| 免费一级欧美片在线播放| 欧美激情视频在线观看| 日本三级在线观看网站| 一区二区在线电影|