go tool trace goalng調優工具

來源:互聯網
上載者:User
這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。

你想知道你的Go程式在做什麼嗎?  go tool trace 可以向你揭示:Go程式運行中的所有的運行時事件。 這種工具是Go生態系統中用於診斷效能問題時(如延遲,並行化和競爭異常)最有用的工具之一。 在我之前的 部落格文章 中,我提到我們在Pusher中使用 go tool trace 來跟蹤為何Go垃圾收集器有很長的停頓時間。 在這篇博文中,我更加深入的介紹 go toll trace 。

go tool trace 試用

go tool trace 可以顯示大量的資訊,所以從哪裡開始是個問題。 我們首先簡要介紹使用介面,然後我們將介紹如何尋找具體問題。

go tool trace UI是一個Web應用程式。 下面我已經嵌入了一個這個web程式的執行個體!  此樣本 是可視化並行快速排序實現的追蹤資訊:

請嘗試這個例子!有關導航UI的協助,請單擊右上方的“?”。單擊螢幕上的任何事件可以在下面擷取更多資訊。這裡有一些你可以從這個追蹤中找到的有價值的資訊:

  • 這個程式運行多長時間?

  • 有多少goroutines運行872微秒?

  • 該進程何時第一次升級到使用三個OS線程?

  • 什麼時候主要調用qSortPar?

  • 是什麼導致額外的過程(1,2和3)開始工作?

  • proc#2什麼時候停止?

太棒了! 我應該怎麼在我的程式中使用 go tool trace ?

您必須調整程式以將運行時事件寫入二進位檔案。 這涉及從標準庫匯入 runtime/trace ,並添加幾行樣板代碼。 這個快速的視頻將引導您:

視頻

以下是需要複製粘貼的代碼:

package mainimport (    "os"    "runtime/trace")func main() {    f, err := os.Create("trace.out")    if err != nil {       panic(err)    }    defer f.Close()    err = trace.Start(f)     if err != nil { panic(err)    }    defer trace.Stop()      // Your program here}

這將使您的程式以 二進位格式 在檔案trace.out中寫入事件數目據。 然後可以運行 go tool trace trace.out 。 這將解析追蹤檔案,並使用可視化程式開啟瀏覽器。 該命令還將啟動伺服器,並使用跟蹤資料來響應可視化操作。 在瀏覽器中載入初始頁面後,單擊“View trace”。 這將載入跟蹤查看器,如上面嵌入的那樣。

使用go tool trace能解決什麼問題?

我們來看一個如何使用這個工具跟蹤典型問題的例子。

診斷延遲問題

當完成關鍵任務的goroutine被阻止運行時,可能會引起延遲問題。 可能的原因有很多:做系統調用時被阻塞; 被共用記憶體阻塞(通道/互斥等); 被runtime系統(例如GC)阻塞,甚至可能發送器不像您想要的那樣頻繁地運行關鍵goroutine。

所有這些都可以使用 go tool trace 來識別。 您可以通過查看PROCs時間軸來跟蹤問題,並發現一段時間內goroutine被長時間阻塞。 一旦你確定了這段時間,應該給出一個關於根本原因的線索。

作為延遲問題的一個例子,讓我們看看上一篇博文中 長時間的GC暫停 :

紅色的事件代表了唯一的程式goroutine正在運行。 在所有四個線程上並行啟動並執行goroutines是垃圾收集器的MARK階段。 這個MARK階段阻止了主要的goroutine。 你能出到阻止runtime.main goroutine的時間長短嗎?

在Go團隊宣布GC暫停時間少於100微秒後 ,我很快就調查了這個延遲問題。 我看到的漫長的停頓時間, go tool trace 的結果看起來很奇怪,特別是可以看到它們(暫停)是在收集器的並發階段發生的。  我在go-nuts 郵件清單中提到了這個問題 ,似乎與 這個問題 有關,現在已經在Go 1.8中修複了。 我的基準測試又出現了 另一個GC暫停問題 ,這在寫本文時依然會出現。 如果沒有 go tool trace 這一工具,我是無法完成調查工作的。

診斷並行問題

假設您已經編寫了一個程式,您希望使用所有的CPU,但運行速度比預期的要慢。 這可能是因為您的程式不像您所期望的那樣並行運行。 這可能是由於在很多關鍵路徑上串列運行太多,而很多代碼原本是可以非同步(並行)啟動並執行。

假設我們有一個pub/sub訊息匯流排,我們希望在單個goroutine中運行,以便它可以安全地修改沒有加互斥鎖的使用者map。 請求處理常式將訊息寫入訊息匯流排隊列。 匯流排從隊列中讀取訊息,在map中尋找訂閱者,並將訊息寫入其通訊端。 讓我們看看單個訊息的 go tool trace 中的內容:

最初的綠色事件是http處理常式讀取發布的訊息並將其寫入訊息匯流排事件隊列。 之後,訊息匯流排以單個線程運行 - 第二個綠色事件 - 將訊息寫給訂閱者。

紅線顯示訊息寫入訂戶的通訊端的位置。 寫入所有訂閱者的過程需要多長時間?

問題是四分之一的線程正在閑置。 有沒有辦法利用它們? 答案是肯定的 我們不需要同步寫入每個使用者; 寫入可以在單獨的goroutine中同時運行。 讓我們看看如果我們作出這個變化,會發生什麼:

正如你所看到的,寫給訂閱者訊息的過程正在許多goroutines的上同步進行。

但它是否更快?

有趣的是,鑒於我們使用4X的CPU,加速是適合的。 這是因為並行運行代碼有更多的開銷:啟動和停止goroutines; 共用記憶體以及單獨的緩衝。 加速的理論上限使得我們無法實現4倍延遲降低: 阿姆達爾定律 。

實際上,並行運行代碼往往效率較低; 特別是在goroutine是非常短暫的,或者他們之間有很多的競爭的情況下。 這是使用此工具的另一個原因:嘗試這兩種方法,並檢查哪種工作最適合您的用例。

什麼時候 go tool trace 不合適?

當然, go tool trace 不能解決一切問題。 如果您想跟蹤運行緩慢的函數,或者找到大部分CPU時間花費在哪裡,這個工具就是不合適的。 為此,您應該使用 go tool pprof ,它可以顯示在每個函數中花費的CPU時間的百分比。  go tool trace 更適合於找出程式在一段時間內正在做什麼,而不是總體上的開銷。 此外,還有“view trace”連結提供的其他可視化功能,這些對於診斷爭用問題特別有用。 瞭解您的程式在理論上的表現(使用老式Big-O分析)也是無可替代的。

希望這篇文章可以讓您瞭解如何使用 go tool trace 診斷問題。 即使您沒有解決具體問題,可視化您的程式是檢查程式運行時特性的好方法。 我在這篇文章中使用的例子很簡單,但更複雜的程式中的癥狀應該與此驚人的相似。

這個部落格文章給了你一個使用 go tool trace 的介紹,但你可能希望更深入地深入瞭解該工具。 目前進行中的 官方 go tool trace 文檔 相當稀少。 有一個 Google文檔 更詳細。 除此之外,我發現參考原始碼是很有用,可以找出 go tool trace 如何工作:

  • go tool trace 原始碼

  • 二進位跟蹤解析器的原始碼

  • trace 原始碼

  • go tool trace 的Web介面來自 Catapult項目的跟蹤查看器 。 該查看器可以從許多跟蹤格式產生可視化。 go工具跟蹤使用 基於JSON 的跟蹤事件格式。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.