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

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()
}