douxunchen3498 2017-07-02 19:57
浏览 232
已采纳

Golang ListenUDP使用BigTable连接阻止多个端口

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:

https://pastebin.com/fzixqmiA

  • 写回答

1条回答 默认 最新

  • ds78662302 2017-07-09 18:12
    关注

    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()
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么