英文:
Golang listenUDP multiple ports blocking with BigTable connection
问题
我正在创建一个简单的UDP客户端,它监听多个端口并将请求保存到Bigtable中。
在提问之前,监听不同的端口非常重要。
在我包含Bigtable之前,一切都运行得很好。但是在包含Bigtable之后,监听器完全阻塞。
我简化了没有Bigtable的代码,如下所示:
func flow(port string) {
protocol := "udp"
udpAddr, err := net.ResolveUDPAddr(protocol, "0.0.0.0:"+port)
if err != nil {
fmt.Println("Wrong Address")
return
}
udpConn, err := net.ListenUDP(protocol, udpAddr)
if err != nil {
fmt.Println(err)
}
defer udpConn.Close()
for {
Publish(udpConn, port)
}
}
func main() {
fmt.Print("Starting server.........")
for i := *Start; i <= *End; i++ {
x := strconv.Itoa(i)
go flow(x)
}
}
这段代码运行良好,但是一旦我添加了以下Bigtable的代码,整个程序就会阻塞。如果我删除创建监听器的go例程(这意味着我不能在多个端口上监听),它就能正常工作。
func createBigTable() {
ctx := context.Background()
client, err := bigtable.NewClient(ctx, *ProjectID, *Instance)
if err != nil {
log.Fatal("Bigtable NewClient:", err)
}
Table = client.Open("x")
}
我通过在createBigTable函数中添加一个查询来使其工作,但程序后面仍然会阻塞。
我不知道这是否是Bigtable、gRPC还是我的实现方式的问题。
非常感谢您提供有关如何修复的建议。
--- 更新 ---
我发现问题不仅仅出现在Bigtable上,当我调用gcloud pubsub时也会出现相同的问题。
--- 更新2 ---
createBigtable在init函数中被调用(在主函数之前):
func init() {
createBigTable()
}
--- 更新3 ---
sigquit的输出可以在此处找到:
英文:
I'm creating a simple udp client that listens on multiple ports and saves the request to bigtable.
It's essential to listen on different ports before you ask.
Everything was working nicely until I included bigtable. After doing so, the listeners block completely.
My stripped down code, without bigtable, looks like this:
func flow(port string) {
protocol := "udp"
udpAddr, err := net.ResolveUDPAddr(protocol, "0.0.0.0:"+port)
if err != nil {
fmt.Println("Wrong Address")
return
}
udpConn, err := net.ListenUDP(protocol, udpAddr)
if err != nil {
fmt.Println(err)
}
defer udpConn.Close()
for {
Publish(udpConn, port)
}
}
func main() {
fmt.Print("Starting server.........")
for i := *Start; i <= *End; i++ {
x := strconv.Itoa(i)
go flow(x)
}
}
This works fine however, as soon as I add the following for bigtable, the whole thing blocks. If I remove the go routine that creates the listener (which means I can't listen on multiple ports) it works.
func createBigTable() {
ctx := context.Background()
client, err := bigtable.NewClient(ctx, *ProjectID, *Instance)
if err != nil {
log.Fatal("Bigtable NewClient:", err)
}
Table = client.Open("x")
}
I managed to get it working by adding a query in the createBigTable func but the program still blocks later on.
I have no idea if this is an issue with bigtable, grpc or just the way I'm doing it.
Would really appreciate some advise about how to fix.
--- UPDATE ---
I've discovered the issue isn't just with BigTable - I also have the same issue when I call gcloud pubsub.
--- UPDATE 2 ---
createBigtable is called in the init function (BEFORE THE MAIN FUNCTION):
func init() {
createBigTable
}
--- Update 3 ---
Output from sigquit can be found here:
答案1
得分: 0
在你的示例中,你使用for {}
来使服务器永远运行。这似乎会导致goroutine永远无法运行。尝试使用WaitGroup
来从main()
例程中释放控制权,并让flow()
例程处理传入的UDP数据包。
import (
...
"sync"
...
)
...
func main() {
fmt.Print("Starting server.")
for i := *Start; i <= *End; i++ {
x := strconv.Itoa(i)
go flow(x)
}
var wg sync.WaitGroup
wg.Add(1)
wg.Wait()
}
请注意,这只是一个示例代码片段,你需要根据你的实际需求进行适当的修改。
英文:
In your playground example, you're using for {}
to keep the server running for forever.
This seems to deprive the goroutines from ever getting to run.
Try using e.g. a WaitGroup
to yield control from the main()
routine and let the flow()
routines handle the incoming UDP packets.
import (
...
"sync"
...
)
...
func main() {
fmt.Print("Starting server.")
for i := *Start; i <= *End; i++ {
x := strconv.Itoa(i)
go flow(x)
}
var wg sync.WaitGroup
wg.Add(1)
wg.Wait()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论