【发布时间】:2021-08-03 19:58:17
【问题描述】:
我正在使用 gRPC 开发一个项目,并且最近将其迁移到让每个服务都在 Docker 容器中运行(值得补充的是,我对容器化还很陌生)。今天,在将我的一个 Go 服务移动到容器中时,我遇到了这个错误,并且已经尝试解决它几个小时,但没有成功。我得到的错误是:
“rpc 错误:代码 = 未实现的 desc = 未知服务 PowerEstimationServicePackage”
我在网上四处查看,似乎该错误虽然描述性不强,但通常意味着您的客户端正在进行的服务调用尚未由服务器在端口上注册。我现在花了几个小时查看我的代码,但我一生都无法弄清楚为什么会出现错误 - 据我所知,我已经正确注册了它!
此外,当我在本地运行 Go 服务时,它运行良好!这让我相信这个问题与我在 Docker 中运行时的端口绑定有关。我觉得我对 Docker 如何处理网络有一个合理的理解,但很可能在这里忽略了一些东西。
相关的客户端代码(本地运行)是:
const {
addrEstimationSP = "127.0.0.1:50101"
}
// Use this to implement the power estimation service routing
type estimationServer struct {
serverPB.UnimplementedPowerEstimationServicesServer
}
func main {
// Create a connection over the specified tcp port
callCounter := interceptors.ClientMetricStruct{}
connEstimationSP := CreateInsecureServerConnection(addrEstimationSP, timeoutDuration, callCounter.ClientMetrics)
/* Create the client and pass the connection made above to it. After the client has been
created, we create the gRPC request */
InfoLogger.Println("Creating clients")
clientEstimationSP := estimationPB.NewPowerEstimationServicePackageClient(connEstimationSP)
DebugLogger.Println("Succesfully created the clients")
requestMessageEstimationSP := estimationPB.ServicePackageRequestMessage{
InputFile: INPUTfilename,
ModelType: estimationPB.ModelTypeEnum_OPENWATER,
}
estimationContext, _ := context.WithTimeout(context.Background(), callTimeoutDuration)
responseEstimationSP, errEstimationSP := clientEstimationSP.PowerEstimatorService(estimationContext, &requestMessageEstimationSP)
if errEstimationSP != nil {
ErrorLogger.Println("Failed to make EstimationSP service call: ")
ErrorLogger.Println(errEstimationSP)
} else {
DebugLogger.Println("Succesfully made service call to GoLang EstimationSP.")
connEstimationSP.Close()
}
responseMessage := serverPB.PowerEstimationResponse{
PowerEstimate: responseEstimationSP.PowerEstimate,
}
}
,服务器端的相关代码(这是我试图移入 Docker 的服务)是:
var (
// Addresses
addrMyself = os.Getenv("POWERESTIMATIONHOST") + ":50101"
)
// server is used to implement PowerEstimationServicePackage
type server struct {
serverPB.UnimplementedPowerEstimationServicePackageServer
}
func main() {
InfoLogger.Println("Started GoLang Aggregator")
// Create a listener on the specified tcp port
listener, err := net.Listen("tcp", addrMyself)
if err != nil {
ErrorLogger.Fatalf("Failed to listen on port %v: \n%v", addrMyself, err)
}
InfoLogger.Println("Listeneing on port: ", addrMyself)
// Create a gRPC server object
estimationServer := grpc.NewServer()
// Attach the power estimation service to the server
serverPB.RegisterPowerEstimationServicePackageServer(estimationServer, &server{})
// Start the server
if err := estimationServer.Serve(listener); err != nil {
ErrorLogger.Fatalf("Failed to expose service: \n%v", err)
}
}
func (s *server) PowerEstimatorService(ctx context.Context, request *serverPB.ServicePackageRequestMessage) (*serverPB.EstimateResponseMessage, error) {
...
}
客户端能够创建与服务器的连接,但在调用 clientEstimationPB.PowerEstimatorService(...) 时出现错误。该服务在 Docker 网络中运行,因此为其地址传递环境变量。 Dockerfile 和 Docker-compose 文件如下所示:
Dockerfile:
FROM golang:alpine
# Install git.
# Git is required for fetching the dependencies.
RUN apk add --no-cache git
WORKDIR $GOPATH/src/github.com/nicholasbunn/masters/
# Create a program logs folder in the service directory
RUN mkdir ./program\ logs
RUN mkdir -p $GOPATH/src/github.com/nicholasbunn/masters/src/powerEstimationSP
COPY /src/powerEstimationSP/go.mod ./src/powerEstimationSP
COPY /src/powerEstimationSP/go.sum ./src/powerEstimationSP
# Copy over contents into image
COPY src/powerEstimationSP/interceptors/ ./src/powerEstimationSP/interceptors
COPY src/powerEstimationSP/proto/ ./src/powerEstimationSP/proto
COPY certification/ certification
COPY src/powerEstimationSP/powerEstimationSP.go ./src/powerEstimationSP
COPY src/powerEstimationSP/powerEstimationSP_test.go ./src/powerEstimationSP
COPY src/fetchDataService/proto src/fetchDataService/proto
COPY src/prepareDataService/proto src/prepareDataService/proto
COPY src/estimateService/proto src/estimateService/proto
WORKDIR $GOPATH/src/github.com/nicholasbunn/masters//src/powerEstimationSP/
# Fetch the dependecies
RUN go mod tidy
# Build the binary. for grpc gateway
RUN go build -o ./powerEstimationSP .
WORKDIR $GOPATH/src/github.com/nicholasbunn/masters/
EXPOSE 50101
ENTRYPOINT ["./src/powerEstimationSP/powerEstimationSP"]
Docker-compose.yaml:
version: "3.8"
services:
...
powerestimationsp:
build:
context: .
dockerfile: src/powerEstimationSP/Dockerfile
environment:
POWERESTIMATIONHOST: powerestimationsp
FETCHHOST: fetchservice
PREPAREHOST: prepareservice
ESTIMATEHOST: estimateservice
PROMETHEUSHOST: prometheus
image: power_estimation_sp
networks:
- southernOcean
ports:
- 50101:50101
networks:
southernOcean:
我觉得解决这个问题真的很简单,可能只是我的一个小误解,我刚刚度过了阴天的一天,所以希望一双新鲜的眼睛可以在这里提供帮助。
谢谢!
【问题讨论】:
标签: docker docker-compose grpc grpc-go