python 微服务 etcd_使用 go-micro用etcd接入微服务,版本冲突解决

内容纲要

报错提示

使用go-micro分布式系统开发框架,通过etcd管理服务,基于gRPC的微服务,编译报错如下,

../lib/pb/publisher.basic.pb.go:225:7: undefined: grpc.ClientConnInterface

../lib/pb/publisher.basic.pb.go:229:11: undefined: grpc.SupportPackageIsVersion6

../lib/pb/publisher.basic.pb.go:240:5: undefined: grpc.ClientConnInterface

../lib/pb/publisher.basic.pb.go:243:22: undefined: grpc.ClientConnInterface

环境

github.com/golang/protobuf v1.4.2

github.com/micro/go-micro/v2 v2.9.0

google.golang.org/grpc v1.26.0

google.golang.org/grpc v1.27.0

Makefile

build:

protoc --proto_path=./proto/ --micro_out=./pb/ --go_out=./pb/ --go_opt=plugins=grpc,paths=source_relative proto/publisher.basic.proto

protoc --proto_path=./proto/ --micro_out=./pb/ --go_out=./pb/ --go_opt=plugins=grpc,paths=source_relative proto/publisher.rpc.proto

原因分析

protoc-gen-go 是 https://github.com/golang/protobuf 项目下的一个golang工具,请见https://github.com/golang/protobuf/tree/master/protoc-gen-go

go get 安装的 protoc-gen-go 是最新版本,我们通过MakeFile文件,make build生成 pd.go文件,grpc下的一些方法是在grpc类库找不到的。

通过查看go.mod,google.golang.org/grpc v1.26.0

升级到 1.27.0,解决了protoc编译出来pb.go文件与 google.golang.org/grpc 不兼容问题。

产生了新的问题,etcd 和 grpc v1.27.0 产生冲突,表明不支持grpc这么高版本。

github.com/coreos/etcd@v3.3.18+incompatible... undefined: resolver.BuildOption

github.com/coreos/etcd@v3.3.18+incompatible... undefined: resolver.ResolveNowOption

protoc –grpc-gateway_out= 生成出来的 pb.go 代码需要 grpc 1.27.0,而 etcd 需要 grpc 1.26.0

解决方案

那么在go.mod内添加一个模块的两个版本,

google.golang.org/grpc v1.26.0

google.golang.org/grpc v1.27.0

还原 grpc 到 1.26.0,protoc-gen-go 降级

github.com/golang/protobuf v1.4.2 降级到 1.3.2

go get -u -v github.com/golang/protobuf/protoc-gen-go@v1.3.2

技术总结

理解这几个类库设计目的和定位

梳理清楚go-micro\etcd框架、编译Protobuf文件、gRPC相互依赖的版本

尽量控制在最新稳定版本,版本不要最新,也不要太旧

Protobuf 类库和版本规范

The github.com/golang/protobuf module is the original Go protocol buffer API.

The google.golang.org/protobuf module is an updated version of this API designed for simplicity, ease of use, and safety. The flagship features of the updated API are support for reflection and a separation of the user-facing API from the underlying implementation.

gogoprotobuf is a fork of golang/protobuf with extra code generation features.

当前版本优先使用

proto3

google.golang.org/protobuf/proto

参考资料

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Etcd是一个高可用的键值存储系统,用于分布式系统中的服务发现和配置共享。而gRPC则是一种高性能、开源和通用的RPC框架,可以在任何环境中连接多种语言开发的应用程序。将EtcdgRPC结合起来,可以实现高效的微服务治理。 在Python中,可以使用etcd3库与Etcd进行通信,使用grpc库实现gRPC服务。具体实现步骤如下: 1. 安装etcd3和grpc库 ```sh pip install etcd3 grpcio grpcio-tools ``` 2. 启动Etcd服务 可以使用Docker容器启动Etcd服务: ```sh docker run --rm -p 2379:2379 -p 2380:2380 --name etcd quay.io/coreos/etcd:v3.3.8 /usr/local/bin/etcd --advertise-client-urls http://0.0.0.0:2379 --listen-client-urls http://0.0.0.0:2379 --listen-peer-urls http://0.0.0.0:2380 ``` 3. 编写服务代码 首先,定义.proto文件,声明gRPC服务: ```protobuf syntax = "proto3"; package helloworld; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; } ``` 然后,使用grpc_tools.protoc工具生成Python代码: ```sh python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. helloworld.proto ``` 编写服务实现代码: ```python import grpc import helloworld_pb2 import helloworld_pb2_grpc class Greeter(helloworld_pb2_grpc.GreeterServicer): def SayHello(self, request, context): return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name) server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server) server.add_insecure_port('[::]:50051') server.start() server.wait_for_termination() ``` 最后,编写Etcd服务注册和发现代码: ```python import etcd3 class EtcdRegistry(object): def __init__(self, etcd_host, etcd_port, service_name, service_addr): self.etcd = etcd3.client(host=etcd_host, port=etcd_port) self.service_name = service_name self.service_addr = service_addr self.lease_id = None def register(self, ttl=10): self.lease_id = self.etcd.lease(ttl) self.etcd.put('/{}/{}/{}'.format(self.service_name, self.service_addr, self.lease_id), str(self.service_addr), lease=self.lease_id) self.etcd.refresh_lease(self.lease_id) def unregister(self): if self.lease_id: self.etcd.revoke_lease(self.lease_id) ``` 在服务启动时,调用register()方法注册服务,停止时调用unregister()方法注销服务。 最后,通过Etcd的watch方法,实现服务发现: ```python import etcd3 class EtcdDiscovery(object): def __init__(self, etcd_host, etcd_port, service_name): self.etcd = etcd3.client(host=etcd_host, port=etcd_port) self.service_name = service_name def watch(self): for event in self.etcd.watch_prefix('/{}'.format(self.service_name)): if event.event_type == 'PUT': yield event.key.decode(), event.value.decode() ``` 在客户端中,调用watch()方法监听服务节点的变化,获取可用的服务列表。 以上就是将EtcdgRPC应用于Python微服务的基本步骤。通过Etcd提供的服务注册和发现功能,可以实现高效的微服务治理,提高微服务的可用性和稳定性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值