Go http 监听器,每秒更新一次数据

标签 go

我正在尝试用 Go 构建一个小网站,其中包含基于从网络服务收集的数据的报告。它使用 API 来查询服务中的数据。该服务只能每隔几秒查询一次。

但是,我必须多次查询才能获得完整的报告数据。现在,我只是在每次调用 http 处理程序 (http.HandleFunc) 时敲击 API 来更新我的整个数据结构。当然,这很糟糕,因为它会触发对受到限制的外部 API 的大量查询。所以,我的报告来得非常非常非常慢。

我想做的是拥有一个以非阻塞方式 updateReportData 的函数,并将该数据存储在 http.HandleFunc() 可以直接摄取而无需调用外部 API 的某个变量中。

但是,我对 Go(以及闭包、信号量、并发等)非常陌生,所以我不太确定如何构建它。我应该使用 channel 吗?我应该使用计时器吗?如何让 updateReportData 不阻塞 http.HandleFunc,但仍按固定间隔运行?

总而言之,我希望有一个后台例程以固定的时间间隔更新数据结构,并且我希望能够在我发出 http 请求时使用 http.HandleFunc 来提供数据结构中的任何数据该程序。我只是不知道如何开始。任何建议将不胜感激。

最佳答案

您需要做一些事情:

  1. 创建轮询数据的后台服务。该服务可以作为定期检查新数据的 goroutine 运行。
  2. 创建一个 channel ,后台服务使用该 channel 将新数据发送到集中位置来存储值。每当后台服务发现新内容时,就应将数据写入此 channel 。另一种选择是使用互斥锁来保护集中式数据存储。根据数据写入和读取的方式,其中一个选项将是更好的选择。
  3. 创建一个返回集中式数据存储的当前内容的 HTTP 处理程序。

这是一个简化的示例,展示了如何使用 goroutine 和 sync.RWMutext 来完成您想要的任务:

package main

import (
    "fmt"
    "net/http"
    "sync"
    "time"
)

var (
    timeSumsMu sync.RWMutex
    timeSums   int64
)

func main() {
    // Start the goroutine that will sum the current time
    // once per second.
    go runDataLoop()
    // Create a handler that will read-lock the mutext and
    // write the summed time to the client
    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        timeSumsMu.RLock()
        defer timeSumsMu.RUnlock()
        fmt.Fprint(w, timeSums)
    })
    http.ListenAndServe(":8080", nil)
}

func runDataLoop() {
    for {
        // Within an infinite loop, lock the mutex and
        // increment our value, then sleep for 1 second until
        // the next time we need to get a value.
        timeSumsMu.Lock()
        timeSums += time.Now().Unix()
        timeSumsMu.Unlock()
        time.Sleep(1 * time.Second)
    }
}

关于Go http 监听器,每秒更新一次数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48483528/

相关文章:

go - 何时关闭 channel

methods - 具有相同名称和数量但类型不同的 Golang 方法

golang将fasthttp替换为gin, slice 边界超出范围运行时错误

java - 在 Golang 中解密在 Java 中加密的内容(没有 iv)

xml - 如何使用 goroutines 解码 XML

Go 模板范围循环引用我的值

Golang Rethinkdb 嵌套过滤器

go - 多路复用器去 :12: can't find import: "github.com/gorilla/context"`

Golang - Visual Studio Code 中的本地导入警告

go - 在 net.DialTCP 中指定本地 IP 地址