Golang expvar 包详解
expvar
包在 Go 语言中用于导出变量,允许通过 HTTP 服务这些变量的值。这对于监控和调试应用程序非常有用。
expvar
包提供了一个机制,通过这个机制,可以将 Go 程序中的变量发布到 HTTP 服务上,以便用户可以通过 Web 浏览器或其他工具查看这些变量的值。
以下是使用 expvar
包的一些示例:
- 导出一个简单的变量:
package main
import (
"expvar"
"fmt"
"log"
"net/http"
)
func main() {
counter := expvar.NewInt("counter")
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
counter.Add(1)
fmt.Fprintf(w, "Hello, you've requested this %d times\n", counter.Value())
})
go http.ListenAndServe(":8080", nil)
log.Fatal(http.ListenAndServe(":8081", nil))
}
在上面的代码中,我们创建了一个名为 counter
的 expvar.Int
类型的变量,并将其初始值设置为 0。然后,我们通过 /
路径将其绑定到 HTTP 服务上。每当有请求发送到根路径时,counter
的值就会增加 1。
- 导出一个更复杂的变量:
package main
import (
"expvar"
"log"
"net/http"
"sync"
)
func main() {
http.Handle("/vars", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json; charset=utf-8")
var mu sync.RWMutex
mu.RLock()
firstRequest := expvar.Do(func(kv expvar.KeyValue) {
_, _ = w.Write([]byte(`"` + kv.Key + `":`))
_ = kv.Value.Write(w)
_, _ = w.Write([]byte(","))
})
mu.RUnlock()
w.Write([]byte(`{"time":"` + time.Now().Format(time.RFC3339) + `"}`))
if firstRequest {
w.Write([]byte(" -- first request"))
}
}))
log.Fatal(http.ListenAndServe(":8080", nil))
}
在上面的代码中,我们使用 expvar.Do
函数遍历所有已发布的变量,并将它们以 JSON 格式输出到 HTTP 响应中。此外,我们还添加了一个自定义变量 time
,它包含当前的请求时间。
注意:在实际的生产环境中,你应该使用更安全的方式来处理 HTTP 响应写入,并且应该考虑到并发访问导致的竞态条件等问题。
评论已关闭