consul 與 grpc 結(jié)合實現(xiàn)服務(wù)注冊發(fā)現(xiàn)及遠程調(diào)用

1 consul 下載與初體驗

  1. 下載對應(yīng)版本的 consul (Mac M1 為例)
https://www.consul.io/downloads

# 查看支持的型號
uname -m
  1. 配置 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ù)

  1. 進入配置文件路徑 cd /etc/consul.d

  2. 創(chuàng)建 json 文件 sudo vim web.json

  3. 添加服務(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"
    }
  }
}
  1. 重啟consul
  2. 查看服務(wù)
image-20220530103957818.png

3 consul 與 grpc 結(jié)合

3.1 準備工作

  1. 安裝 consul 的包
go get github.com/hashicorp/consul
  1. 開發(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)

  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 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(&reg)

    //////////////////////以下為 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)
}
  1. 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)
}
  1. consul web 服務(wù)驗證
image-20220601094921063.png
  1. 注銷服務(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")
}
  1. 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
)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容