1 consul 下載與初體驗
- 下載對應(yīng)版本的 consul (Mac M1 為例)
https://www.consul.io/downloads
# 查看支持的型號
uname -m
- 配置 consul 到環(huán)境變量

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 主動注冊服務(wù)的配置信息
-data-dir=path 存儲所以注冊的server機器的詳細信息
-dev 開發(fā)者模式,直接以默認配置啟動 consul
-node=hostname 服務(wù)發(fā)現(xiàn)的名稱
-rejoin consul啟動后,可加入 consul 集群
-server 以服務(wù)方式開啟 consul,允許其他 consul 連接到開啟server的consul
-ui 使用web頁面來查看服務(wù)發(fā)現(xiàn)的信息
2.2 server 模式啟動 consul
# 先創(chuàng)建一下config目錄
sudo mkdir /etc/consul.d
# 啟動 consul 服務(wù)
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
# 優(yōu)雅關(guān)閉 consul
consul leave
2.3 注冊服務(wù)
進入配置文件路徑 cd /etc/consul.d
創(chuàng)建 json 文件 sudo vim web.json
添加服務(wù)信息
{
"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
- 查看服務(wù)

image-20220530103957818.png
3 consul 與 grpc 結(jié)合
3.1 準備工作
- 安裝 consul 的包
go get github.com/hashicorp/consul
- 開發(fā)流程
1.創(chuàng)建 proto 文件,指定 rpc 服務(wù)
2.啟動 consul 服務(wù),consul agend -dev
3.啟動 server
3.1 獲取 consul 對象
3.2 使用 consul對象,將 server 信息注冊給 consul
3.3 啟動服務(wù)
4. 啟動client
4.1 獲取consul 對象。
4.2 使用consul對象,從consul 上獲取健康的服務(wù)列表。
4.3 訪問服務(wù) (grpc遠程調(diào)用)
3.2 編碼實現(xiàn)
- 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() {
// 服務(wù)注冊
// 1.初始化 consul 配置
consulConfig := api.DefaultConfig()
// 2.創(chuàng)建 consul 對象
consulClient, _ := api.NewClient(consulConfig)
// 3.注冊的服務(wù)配置
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 服務(wù)到 consul 上
consulClient.Agent().ServiceRegister(®)
//////////////////////以下為 grpc 服務(wù)遠程調(diào)用////////////////////////
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() {
// 服務(wù)發(fā)現(xiàn)
// 1.初始化 consul 配置
consulConfig := api.DefaultConfig()
// 2.創(chuàng)建 consul 對象
consulClient,_ := api.NewClient(consulConfig)
// 3.服務(wù)發(fā)現(xiàn). 從 consul 上, 獲取健康的服務(wù)
// 參數(shù):
// service: 服務(wù)名。 -- 注冊服務(wù)時,指定該string
// tag:外名/別名。 如果有多個, 任選一個
// passingOnly:是否通過健康檢查。 true
// q:查詢參數(shù)。 通常傳 nil
// 返回值:
// ServiceEntry: 存儲服務(wù)的切片。
// QueryMeta:額外查詢返回值。 nil
// error: 錯誤信息
services,_,_ := consulClient.Health().Service("userService","grpc",true,nil)
// 4.簡單的負載均衡,獲取服務(wù)地址
addr := services[0].Service.Address + ":" + strconv.Itoa(services[0].Service.Port)
//////////////////////以下為 grpc 服務(wù)遠程調(diào)用///////////////////////////
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 服務(wù)驗證

image-20220601094921063.png
- 注銷服務(wù)
package main
import "github.com/hashicorp/consul/api"
func main() {
// 1. 初始化 consul 配置
consuConfig := api.DefaultConfig()
// 2. 創(chuàng)建 consul 對象
consulClient, _ := api.NewClient(consuConfig)
// 3. 注銷服務(wù),傳入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
)