1 consul 下载与初体验
- 下载对应版本的 consul (Mac M1 为例)
https://www.consul.io/downloads
# 查看支持的型号
uname -m
- 配置 consul 到环境变量
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 注册服务
进入配置文件路径 cd /etc/consul.d
创建 json 文件 sudo vim web.json
添加服务信息
{
"service":{
"name":"ad_service",
"tags":["demo","test"],
"port":8080,
"check":{
"id":"api",
"name":"ad_service check",
"http":"http://localhost:8080",
"interval":"5s",
"timeout":"1s"
}
}
}
- 重启consul
- 查看服务
3 consul 与 grpc 结合
3.1 准备工作
- 安装 consul 的包
go get github.com/hashicorp/consul
- 开发流程
1.创建 proto 文件,指定 rpc 服务
2.启动 consul 服务,consul agend -dev
3.启动 server
3.1 获取 consul 对象
3.2 使用 consul对象,将 server 信息注册给 consul
3.3 启动服务
4. 启动client
4.1 获取consul 对象。
4.2 使用consul对象,从consul 上获取健康的服务列表。
4.3 访问服务 (grpc远程调用)
3.2 编码实现
- 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);
}
- server端
package main
import (
"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(®)
//////////////////////以下为 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)
}
- client端
package main
import (
"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)
}
- consul web 服务验证
- 注销服务
package main
import "github.com/hashicorp/consul/api"
func main() {
// 1. 初始化 consul 配置
consuConfig := api.DefaultConfig()
// 2. 创建 consul 对象
consulClient, _ := api.NewClient(consuConfig)
// 3. 注销服务,传入serviceID
consulClient.Agent().ServiceDeregister("userService id")
}
- go mod
module consul_grpc
go 1.16
require (
github.com/golang/protobuf v1.5.2
github.com/hashicorp/consul/api v1.12.0
google.golang.org/grpc v1.47.0
)