为了账号安全,请及时绑定邮箱和手机立即绑定

如何让 Go 应用程序等待数据在 Redis 列表中可用?

如何让 Go 应用程序等待数据在 Redis 列表中可用?

Go
慕尼黑8549860 2021-09-27 16:39:00
我有一个使用Radix Redis 客户端的 Go 应用程序。它的工作是作为后台进程运行并等待 Redis 列表将项目添加到其中进行处理。背景(可以随意跳过):我有一个 Node.js Web 应用程序,它需要从已知至少需要一整秒或更长时间才能响应的外部 API 请求数据。数据不是立即需要的,所以我让 Node 应用程序向 Redis 列表添加一个项目,然后继续处理重要的内容。同时,我有一个 Go 应用程序,它应该在幕后运行,并在每次发现项目已添加到列表时做一些工作。现在它只是一个main连接到 Redis 并使用 RedisBRPOP命令检查列表中是否包含项目的函数(因为我希望 Redis 在等待作业时阻塞)。运行程序会导致建立连接,然后...如果列表中有一个项目,Go 应用程序会处理它,但它需要如果列表中没有项目,则 Go 应用程序将退出我需要 Go 应用程序只是坐在那里等待新项目,我真的不想求助于轮询,尤其是因为 BRPOP 和 BLPUSH 命令是专门制作的,因此应用程序不需要轮询。我目前的解决方案是创建一个无限循环,永远一遍又一遍地运行 BRPOP 命令。这感觉像是错误的方法。到目前为止,这是整个程序(我是 Go 的新手,但不是编程的新手,所以不要笑得太厉害):package mainimport (  "fmt"  "github.com/fzzy/radix/redis")func main() {  client, err := redis.Dial("tcp", "localhost:6379")  if err != nil {    fmt.Println("An error message just for debug purposes")  } else {    // Here I check to make sure the server is responding    ping := client.Cmd("PING")    fmt.Println(ping) // Just to be sure I'm doing things right    for {      fmt.Println("Looking for a new Q item...")      workItem, err := client.Cmd("BRPOP", "q:test").Str()      if err != nil {        fmt.Println("No error, " + workItem)      }    }  }}那么让 Go 应用程序等待数据在 Redis 列表中可用的正确方法是什么?更新:根据一些评论,我将进一步解释我的期望和正在发生的事情。我对阻塞 Redis 命令的理解是它只会暂停调用它的程序,直到它有东西要返回。因此,在我的情况下,当在队列中没有项目的情况下运行程序时,程序会打印:Looking for a new Q item...No error, 它无限地打印上述内容,这是有道理的,因为我有一个永无止境的 for 循环,但是因为我使用了阻塞命令,所以我希望它的行为更像是一个推。我希望循环只是暂停并等待队列中有一个项目,然后再进行下一次迭代。我担心它会在没有队列项的情况下继续循环,因为最终该进程将开始不必要地消耗资源并减慢 Redis 由于不断涌现的BRPOP命令(尽管它是一个阻塞命令)。所以我想现在新的问题是 - 有没有更好的方法让 Go 程序在等待 Redis 列表(或我的临时队列)中的新项目时保持运行?- 以当前形式运行该程序是否会消耗比应有的更多资源和/或降低 Redis 性能?解决了感谢@JimB 关于“您忽略的错误...”的问题,我再次查看了代码以确保我没有遗漏一些明显的内容。我是:原来在我的循环中我切换了错误和成功处理代码。所以每次出错时,我都会向控制台打印一条成功消息,这样我就可以看到程序内部发生了什么。切换代码并正确处理错误后,我发现我调用的BRPOP参数太少了。我修复了代码,现在循环会一直挂在那里,直到列表中有东西要处理。我想我一直都做对了。但是,如果对性能或更好的方法有任何意见或建议,我仍然会听到并且很乐意听到它们。
查看完整描述

1 回答

?
qq_遁去的一_1

TA贡献1725条经验 获得超7个赞

我切换了错误和成功处理程序。我给 BRPOP 命令的参数太少了。循环中的这段代码修复了它:


// We now import "log" now as well

// Inside the for loop...

if err != nil {

  log.Fatal(err) // This alerted me to the wrong # of arguments issue

} else {

  fmt.Println("No error to be had " + workItem) // Will not print until there is an item in the list

}


查看完整回答
反对 回复 2021-09-27
  • 1 回答
  • 0 关注
  • 202 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信