微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

我的Docker容器中的gRPC客户端不起作用,但容器外部的客户端运行良好

如何解决我的Docker容器中的gRPC客户端不起作用,但容器外部的客户端运行良好

Envs

$ protoc --version
libprotoc 3.7.1

$ docker-compose --version
docker-compose version 1.22.0,build f46880fe

$ docker --version
Docker version 20.10.0-beta1,build ac365d7

我想做什么

我想做一个由gin-gonic实现的微服务。

代码

$ tree
.
├── api
│   ├── Dockerfile
│   ├── go.mod
│   ├── go.sum
│   ├── main.go
│   ├── pb
│   │   ├── proto
│   │   │   └── user.proto
│   │   ├── user_grpc.pb.go
│   │   └── user.pb.go
│   └── services
│       ├── README.md
│       └── user
│           ├── Dockerfile
│           ├── go.mod
│           ├── go.sum
│           ├── main.go
│           └── pb
│               ├── user_grpc.pb.go
│               └── user.pb.go
├── docker-compose.yml
├── make_pb.sh
└── README.md

您可以看到我现在有2个Dockerfile。
api目录中的dockefile运行gRPC客户端程序。
用户目录中的另一个Dockerfile运行gRPC服务器程序。

api / main.go

package main

import (
    "context"
    "log"
    "os"
    "time"

    pb "github.com/Asuha-a/URLShortener/api/pb"
    "google.golang.org/grpc"
)

const (
    address     = "localhost:50051"
    defaultName = "world"
)

func main() {
    hello()
    //r := gin.Default()
    //r.GET("",hello)
    //r.Run()
}

func hello() {
    log.Println(grpc.WithBlock())
    conn,err := grpc.Dial(address,grpc.WithInsecure(),grpc.WithBlock())
    if err != nil {
        log.Fatalf("did not connect: %v",err)
    }
    defer conn.Close()
    client := pb.NewGreeterClient(conn)

    // Contact the server and print out its response.
    name := defaultName
    if len(os.Args) > 1 {
        name = os.Args[1]
    }
    ctx,cancel := context.WithTimeout(context.Background(),time.Second)
    defer cancel()
    r,err := client.SayHello(ctx,&pb.HelloRequest{Name: name})
    if err != nil {
        log.Fatalf("Could not greet: %v",err)
    }
    log.Printf("Greeting: %s",r.GetMessage())
}

api / services / user / main.go

package main

import (
    "context"
    "log"
    "net"

    pb "github.com/Asuha-a/URLShortener/api/services/user/pb"
    "google.golang.org/grpc"
)

const (
    port = ":50051"
)

// server is used to implement helloworld.GreeterServer.
type server struct {
    pb.UnimplementedGreeterServer
}

// SayHello implements helloworld.GreeterServer
func (s *server) SayHello(ctx context.Context,in *pb.HelloRequest) (*pb.HelloReply,error) {
    log.Printf("Received: %v",in.GetName())
    return &pb.HelloReply{Message: "Hello " + in.GetName()},nil
}

func main() {
    log.Println("Now listening")
    lis,err := net.Listen("tcp",port)
    if err != nil {
        log.Fatalf("Failed to listen: %v",err)
    }
    s := grpc.NewServer()
    pb.RegisterGreeterServer(s,&server{})
    if err := s.Serve(lis); err != nil {
        log.Fatalf("Failed to serve: %v",err)
    }
}

docker-compose.yml

version: '3'

services:
  gateway:
    build:
      context: ./api/
      dockerfile: Dockerfile
    ports:
      - 8080:8080
    tty:
      true
    depends_on:
      - user
  user:
    build:
      context: ./api/services/user
      dockerfile: Dockerfile
    ports:
      - 50051:50051
    tty:
      true

Dockerfile具有相同的代码

FROM golang:latest

RUN mkdir /go/src/work
workdir /go/src/work
ADD . /go/src/work

CMD go run main.go

发生了什么

当我运行docker-compose up时,grpc.Dial似乎不起作用。

日志在这里

$ docker-compose up              
Recreating urlshortener_user_1 ... done
Recreating urlshortener_gateway_1 ... done
Attaching to urlshortener_user_1,urlshortener_gateway_1
user_1     | go: downloading google.golang.org/grpc v1.33.1
user_1     | go: downloading google.golang.org/protobuf v1.25.0
user_1     | go: downloading github.com/golang/protobuf v1.4.3
gateway_1  | go: downloading google.golang.org/grpc v1.33.1
gateway_1  | go: downloading github.com/golang/protobuf v1.4.3
gateway_1  | go: downloading google.golang.org/protobuf v1.25.0
user_1     | go: downloading google.golang.org/genproto v0.0.0-20201028140639-c77dae4b0522
user_1     | go: downloading golang.org/x/net v0.0.0-20201029055024-942e2f445f3c
gateway_1  | go: downloading google.golang.org/genproto v0.0.0-20201026171402-d4b8fe4fd877
gateway_1  | go: downloading golang.org/x/net v0.0.0-20201027133719-8eef5233e2a1
gateway_1  | go: downloading golang.org/x/sys v0.0.0-20201027140754-0fcbb8f4928c
user_1     | go: downloading golang.org/x/sys v0.0.0-20201029020603-3518587229cd
user_1     | go: downloading golang.org/x/text v0.3.4
gateway_1  | go: downloading golang.org/x/text v0.3.4
user_1     | 2020/10/29 08:29:42 Now listening
gateway_1  | 2020/10/29 08:29:43 true

这应该印有“问候:你好,世界”。

我尝试过的

当我运行没有容器的服务器和客户端时,它成功了。

运行客户端

$ go run main.go 
2020/10/29 17:37:17 true
2020/10/29 17:38:02 Greeting: Hello world

运行服务器

$ go run main.go 
2020/10/29 17:38:00 Now listening
2020/10/29 17:38:02 Received: world

当我在没有容器的情况下运行服务器并在有容器的情况下运行客户端时,失败了。

运行客户端

$ docker-compose up              
Recreating urlshortener_gateway_1 ... done
Attaching to urlshortener_gateway_1
gateway_1  | go: downloading google.golang.org/protobuf v1.25.0
gateway_1  | go: downloading github.com/golang/protobuf v1.4.3
gateway_1  | go: downloading google.golang.org/grpc v1.33.1
gateway_1  | go: downloading google.golang.org/genproto v0.0.0-20201026171402-d4b8fe4fd877
gateway_1  | go: downloading golang.org/x/net v0.0.0-20201027133719-8eef5233e2a1
gateway_1  | go: downloading golang.org/x/sys v0.0.0-20201027140754-0fcbb8f4928c
gateway_1  | go: downloading golang.org/x/text v0.3.4
gateway_1  | 2020/10/29 08:40:47 true

运行服务器

$ go run main.go
2020/10/29 17:40:19 Now listening

当我与客户端一起运行服务器并且在没有容器的情况下运行客户端时,它成功了。

运行客户端

$ go run main.go 
2020/10/29 17:43:40 true
2020/10/29 17:43:41 Greeting: Hello world

运行服务器

$ docker-compose up
Removing urlshortener_user_1
Recreating 42fb18da11cf_urlshortener_user_1 ... done
Attaching to urlshortener_user_1
user_1  | go: downloading google.golang.org/grpc v1.33.1
user_1  | go: downloading google.golang.org/protobuf v1.25.0
user_1  | go: downloading github.com/golang/protobuf v1.4.3
user_1  | go: downloading golang.org/x/net v0.0.0-20201029055024-942e2f445f3c
user_1  | go: downloading google.golang.org/genproto v0.0.0-20201028140639-c77dae4b0522
user_1  | go: downloading golang.org/x/sys v0.0.0-20201029020603-3518587229cd
user_1  | go: downloading golang.org/x/text v0.3.4
user_1  | 2020/10/29 08:43:41 Now listening
user_1  | 2020/10/29 08:43:41 Received: world

我想知道的事情

为什么在容器中运行客户端失败?
如何解决

解决方法

此评论解决了问题。

容器中的本地主机与服务器运行的位置不同。 – 14分钟前,马特(Matt)

我修复了api / main.go。

address = "localhost:50051" -> address = "user:50051"

现在可以使用了。
主机名必须是在docker-compose.yml中指定的容器名称。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。