Docker 中的 Basic Go RPC 因 SIGSEGV 而失败



我正在尝试使用 Golang 获取一个简单的客户端/服务器 RPC 示例在两个 docker 容器之间运行。

当我在本地计算机上运行它们时,可以完美地构建和运行。 我知道将它们构建到 docker 容器中可能会有一些我需要解决的通信错误,但我什至无法进入那个阶段,因为我在尝试运行我的客户端时遇到了分段错误。

当我运行主(服务器(容器时,它可以工作,没有问题。 但是当我运行工作线程(客户端(时,我得到这个:

panic: runtime error: invalid memory address or nil pointer `   `dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x10 
pc=0x72425d]
goroutine 1 [running]:
net/rpc.(*Client).send(0x0, 0xc0000d61e0)
/usr/local/go/src/net/rpc/client.go:72 +0x3d
net/rpc.(*Client).Go(0x0, 0x7e062d, 0xa, 0x7887e0, 
0xc0000b04a8, 0x788860, 0xb0c440, 0xc0000aa300, 
0xc0000d6190)
/usr/local/go/src/net/rpc/client.go:316 +0xcc
net/rpc.(*Client).Call(...)
/usr/local/go/src/net/rpc/client.go:322
main.main()
/app/worker.go:20 +0x11c
exit status 2

我的师傅:

package main
import (
"fmt"
"net"
"net/http"
"net/rpc"
)
type Args struct {
Addthis int
}
type Reply struct {
Ret int
}
type Api int
func (master *Api) Add(args Args, reply *Reply) error {
out := args.Addthis + 10
reply.Ret = out
return nil
}
func main() {
var master = new(Api)
rpc.Register(master)
rpc.HandleHTTP()
listener, _ := net.Listen("tcp", ":4040")
fmt.Printf("nServing on %dn", 4040)
http.Serve(listener, nil)
}

我的主 Dockerfile:

FROM golang:latest
WORKDIR /app
COPY ./ /app
EXPOSE 4040
ENTRYPOINT go run master.go

我使用以下命令构建和运行主控:

docker build -t master
docker run --net=testnet --name=master master

这工作正常。

我的工人

package main
import (
"fmt"
"net/rpc"
)
type Args struct {
Addthis int
}
type Reply struct {
Ret int
}
func main() {
var reply Reply
client, _ := rpc.DialHTTP("tcp", ":4040")
num := Args{215}
client.Call("master.Add", num, &reply)
fmt.Println("Here")
fmt.Printf("nGot back: %dn", reply.Ret) 
}

我的工作线程 Dockerfile:

FROM golang:latest
WORKDIR /app
COPY ./ /app
EXPOSE 4040
ENTRYPOINT go run worker.go

我使用以下命令构建和运行工作线程:

docker build -t worker .
docker run --net=testnet --name=worker worker

那是我收到上述错误的时候。

谷歌搜索了三个小时,似乎没有任何帮助。 我想我不知道要使用什么搜索。

我知道这实际上可能不会按原样进行通信,但我想调试通信问题,而不是处理分段错误。 代码是由我的教授提供的,不是作为作业的一部分,而只是因为我要求它。 他声称这对他来说没有问题,并且对我的故障排除没有帮助(我不认为他实际上尝试过将其部署在容器中,但我不会打电话给他。 他很"敏感"(。 "尝试堆栈交换!"这是他所说的,真的。

client, _ := rpc.DialHTTP("tcp", ":4040")

这基本上意味着您正在尝试连接到同一容器上的端口 4040,但是,您的主节点在不同的容器中运行。要连接到您的主容器,您需要连接到 docker 自动分配的 {ip:4040}(用于测试(或设置 docker 网络以正确使用容器。

最新更新