consul服务发现(grpc)

1.consul安装

安装

Consul v1.15.2 Binaries | HashiCorp Releases

解压

unzip consul_1.15.2_linux_amd64.zip

 

查看帮助信息

 

启动

consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node=n1 -bind=192.168.188.201 -ui -rejoin -config-dir=/etc/consul.d/ -client 0.0.0.0

 

 

2.代码演示

目录结构如下

新建个项目grpc-consul,再这之下新建个目录chitchat,再这之下新建client,proto,server

 

grpc基础调用

proto包下新建helloworld.proto

//指定版本 默认版本2
syntax = "proto3";

// 指定等会文件生成出来的package
package server;

//代码生成目录
option go_package = "grpc-consul/chitchat/proto";

service SayService{
    //rpc服务的函数名 (传人参数)返回(返回参数)
    //一元调用
    rpc SayHello(SayRequest) returns(SayResponse){}
}

//定义消息
message SayRequest{
    string name = 1;
    string msg = 5;
}

message SayResponse{
    string msg = 5;
}

生成代码

protoc --go_out=. --go_opt=paths=source_relative --go-grpc_out=. --go-grpc_opt=paths=source_relati
ve .\chitchat\proto\helloworld.proto

 

下载缺失依赖

go mod tidy

 

在server包下新建server.go

package main

import (
    "context"
    "google.golang.org/grpc"
    "grpc/chitchat/proto"
    "log"
    "net"
)

func main() {
    //tcp监听9090
    listen, err := net.Listen("tcp", "localhost:9090")
    if err != nil {
        log.Fatal("出现错误", err)
        return
    }
    newServer := grpc.NewServer()
    proto.RegisterSayServiceServer(newServer, &server{})
    log.Printf("server listen : %d", listen.Addr())
    err = newServer.Serve(listen)
    if err != nil {
        log.Fatal(err)
    }
}

type server struct {
    proto.UnimplementedSayServiceServer
}

func (server) SayHello(ctx context.Context, in *proto.SayRequest) (*proto.SayResponse, error) {
    log.Printf("服务端接收到 : %v\n", in)
    return &proto.SayResponse{
        Msg: "Hello client , This is server!",
    }, nil
}

一个简单的一元调用服务端代码,不再阐述。

同样在client包下新建client.go

代码如下:

package main

import (
    "context"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    "grpc/chitchat/proto"
    "log"
)

func main() {
    //建立与服务器的连接
    connect, err := grpc.Dial("localhost:9090", grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        log.Fatal(err)
        return
    }
    defer connect.Close()
    //创建客户端对象 client
    client := proto.NewSayServiceClient(connect)
    sayHello(client)

}

func sayHello(client proto.SayServiceClient) {
    //创建一个上下文对象 ctx
    ctx := context.Background()
    sayRequest := &proto.SayRequest{
        Name: "Dreams",
        Msg: "Hello server , This is client!",
    }
    sayHello, err := client.SayHello(ctx, sayRequest)
    if err != nil {
    log.Fatal(err)
        return
    }
    log.Println("客户端接收到 :", sayHello.Msg)
}

一个简单的grpc客户端,,不再阐述。

运行如下:

 

consul注册

导入consul

go get github.com/hashicorp/consul/api

 

新建chitchat/consul/grpc_consul.go

package consul

import (
    "github.com/hashicorp/consul/api"
    "log"
)

func GetConsulRegister(ID, Name, Address string, Port int) {
    config := api.DefaultConfig()
    config.Address = "192.168.188.201:8500"
    client, err := api.NewClient(config)
    if err != nil {
       log.Fatal(err)
    }

    // 健康检查设置
    check := &api.AgentServiceCheck{
        //存放本机ip地址,不能写localhost,否则consul就一直检测的是consul安装的主机ip地址
        TCP: "********:9090",
        Interval: "10s",
    }
    registration := api.AgentServiceRegistration{
        ID: ID,
        Name: Name,
        Address: Address,
        Port: Port,
        Check: check,
    }

    err = client.Agent().ServiceRegister(&registration)
    if err != nil {
        log.Fatal(err)
    }

}

api.DefaultConfig()用于创建一个默认的 Consul 客户端配置对象

api.NewClient() 用于创建一个连接到 Consul 的客户端对象。该函数接受一个 api.Config 对象作为参数,并返回一个连接到 Consul 的客户端。

api.AgentServiceRegistration 是 Consul Go 库中的一个结构体,用于定义要注册到 Consul 上的服务的信息。

api.AgentServiceCheck 是 Consul Go 库中的一个结构体,用于定义服务的健康检查方式。

client.Agent().ServiceRegister(&registration) 用于将服务注册信息发送到 Consul Agent 进行注册。

 

修改server代码,添加注册consul

func main() {
    //tcp监听9090
    listen, err := net.Listen("tcp", "localhost:9090")
    if err != nil {
        log.Fatal("出现错误", err)
        return
    }
    newServer := grpc.NewServer()
    proto.RegisterSayServiceServer(newServer, &server{})
    log.Printf("server listen : %d", listen.Addr())

    //服务注册进consul
    consul.GetConsulRegister("hello", "hello-server", "localhost", 9090)

    err = newServer.Serve(listen)

    if err != nil {
       log.Fatal(err)
    }
}

 

 

运行可以看到成功

 

 

 

consul发现

grpc_consul.go下新建GetConsulDiscover

func GetConsulDiscover() (string, error) {
    // 创建 Consul 客户端连接
    config := api.DefaultConfig()
    config.Address = "192.168.188.201:8500"
    client, err := api.NewClient(config)
    if err != nil {
        return "", err
    }

    // 查询 Consul 中的服务实例
    services, _, err := client.Catalog().Service("hello-server", "", nil)
    if err != nil {
        return "", err
    }

    if len(services) == 0 {
        return "", errors.New("没有发现该服务!")
    }

    // 返回第一个服务实例的地址和端口
    service := services[0]
    address := fmt.Sprintf("%s:%d", service.ServiceAddress, service.ServicePort)
    return address, nil
}

client.Catalog().Service() 是 Consul 的 Go 客户端库中的一个方法,用于查询 Consul 中特定服务的实例。

同样可以使用另一个方法:client.Health().Service() 用于查询指定服务的健康检查状态。

如下:

func GetConsulDiscover() (string, error) {
    // 创建 Consul 客户端连接
    config := api.DefaultConfig()
    config.Address = "192.168.188.201:8500"
    client, err := api.NewClient(config)
    if err != nil {
        return "", err
    }

    // 查询 Consul 中的服务实例
    services,_, err := client.Health().Service("hello-server", "", true, nil)
    if err != nil {
        return "", err
    }

    // 返回第一个服务实例的地址和端口
    service := services[0].Service
    address := fmt.Sprintf("%s:%d", service.Address, service.Port)
    return address, nil
}

 

 

在client.go修改main函数,调用发现函数

func main() {

    addr, err := consul.GetConsulDiscover()
    if err != nil {
        log.Fatal(err)
        return
    }

    //建立与服务器的连接
    connect, err := grpc.Dial(addr, grpc.WithTransportCredentials(insecure.NewCredentials()))
    if err != nil {
        log.Fatal(err)
        return
    }
    defer connect.Close()
    //创建客户端对象 client
    client := proto.NewSayServiceClient(connect)
    sayHello(client)

}

 

成功运行如下

服务注销

简单调用一下ServiceDeregister函数即可

func GetConsuldel(ID string,) {
    config := api.DefaultConfig()
    //config.Address = "192.168.188.201:8500"
    client, err := api.NewClient(config)
    if err != nil {
        log.Fatal(err)
    }
    err = client.Agent().ServiceDeregister(ID)
    if err != nil {
        log.Fatal(err)
    }
}

暂无评论

发送评论 编辑评论

|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇