как использовать etcd для обнаружения служб?

Я новичок в etcd
моя цель - следовать
1. служба регистрируется после запуска службы
2. клиент находит службу и вызывает службу

следующий код показывает тест, как найти сервис и вызвать его

func ClientTestService() {
    cli, err := clientv3.New(clientv3.Config{
        Endpoints:   []string{endpoint},
        DialTimeout: time.Second * 5,
    })

    if err != nil {
        log.Println("connect etcd err:", err.Error())
        return
    }

    defer cli.Close()
    r := &naming.GRPCResolver{Client: cli}
    b := grpc.RoundRobin(r)

    conn, err := grpc.Dial(service_name, grpc.WithBalancer(b), grpc.WithInsecure())
    if err != nil {
        log.Println("dial err:", err.Error())
        return
    }

    defer conn.Close()
    c := calc.NewCalcClient(conn)
    req := calc.CalcRequest{IResult: 1, SResult: "req"}
    resp, err := c.CalcResult(context.Background(), &req)
    if err != nil {
        log.Println("calc err:", err)
        return
    }
    log.Println(resp.IResult, resp.SResult)
}

вывод консоли "calc err: ошибка rpc: код = недоступное описание = нет доступного адреса" после выполнения resp, err := c.CalcResult(context.Background(), &req)
это означает, что преобразователь не может найти адрес службы по имени службы
я думаю, есть два возможно
1. сначала нужно запустить службу вызова etcd "прокси-служба" или "шлюз"
2. необходимо получить адрес службы из имени службы вручную

следующий код показывает службу регистрации

func RegisterService(w *sync.WaitGroup) {
    w.Add(1)
    defer func() {
        w.Done()
    }()

    cli, err := clientv3.New(clientv3.Config{
        Endpoints:   []string{endpoint},
        DialTimeout: time.Second * 5,
    })

    if err != nil {
        log.Println("etcd err:", err)
        return
    }

    cli.Delete(cli.Ctx(), service_name)
    r := &naming.GRPCResolver{Client: cli}
    for _, addr := range GetLocalAddrs() {
        service_node := addr + ":" + strconv.Itoa(port)
        err = r.Update(cli.Ctx(), service_name, gn.Update{Op: gn.Add, Addr: service_node})
        log.Println("register node :", service_name, service_node, err)
    }
}

Насколько я понимаю, функция «ClientTestService» подключает сервер etcd и разрешает имя службы в адрес службы и вызывает службу по балансу
, но когда я отлаживаю этот код, а затем нахожу его, просто вызываю etcd по балансу, есть ли функция в etcd для моего необходимость ?


person tfzxyinhao    schedule 26.04.2017    source источник
comment
У меня такая же проблема. Ошибка возникает, когда клиентский код вызывает метод сервера. Вот что я получил из журнала etcd: 2017-08-13 20:04:22.571628 I | etcdserver/api/v3rpc: transport: http2Server.HandleStreams failed to read frame: read tcp 127.0.0.1:2379->127.0.0.1:49150: read: connection reset by peer]   -  person Steven Ferrer    schedule 13.08.2017
comment
@srxf Это etcd v3.2 в оконной системе из-за ошибки, вы можете использовать последнюю версию etcd   -  person tfzxyinhao    schedule 15.08.2017
comment
я использую последнюю версию etcd v3.2.5, работающую на x64 Ubuntu Linux Box. ты уже заработал?   -  person Steven Ferrer    schedule 16.08.2017
comment
@srxf да, у меня это отлично работает   -  person tfzxyinhao    schedule 17.08.2017
comment
может быть я что-то упустил, буду очень признателен, если поделитесь кодом :)   -  person Steven Ferrer    schedule 17.08.2017
comment
@srxf, в содержании вопроса есть код, в моем коде нет проблем, просто ошибка etcd вызывает эту проблему   -  person tfzxyinhao    schedule 17.08.2017


Ответы (1)


Попробуйте добавить grpc.WithBlock() для Dial, например:

grpc.Dial(service_name, grpc.WithBalancer(b), grpc.WithInsecure(), grpc.WithBlock() )
person Elvin.Du    schedule 17.07.2017