
本文介绍如何在 Go 语言中实现一个定时轮询任务,该任务能够定期抓取 URL 列表的内容,并允许在运行时动态添加新的 URL 到列表中。我们将使用 Goroutine 和 Channel 来实现并发安全,确保在添加 URL 的同时,轮询任务能够及时更新 URL 列表。
Go 语言定时轮询任务:动态更新 URL 列表
在 Go 语言中,实现定时轮询任务并动态更新 URL 列表,需要考虑并发安全和数据同步问题。以下提供一种基于 Goroutine 和 Channel 的解决方案。
核心结构体:harvester
我们定义一个 harvester 结构体,用于管理 URL 列表的轮询和更新:
type harvester struct { ticker *time.Ticker // 定时器 add chan string // 新 URL 通道 urls []string // 当前 URL 列表}
ticker: time.Ticker 用于触发定时任务。add: chan string 用于接收新增的 URL。urls: []string 存储需要轮询的 URL 列表。
创建 harvester 实例:newHarvester
newHarvester 函数负责创建 harvester 实例并启动后台 Goroutine:
func newHarvester() *harvester { rv := &harvester{ ticker: time.NewTicker(time.Minute * 30), // 每 30 分钟触发一次 add: make(chan string), } go rv.run() return rv}
time.NewTicker(time.Minute * 30) 创建一个每 30 分钟触发一次的定时器。make(chan string) 创建一个用于接收 URL 的 Channel。go rv.run() 启动一个 Goroutine 执行 run 方法。
轮询和更新逻辑:run 方法
run 方法是 harvester 的核心逻辑,负责定时轮询 URL 列表并处理新增 URL:
func (h *harvester) run() { for { select { case <-h.ticker.C: // 当定时器触发时,开始轮询 for _, u := range h.urls { harvest(u) // 实际抓取 URL 内容的函数 } case u := <-h.add: // 接收到新的 URL,添加到 URL 列表 h.urls = append(h.urls, u) } }}
select 语句用于同时监听定时器和 Channel。case case u :=
添加 URL:AddURL 方法
AddURL 方法用于向 harvester 添加新的 URL:
func (h *harvester) AddURL(u string) { // 将新的 URL 发送到 Channel h.add <- u}
通过将 URL 发送到 h.add Channel,可以安全地将新的 URL 添加到列表中,而无需担心并发问题。
示例代码
package mainimport ( "fmt" "time")type harvester struct { ticker *time.Ticker // periodic ticker add chan string // new URL channel urls []string // current URLs}func newHarvester() *harvester { rv := &harvester{ ticker: time.NewTicker(time.Minute * 1), // for test, change to 30 minutes add: make(chan string), urls: []string{"http://example.com", "http://google.com"}, //init urls } go rv.run() return rv}func (h *harvester) run() { for { select { case <-h.ticker.C: // When the ticker fires, it's time to harvest for _, u := range h.urls { harvest(u) } case u := <-h.add: // At any time (other than when we're harvesting), // we can process a request to add a new URL h.urls = append(h.urls, u) fmt.Println("add new url:", u) } }}func (h *harvester) AddURL(u string) { // Adding a new URL is as simple as tossing it onto a channel. h.add <- u}func harvest(url string) { fmt.Println("harvesting url:", url) //Download the current contents of the URL and do something with it time.Sleep(time.Second * 1) //simulate network request}func main() { h := newHarvester() time.Sleep(time.Second * 5) // wait for init harvesting h.AddURL("http://baidu.com") time.Sleep(time.Second * 65) //wait for next harvesting}
注意事项
harvest 函数需要根据实际需求实现,负责抓取 URL 内容并进行处理。错误处理:在 harvest 函数中,需要处理网络请求可能出现的错误。资源释放:在程序退出时,需要停止定时器 h.ticker.Stop() 并关闭 Channel close(h.add),防止资源泄漏。可以根据实际情况调整定时器的时间间隔。如果需要移除 URL,可以添加一个 remove Channel,并在 run 方法中处理移除逻辑。
总结
通过使用 Goroutine 和 Channel,我们可以实现一个并发安全的定时轮询任务,并能够动态更新 URL 列表。这种方法避免了使用锁,提高了程序的性能和可维护性。 这种模式可以扩展到其他需要定时执行任务并动态更新配置的场景。
以上就是Go 语言定时轮询任务:动态更新 URL 列表的详细内容,更多请关注创想鸟其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1413765.html
微信扫一扫
支付宝扫一扫