亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

在 Golang 中設置網絡命名空間后運行 GRPC 時是否有任何已知限制?

在 Golang 中設置網絡命名空間后運行 GRPC 時是否有任何已知限制?

Go
互換的青春 2023-06-12 17:31:25
在我的 Golang 項目中切換網絡名稱空間后,我在 GRPC 客戶端和服務器之間進行通信時遇到問題。為了解決這個問題,我相應地修改了GRPC示例程序Hello World,結果出現了同樣的問題。在 golang 應用程序中切換命名空間后使用 GRPC 時是否有任何已知限制?我已經閱讀了與在 Golang 中切換命名空間相關的問題,但我想這是否會導致問題取決于 GRPC 行為。GRPC 客戶端是否生成任何額外的 goroutines?由于命名空間切換,這樣的 goroutine 不一定會在與原始 goroutine 鎖定線程相同的命名空間中執行。我假設 GRPC 服務器為每個客戶端生成 goroutine,但它是否會在生成新 goroutine 之前在原始 goroutine 中創建套接字?這個問題也與生成的 goroutines 不必在調用 grpc.Serve() 的相同命名空間中執行有關(命名空間切換需要 runtime.LockOSThread())。如果服務器和客戶端在匹配的命名空間(ip netns exec ...)中啟動,則通信有效,但如果在客戶端內部執行命名空間切換,則通信失敗。在服務器內部執行名稱空間切換時通信也有效,因此問題應該在客戶端。greeter_client/main.go:package mainimport (    "fmt"    "log"    "os"    "runtime"    "syscall"    "time"    pb "grpctest/helloworld/helloworld"    "github.com/vishvananda/netns"    "golang.org/x/net/context"    "google.golang.org/grpc")const (    defaultName    = "world"    defaultAddress = "localhost:50051"    nsEnv          = "NAMESPACE"    addressEnv     = "ADDRESS"    blockEnv       = "DIALBLOCK")func main() {    fmt.Printf("* Client thread id before runtime.LockOSThread(): %d\n", syscall.Gettid())    runtime.LockOSThread()    defer runtime.UnlockOSThread()    fmt.Printf("* Client thread id after runtime.LockOSThread(): %d\n", syscall.Gettid())    var dialOpts []grpc.DialOption    dialOpts = append(dialOpts, grpc.WithInsecure())    _, ok := os.LookupEnv(blockEnv)    if ok == true {        dialOpts = append(dialOpts, grpc.WithBlock())        fmt.Printf("* Dial in blocked mode\n")    } else {        fmt.Printf("* Dial in unblocked mode\n")    }    address, ok := os.LookupEnv(addressEnv)    if ok == false {        address = defaultAddress    }    fmt.Printf("* Talk to server at %s\n", address)    var origns netns.NsHandle    namespace, ok := os.LookupEnv(nsEnv)    if ok {        fmt.Printf("* Switch namespace to %s\n", namespace)        origns, err := netns.Get()        if err != nil {            log.Fatal("failed to get current namespace")        }
查看完整描述

1 回答

?
慕雪6442864

TA貢獻1812條經驗 獲得超5個贊

我遇到了完全相同的問題,無論是否鎖定操作系統線程,netns 都會在每個新的 goroutine 上切換回原始名稱空間。


我發現只要服務器在正確的 netns 中啟動(我放棄了嘗試以編程方式執行此操作并只是通過生成服務器進程exec.Command),您只需為 GRPC 客戶端設置自定義撥號程序以在連接到正確的網絡:


dialOpts = append(dialOpts, grpc.WithDialer(func(addr string, timeout time.Duration) (net.Conn, error) {

        netns.Set(newns)

        return net.DialTimeout("tcp", addr, timeout)

    }))


查看完整回答
反對 回復 2023-06-12
  • 1 回答
  • 0 關注
  • 176 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號