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

但是,我必须查询多次才能获得完整的报告数据。现在,我只是在每次调用HTTP处理程序(http.HandleFunc)时都要锤打API来更新整个数据结构。当然,这很不好,因为它会触发对外部API的大量查询,这些查询已受到限制。因此,我的报告非常非常非常缓慢地提出。

我要做的是具有一个以非阻塞方式updateReportData的功能,并将该数据存储在http.HandleFunc()可以在不调用外部API的情况下仅吸收的某些变量中。

但是,我是Go语言的新手(包括闭包,信号量,并发等),因此我不确定如何构建它。我应该使用 channel 吗?我应该使用计时器吗?如何获取updateReportData而不阻止http.HandleFunc,但仍以固定间隔运行?

综上所述,我想有一个后台例程以固定的间隔更新数据结构,并且我希望能够在每次向程序发出http请求时使用http.HandleFunc来提供数据结构中的任何数据。我只是不知道如何开始。任何意见,将不胜感激。

最佳答案

您需要做一些事情:

  • 创建一个轮询数据的后台服务。该服务可以作为goroutine运行,该例程定期检查新数据。
  • 创建一个 channel ,后台服务使用该 channel 将新数据发送到集中位置以存储值。后台服务在发现新内容时应将数据写入此 channel 。另一种选择是使用互斥量保护集中式数据存储。根据数据写入和读取的方式,一个选项将是一个更好的选择。
  • 创建一个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/

    10-11 22:13
    查看更多