[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示

这篇具有很好参考价值的文章主要介绍了[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. GRPC微服务集群概念

上一节讲解了consul集群: [golang 微服务] 5. 微服务服务发现介绍,安装以及consul的使用,Consul集群,这样的话,当一台server挂掉之后,集群就会从另一台server中获取服务,这就保证了客户端访问consul集群的负载均衡性. 这里还有一个问题: 就是当终端的对应的 微服务挂掉了,consul集群server就不能访问对应的微服务了,这个怎么办呢?这就引入了 GRPC微服务集群, 那什么是GRPC微服务集群呢?
把一个GRPC微服务部署到多台不同的服务器上的功能,就叫 GRPC微服务集群, 这样当 其中一个微服务挂掉后 ,consul就会访问另外服务器上对应的微服务,从而实现 微服务的负载均衡
[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示
GRPC微服务集群主要实现的是 微服务的负载均衡,实现同样的微服务部署在不同的服务器的功能,结合Consul搭建GRPC微服务集群非常简单:
  • 同一个微服务的不同应用使用同样的注册名

  • 同一个微服务的不同应用注册服务的时候使用不同的ID

[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示

下面通过代码展示来更进一步了解微服务集群

二.代码展示

  1. 注销相关服务

在consul ui上查看是否存在goods服务,如果有,则先注销之前的goods服务,代码见 [golang 微服务] 5. 微服务服务发现介绍,安装以及consul的使用,Consul集群,注销后就没有对应的微服务了,界面展示如下:
[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示

点击client-1进入,查看里面的服务,发现服务没有了

[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示
  1. 进行微服务集群的部署

以goods微服务举例,把server/goods部署到2台服务器上,修改main.go中代码,以示区分不同服务器的同一个微服务
比如:把goods部署到一台192.168.1.111上,main.go代码如下:
package main

import (
    "context"
    "fmt"
    "github.com/hashicorp/consul/api"
    "goods/proto/goodsService"
    "net"
    "google.golang.org/grpc"
    "strconv"
)

//rpc远程调用的接口,需要实现goods.proto中定义的Goods服务接口,以及里面的方法
//1.定义远程调用的结构体和方法,这个结构体需要实现GoodsServer的接口

type Goods struct{}

//GoodsServer方法参考goods.pb.go中的接口
/*
// GoodsServer is the server API for Goods service.
type GoodsServer interface {
    // 通过rpc来指定远程调用的方法:
    // AddGoods方法:增加商品, 这个方法里面实现对传入的参数AddGoodsReq, 以及返回的参数AddGoodsRes进行约束
    AddGoods(context.Context, *AddGoodsReq) (*AddGoodsRes, error)
    // 获取商品列表: GetGoodsReq 参数可为空, 返回参数GetGoodsRes是一个商品相关的切片
    GetGoods(context.Context, *GetGoodsReq) (*GetGoodsRes, error)
}
*/
//增加商品数据
func (this Goods) AddGoods(c context.Context, req *goodsService.AddGoodsReq) (*goodsService.AddGoodsRes, error) {
    fmt.Println(req)
    //模拟返回操作,正式项目在这里进行数据库的操作即可,根据操作结果,返回相关数据
    return &goodsService.AddGoodsRes{
        Message: "第一个goods微服务-增加数据成功",
        Success: true,
    }, nil
}

//获取商品列表
func (g Goods) GetGoods(c context.Context, req *goodsService.GetGoodsReq) (*goodsService.GetGoodsRes, error) {
    //  GoodsList []*GoodsModel
    var tempList []*goodsService.GoodsModel  //定义返回的商品列表切片
    //模拟从数据库中获取商品的请求,循环结果,把商品相关数据放入tempList切片中
    for i := 0; i < 10; i++ {
        tempList = append(tempList, &goodsService.GoodsModel{
            Title:   "商品" + strconv.Itoa(i),  // strconv.Itoa(i): 整型转字符串类型
            Price:   float64(i),  //float64(i): 强制转换整型为浮点型
            Content: "测试商品内容" + strconv.Itoa(i),
        })
    }
    return &goodsService.GetGoodsRes{
        GoodsList: tempList,
    }, nil
}

func main() {
    //------------------------- consul服务相关----------------------
    //注册consul服务
    //1、初始化consul配置
    consulConfig := api.DefaultConfig()
    //设置consul服务器地址: 默认127.0.0.1:8500, 如果consul部署到其它服务器上,则填写其它服务器地址
    consulConfig.Address = "192.168.1.132:8500"
    //2、获取consul操作对象
    consulClient, _ := api.NewClient(consulConfig)
    // 3、配置注册服务的参数
    agentService := api.AgentServiceRegistration{
        ID:      "1",  // 服务id,顺序填写即可
        Tags:    []string{"goods"},  // tag标签
        Name:    "GoodsService",  //服务名称, 注册到服务发现(consul)的K
        Port:    8080, // 端口号: 需要与下面的监听, 指定 IP、port一致
        Address: "192.168.1.111",  // 当前微服务部署    地址: 结合Port在consul设置为V: 需要与下面的监听, 指定 IP、port一致
        Check: &api.AgentServiceCheck{  //健康检测
            TCP:      "192.168.1.111:8080",  //前微服务部署地址,端口 : 需要与下面的监听, 指定 IP、port一致
            Timeout:  "5s",  // 超时时间
            Interval: "30s",  // 循环检测间隔时间
        },
    }

    //4、注册服务到consul上
    consulClient.Agent().ServiceRegister(&agentService)

    //1. 初始一个 grpc 对象
    grpcServer := grpc.NewServer()
    //2. 注册服务
    //helloService.RegisterGoodsServer(grpcServer, &Goods{})
    // &Hello{}和 new(Hello)相同
    goodsService.RegisterGoodsServer(grpcServer, new(Goods))
    //3. 设置监听, 指定 IP、port
    listener, err := net.Listen("tcp", "192.168.1.111:8080")
    if err != nil {
        fmt.Println(err)
    }
    // 4退出关闭监听
    defer listener.Close()
    //5、启动服务
    grpcServer.Serve(listener)
}
再把goods部署到另一台192.168.1.112上,main.go代码如下:
package main

import (
    "context"
    "fmt"
    "github.com/hashicorp/consul/api"
    "goods/proto/goodsService"
    "net"
    "google.golang.org/grpc"
    "strconv"
)

//rpc远程调用的接口,需要实现goods.proto中定义的Goods服务接口,以及里面的方法
//1.定义远程调用的结构体和方法,这个结构体需要实现GoodsServer的接口

type Goods struct{}

//GoodsServer方法参考goods.pb.go中的接口
/*
// GoodsServer is the server API for Goods service.
type GoodsServer interface {
    // 通过rpc来指定远程调用的方法:
    // AddGoods方法:增加商品, 这个方法里面实现对传入的参数AddGoodsReq, 以及返回的参数AddGoodsRes进行约束
    AddGoods(context.Context, *AddGoodsReq) (*AddGoodsRes, error)
    // 获取商品列表: GetGoodsReq 参数可为空, 返回参数GetGoodsRes是一个商品相关的切片
    GetGoods(context.Context, *GetGoodsReq) (*GetGoodsRes, error)
}
*/
//增加商品数据
func (this Goods) AddGoods(c context.Context, req *goodsService.AddGoodsReq) (*goodsService.AddGoodsRes, error) {
    fmt.Println(req)
    //模拟返回操作,正式项目在这里进行数据库的操作即可,根据操作结果,返回相关数据
    return &goodsService.AddGoodsRes{
        Message: "第二个goods微服务-增加数据成功",
        Success: true,
    }, nil
}

//获取商品列表
func (g Goods) GetGoods(c context.Context, req *goodsService.GetGoodsReq) (*goodsService.GetGoodsRes, error) {
    //  GoodsList []*GoodsModel
    var tempList []*goodsService.GoodsModel  //定义返回的商品列表切片
    //模拟从数据库中获取商品的请求,循环结果,把商品相关数据放入tempList切片中
    for i := 0; i < 10; i++ {
        tempList = append(tempList, &goodsService.GoodsModel{
            Title:   "商品" + strconv.Itoa(i),  // strconv.Itoa(i): 整型转字符串类型
            Price:   float64(i),  //float64(i): 强制转换整型为浮点型
            Content: "测试商品内容" + strconv.Itoa(i),
        })
    }
    return &goodsService.GetGoodsRes{
        GoodsList: tempList,
    }, nil
}

func main() {
    //------------------------- consul服务相关----------------------
    //注册consul服务
    //1、初始化consul配置
    consulConfig := api.DefaultConfig()
    //设置consul服务器地址: 默认127.0.0.1:8500, 如果consul部署到其它服务器上,则填写其它服务器地址
    consulConfig.Address = "192.168.1.132:8500"
    //2、获取consul操作对象
    consulClient, _ := api.NewClient(consulConfig)
    // 3、配置注册服务的参数
    agentService := api.AgentServiceRegistration{
        ID:      "2",  // 服务id,顺序填写即可
        Tags:    []string{"goods"},  // tag标签
        Name:    "GoodsService",  //服务名称, 注册到服务发现(consul)的K
        Port:    8080, // 端口号: 需要与下面的监听, 指定 IP、port一致
        Address: "192.168.1.112",  // 当前微服务部署    地址: 结合Port在consul设置为V: 需要与下面的监听, 指定 IP、port一致
        Check: &api.AgentServiceCheck{  //健康检测
            TCP:      "192.168.1.112:8080",  //前微服务部署地址,端口 : 需要与下面的监听, 指定 IP、port一致
            Timeout:  "5s",  // 超时时间
            Interval: "30s",  // 循环检测间隔时间
        },
    }

    //4、注册服务到consul上
    consulClient.Agent().ServiceRegister(&agentService)

    //1. 初始一个 grpc 对象
    grpcServer := grpc.NewServer()
    //2. 注册服务
    //helloService.RegisterGoodsServer(grpcServer, &Goods{})
    // &Hello{}和 new(Hello)相同
    goodsService.RegisterGoodsServer(grpcServer, new(Goods))
    //3. 设置监听, 指定 IP、port
    listener, err := net.Listen("tcp", "192.168.1.112:8080")
    if err != nil {
        fmt.Println(err)
    }
    // 4退出关闭监听
    defer listener.Close()
    //5、启动服务
    grpcServer.Serve(listener)
}
这两台服务器上的代码 不同之处: ID一定要不一样 ,Port为对应服务器上的端口号 ,Address为对应服务器的ip,Name(服务名称),标签(Tag)一定要一致,其他地方不变, 这样 负载均衡的微服务集群就准备好了
然后在这两台服务器上启动服务: go run main.go,这样就注册goods微服务到consul服务发现集群中了,如下图:
[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示

GoodsService服务图示:

[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示
  1. 客户端进行调度

客户端请求微服务, 要达到这样的效果: 一个客户请求访问192.168.1.111这台goods微服务,另一个客户请求访问192.168.1.112这台goods微服务; 要实现该效果,就要在客户端这边修改相关代码,有两种方式, 如下:

方式一

在客户端client/main.go代码中操作: 在拼接地址步骤时, 写一个算法(随机取获取返回的几个地址的切片),不直接取值
package main

import (
    "client/proto/goodsService"
    "context"
    "fmt"
    "github.com/hashicorp/consul/api"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    "strconv"
)

func main() {
    //----------------------------consul相关---------------------------
    //初始化consul配置, 客户端服务器需要一致
    consulConfig := api.DefaultConfig()
    //设置consul服务器地址: 默认127.0.0.1:8500, 如果consul部署到其它服务器上,则填写其它服务器地址
    consulConfig.Address = "192.168.1.132:8500"
    //2、获取consul操作对象
    consulClient, _ := api.NewClient(consulConfig)  //目前先屏蔽error,也可以获取error进行错误处理

    ----------------------------goods微服务相关--------------------------

    //3、获取consul服务发现地址,返回的ServiceEntry是一个结构体数组
    //参数说明:service:服务名称,服务端设置的那个Name, tag:标签,服务端设置的那个Tags,, passingOnly bool, q: 参数
    serviceGoodsEntry, _, _ := consulClient.Health().Service("GoodsService", "test", false, nil)
    
    //拼接地址: 写一个算法(随机取获取返回的几个地址的切片),不直接取值
    //strconv.Itoa: int转string型
    addressGoods := serviceGoodsEntry[0].Service.Address + ":" + strconv.Itoa(serviceGoodsEntry[0].Service.Port)

    // 1、连接服务器
    /*
        credentials.NewClientTLSFromFile :从输入的证书文件中为客户端构造TLS凭证。
        grpc.WithTransportCredentials :配置连接级别的安全凭证(例如,TLS/SSL),返回一个
        DialOption,用于连接服务器。

    */
    grpcGoodsClient, err := grpc.Dial(addressGoods, grpc.WithTransportCredentials(insecure.NewCredentials()))

    if err != nil {
        fmt.Println(err)
    }
    //2、注册客户端
    clientGoods := goodsService.NewGoodsClient(grpcGoodsClient)
    //增加
    res1, _ := clientGoods.AddGoods(context.Background(), &goodsService.AddGoodsReq{
        Goods: &goodsService.GoodsModel{
            Title:   "测试商品",
            Price:   20,
            Content: "测试商品的内容",
        },
    })
    fmt.Println(res1.Message)
    fmt.Println(res1.Success)

    //获取商品数据
    res2, _ := clientGoods.GetGoods(context.Background(), &goodsService.GetGoodsReq{})
    fmt.Printf("%#v", res2.GoodsList)

    for i := 0; i < len(res2.GoodsList); i++ {
        fmt.Printf("%#v\r\n", res2.GoodsList[i])
    }
}

方式二

使用 grpc-consul-resolver实现 域名解析, 在这里需要引入grpc-consul-resolver,直接使用命令 go mod tidy 操作
 package main

import (
    "client/proto/goodsService"
    "context"
    "fmt"
    "github.com/hashicorp/consul/api"
    "google.golang.org/grpc"
    "google.golang.org/grpc/credentials/insecure"
    _ "github.com/mbobakov/grpc-consul-resolver" // 必须引入
    "strconv"
)

func main() {
    //直接进行连接服务器拨号操作
    grpcGoodsClient, err := grpc.Dial(
        "consul://192.168.234.132:8500/GoodsService",  //服务发现地址+服务名称
        grpc.WithTransportCredentials(insecure.NewCredentials()),
        //轮询调度策略
        grpc.WithDefaultServiceConfig(`{"loadBalancingPolicy": "round_robin"}`),
    )

    if err != nil {
        fmt.Println(err)
    }

    //2、注册客户端
    clientGoods := goodsService.NewGoodsClient(grpcGoodsClient)
    //增加
    res1, _ := clientGoods.AddGoods(context.Background(), &goodsService.AddGoodsReq{
        Goods: &goodsService.GoodsModel{
            Title:   "测试商品",
            Price:   20,
            Content: "测试商品的内容",
        },
    })
    fmt.Println(res1.Message)
    fmt.Println(res1.Success)

    //获取商品数据
    res2, _ := clientGoods.GetGoods(context.Background(), &goodsService.GetGoodsReq{})
    fmt.Printf("%#v", res2.GoodsList)

    for i := 0; i < len(res2.GoodsList); i++ {
        fmt.Printf("%#v\r\n", res2.GoodsList[i])
    }
}
使用 grpc-consul-resolver 进行操作,省去了consul相关操作对象连接,要方便一下

然后运行go run main.go,可以看到,该客户端调用微服务是随机的

[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示

好了,微服务集群就搭建好了,这样就实现了: 当一台微服务挂了,客户端照样能够调度访问,因为实现了微服务的负载均衡操作

[上一节][golang 微服务] 5. 微服务服务发现介绍,安装以及consul的使用,Consul集群

[下一节][golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例文章来源地址https://www.toymoban.com/news/detail-490955.html

到了这里,关于[golang 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 在CSDN学Golang场景化解决方案(基于grpc的微服务开发脚手架)

    在Golang基于gRPC的微服务开发中,可以采用TLS加密通信来确保服务与服务之间的安全通信。下面是一个简单的设计示例: 生成证书和密钥: 定义gRPC服务器: 客户端连接gRPC服务器: 在服务实现中添加TLS加密通信: 这样,在Golang基于gRPC的微服务开发中,就可以使用TLS加密通信

    2024年02月14日
    浏览(33)
  • [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例

    上一节讲解了 GRPC微服务集群 + Consul集群 + grpc-consul-resolver 相关的案例,知道了微服务之间通信采用的 通信协议 ,如何实现 服务的注册和发现 ,搭建 服务管理集群 ,以及服务与服务之间的 RPC通信方式 ,具体的内容包括: protobuf协议 , consul 及 docker部署consul集群 , GRPC框架 的

    2024年02月09日
    浏览(28)
  • golang grpc配置使用实战教程

    RPC是远程过程调用(Remote Procedure Call)的缩写形式, RPC 的主要功能目标是让构建分布式计算(应用)更容易,在提供强大的远程调用能力时不损失本地调用的语义简洁性。通俗地讲, 使用RPC进行通信,调用远程函数就像调用本地函数一样,RPC底层会做好数据的序列化与传输。

    2024年02月03日
    浏览(30)
  • golang工程——grpc-gateway 转发http header中自定义字段到grpc上下文元数据

    http header 转发到 grpc上下文 grpc网关可以将请求体内容转发到grpc对应消息中。那如何获取http header头中的信息,本文将介绍如何将http header转发到grpc上下文并采用拦截器,获取http header中的内容。 有些http header中的内置字段是会转发的比如Authorization,但是狠多自定义字段是转发

    2024年02月08日
    浏览(26)
  • golang 通用的 grpc http 基础开发框架

    golang 通用的 grpc http 基础开发框架 仓库地址: https://github.com/webws/go-moda 仓库一直在更新,欢迎大家吐槽和指点 transport: 集成 http(echo、gin)和 grpc。 tracing: openTelemetry 实现微务链路追踪 pprof: 分析性能 config: 通用的配置文件读取模块,支持 toml、yaml 和 json 格式。 logger: 日志系统

    2024年02月10日
    浏览(27)
  • golang gRPC:根据.protobuf文件生成go代码

    安装 protoc 编译器。如果没有安装,可以参考官方文档进行安装。 使用 protoc 命令生成 gRPC 代码: 此命令将生成 .pb.go 和 _grpc.pb.go 文件,其中包含 protobuf 和 gRPC 的代码实现. –go_out选项会生成纯粹的Protocol Buffer消息代码,这包括Go语言的消息结构体和一些辅助方法。如果你只

    2024年02月14日
    浏览(35)
  • go get google.golang.org/grpc报错

    win10环境,报错完整内容如下 go get google.golang.org/grpc: module google.golang.org/grpc: Get https://proxy.golang.org/google.golang.org/grpc/@v/list: dial tcp [2404:6800:4012:3::2011]:443: connectex: A connection attempt failed because the connected party did no t properly respond after a period of time, or established connection failed because c

    2024年02月11日
    浏览(40)
  • 阿里云k8s容器部署consul集群的高可用方案

    原本consul集群是由三个server节点搭建的,购买的是三个ecs服务器, java服务在注册到consul的时候,随便选择其中一个节点。 从上图可以看出, consul-01有28个服务注册,而consul-02有94个服务,consul-03则是29个。 有一次发生consul集群故障,某个conusl节点挂了,导致整个的服务发现

    2024年04月14日
    浏览(85)
  • 微服务 - Consul服务注册中心

    上篇说到构建良好的架构,依托于基础设施建设(自动化测试、自动化部署、服务监控,服务发现、配置中心等等),决定成败的往往是基础设施建设,所以从搭建一个注册中心和配置中心开始我们新一阶段的启程。 注册中心选型 你有没有思考过这样一个问题,为什么会有这么

    2023年04月23日
    浏览(40)
  • golang 工程组件:grpc-gateway 环境安装+默认网关测试

    grpc-gateway 顾名思义是专门是grpc的网关。也是一个protobuf的编译器,是一个proto的插件。 grpc-gateway就是将http请求处理后转发到对应grpc服务上。很多浏览器,或者客户端开箱不支持grpc,只支持传统的restful API。 grpc网关而且也支持负载,兼容不同版本。 官方文档 grpc-gateway 源码

    2024年02月08日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包