我正在尝试使用Golang获取在两个docker容器之间运行的简单客户端/服务器RPC示例。
当我在本地计算机上运行它们时,它们都可以完美构建和运行。我知道将它们构建到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
我的master.go:
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 %d\n", 4040)
http.Serve(listener, nil)
}
我的主Dockerfile:
FROM golang:latest
WORKDIR /app
COPY ./ /app
EXPOSE 4040
ENTRYPOINT go run master.go
我使用以下命令构建并运行master:
docker build -t master
docker run --net=testnet --name=master master
这很好。
我的worker.go
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: %d\n", 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
就是当我遇到上述错误时。
[Google搜索了三个小时,似乎没有任何帮助。我想我不知道该使用什么搜索。
我知道这实际上可能不会按原样进行通信,但是我想调试通信问题,而不是处理分段错误。该代码不是由我的教授提供的,而是我要求的。他声称这对他来说没有问题,并且对我的疑难解答没有帮助(我认为他实际上没有尝试将其部署在容器中,但我不会拒绝他。他很“敏感”)。 “尝试交换堆栈!”是他所说的,真的。
client, _ := rpc.DialHTTP("tcp", ":4040")
这基本上意味着您正在尝试连接到同一容器上的端口4040,但是,您的主服务器正在其他容器中运行。要连接到主容器,您需要连接到{ip that docker has assigned automatically:4040}(用于测试)或setup your docker network以正确使用容器。