当前位置: 代码迷 >> 综合 >> consul 与 grpc 结合实现服务注册发现及远程调用
  详细解决方案

consul 与 grpc 结合实现服务注册发现及远程调用

热度:52   发布时间:2023-09-11 04:58:57.0

1 consul 下载与初体验

  1. 下载对应版本的 consul (Mac M1 为例)
https://www.consul.io/downloads# 查看支持的型号
uname -m
  1. 配置 consul 到环境变量
consul 与 grpc 结合实现服务注册发现及远程调用
image-20220530094156506.png

2 consul 使用

2.1 常用命令解释

consul agent-bind=0.0.0.0           指定 consul 所在机器的IP地址,默认 0.0.0.0-http-port=8500   consul自带的web访问的默认端口:8500-client=127.0.0.1 表面可以访问consul的客户端ip,默认本机。0.0.0.0表示所以机器可访问-config-dir=foo     主动注册服务的配置信息-data-dir=path      存储所以注册的server机器的详细信息-dev                            开发者模式,直接以默认配置启动 consul-node=hostname      服务发现的名称-rejoin                     consul启动后,可加入 consul 集群-server                     以服务方式开启 consul,允许其他 consul 连接到开启server的consul-ui                             使用web页面来查看服务发现的信息

2.2 server 模式启动 consul

# 先创建一下config目录
sudo mkdir /etc/consul.d
# 启动 consul 服务
sudo consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node=n1 -bind=0.0.0.0 -ui -rejoin -config-dir=/etc/consul.d -client 0.0.0.0
# 查看集群的成员信息 或者通过web界面查看 localhost:8500
consul members
# 查看 consul 的信息
consul info
# 重新加载配置文件
consul reload
# 优雅关闭 consul
consul leave

2.3 注册服务

  1. 进入配置文件路径 cd /etc/consul.d

  2. 创建 json 文件 sudo vim web.json

  3. 添加服务信息

{"service":{"name":"ad_service","tags":["demo","test"],"port":8080,"check":{"id":"api","name":"ad_service check","http":"http://localhost:8080","interval":"5s","timeout":"1s"}}
}
  1. 重启consul
  2. 查看服务
consul 与 grpc 结合实现服务注册发现及远程调用
image-20220530103957818.png

3 consul 与 grpc 结合

3.1 准备工作

  1. 安装 consul 的包
go get github.com/hashicorp/consul
  1. 开发流程
1.创建 proto 文件,指定 rpc 服务
2.启动 consul 服务,consul agend -dev
3.启动 server3.1 获取 consul 对象3.2 使用 consul对象,将 server 信息注册给 consul 3.3 启动服务
4. 启动client4.1 获取consul 对象。4.2 使用consul对象,从consul 上获取健康的服务列表。4.3 访问服务 (grpc远程调用)

3.2 编码实现

  1. proto 文件

编译:protoc --go_out=plugins=grpc:./ *.proto

syntax = "proto3";
option go_package = "./;pb";
package pb;
message GetUserInfoReq {int32 user_id = 1;
}
message GetUserInfoRsp {int32 user_id = 1;string user_name = 2;int32 age = 3;
}service UserService {rpc GetUserInfo(GetUserInfoReq) returns (GetUserInfoRsp);
}
  1. server端
package mainimport ("consul_grpc/pb""context""fmt""github.com/hashicorp/consul/api""google.golang.org/grpc""net"
)type UserService struct {
}func (*UserService) GetUserInfo(ctx context.Context, req *pb.GetUserInfoReq) (*pb.GetUserInfoRsp, error) {if req.UserId == 10 {return &pb.GetUserInfoRsp{UserId:   req.UserId,UserName: "yorick_10",Age:      25,}, nil}return &pb.GetUserInfoRsp{UserId:   req.UserId,UserName: "yorick_other",Age:      20,}, nil
}func main() {// 服务注册// 1.初始化 consul 配置consulConfig := api.DefaultConfig()// 2.创建 consul 对象consulClient, _ := api.NewClient(consulConfig)// 3.注册的服务配置reg := api.AgentServiceRegistration{ID:      "userService id",Name:    "userService",Tags:    []string{"consul", "grpc"},Address: "127.0.0.1",Port:    8080,Check: &api.AgentServiceCheck{CheckID:  "consul grpc test",TCP:      "127.0.0.1:8080",Timeout:  "1s",Interval: "5s",},}// 4. 注册 grpc 服务到 consul 上consulClient.Agent().ServiceRegister(&reg)//以下为 grpc 服务远程调用grpcServer := grpc.NewServer()pb.RegisterUserServiceServer(grpcServer, new(UserService))listener, _ := net.Listen("tcp", "127.0.0.1:8080")defer listener.Close()fmt.Println("server start...")grpcServer.Serve(listener)
}
  1. client端
package mainimport ("consul_grpc/pb""context""fmt""github.com/hashicorp/consul/api""google.golang.org/grpc""google.golang.org/grpc/credentials/insecure""strconv"
)func main() {// 服务发现// 1.初始化 consul 配置consulConfig := api.DefaultConfig()// 2.创建 consul 对象consulClient,_ := api.NewClient(consulConfig)// 3.服务发现. 从 consul 上, 获取健康的服务//  参数://  service: 服务名。 -- 注册服务时,指定该string//  tag:外名/别名。 如果有多个, 任选一个//  passingOnly:是否通过健康检查。 true//  q:查询参数。 通常传 nil//  返回值://  ServiceEntry: 存储服务的切片。//  QueryMeta:额外查询返回值。 nil//  error: 错误信息services,_,_ := consulClient.Health().Service("userService","grpc",true,nil)// 4.简单的负载均衡,获取服务地址addr := services[0].Service.Address + ":" + strconv.Itoa(services[0].Service.Port)//以下为 grpc 服务远程调用///grpcConn, _ := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))grpcClient := pb.NewUserServiceClient(grpcConn)req := pb.GetUserInfoReq{UserId: 1}rsp, _ := grpcClient.GetUserInfo(context.Background(), &req)fmt.Println(rsp)
}
  1. consul web 服务验证
consul 与 grpc 结合实现服务注册发现及远程调用
image-20220601094921063.png
  1. 注销服务
package mainimport "github.com/hashicorp/consul/api"func main() {// 1. 初始化 consul 配置consuConfig := api.DefaultConfig()// 2. 创建 consul 对象consulClient, _ := api.NewClient(consuConfig)// 3. 注销服务,传入serviceIDconsulClient.Agent().ServiceDeregister("userService id")
}
  1. go mod
module consul_grpcgo 1.16require (github.com/golang/protobuf v1.5.2github.com/hashicorp/consul/api v1.12.0google.golang.org/grpc v1.47.0
)
  相关解决方案