[golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例
作者:mmseoamin日期:2023-12-25

一.go-micro框架

  1. 前言

上一节讲解了 GRPC微服务集群+ Consul集群+ grpc-consul-resolver相关的案例,知道了微服务之间通信采用的 通信协议,如何实现 服务的注册和发现,搭建 服务管理集群,以及服务与服务之间的 RPC通信方式,具体的内容包括: protobuf协议, consul及 docker部署consul集群, GRPC框架的使用等具体的实现方案.以上这些具体的方案都是为了解决: 微服务实践过程中具体的某个问题而提出的,实现微服务架构的项目开发,但是,在具体的项目开发过程中,开发者聚焦的是 业务逻辑的开发和 功能的实现,大量的 环境配置, 调试搭建等基础性工作会耗费相当一部分的精力,因此有必要将微服务架构中所涉及到的,相关的解决方案做 集中管理和维护,这就需要使用到 Micro来进行处理
  1. go-micro介绍

Go Micro是一个简化分布式开发 的微服务生态系统,该系统为开发分布式应用程序提供了 高效, 便捷的模块构建, 主要目的是 简化分布式系统的开发,它默认实现了 consul作为服务发现(2019年源码修改了默认使用 mdns),通过 http进行通信,通过 protobuf和 json进行编解码,可以方便开发者们非常简单的开发出微服务架构的项目,并且随着业务模块的增加和功能的增加,Go Micro还能够提供管理微服务环境的工具和功能
github地址: https://github.com/asim/go-micro
  1. go-micro的主要功能

  • 身份验证

    身份验证作为一等公民内置,身份验证和授权通过为每个服务提供身份和证书来实现安全的零信任网络,这还包括基于规则的访问控制
    • 动态配置

      从 任何地方加载和 热重载动态配置,config 接口提供了一种从任何来源(如环境变量、文件、etcd) 加载应用程序级别配置的方法,可以合并源,甚至定义回退
      • 数据存储

        一个简单的 数据存储接口,用于 读取、写入和 删除记录,它默认包括对 内存、 文件和 CockroachDB 的支持, 状态和持久性成为原型设计之外的核心要求,Micro 希望将其构建到框架中
        • 服务发现

          自动服务注册和 名称解析,服务发现是 微服务开发的核心,当服务 A 需要与服务 B 通话时,它需要该服务的位置,默认发现机制是 多播 DNS (mdns),一个 zeroconf 系统
          • 负载均衡

            基于服务发现的 客户端负载均衡,一旦有了任意数量的 服务实例的 地址,现在需要一种方法来决定 路由到哪个节点,使用 随机散列负载均衡来提供 跨服务的均匀分布,并在出现问题时 重试不同的节点
            • 消息编码

              基于 内容类型的 动态消息编码,客户端和服务器将使用 编解码器和 内容类型无缝编码和解码 Go 类型,任何种类的消息都可以被编码并从不同的客户端发送,默认情况下,客户端和服务器会处理此问题,这默认包括 protobuf 和 json
              • RPC 客户端/服务器

                基于 RPC 的请求/响应,支持 双向流,为同步通信提供了一个抽象,对服务的请求将被 自动解析、负载均衡、拨号和流式传输
                • Async Messaging

                  PubSub 作为 异步通信和 事件驱动架构的一等公民内置, 事件通知是 微服务开发的核心模式,默认消息系统是 HTTP 事件消息代理
                  • 事件流

                    PubSub 非常适合 异步通知,但对于更高级的用例, 事件流是首选,提供 持久存储,从偏移量和确认中消耗,Go Micro 包括对 NATS Jetstream 和 Redis 流的支持
                    • 同步

                      分布式系统通常以 最终一致的方式构建,对 分布式锁定和 领导(Leader)的支持作为同步接口内置,当使用 最终一致的数据库或 调度时,请使用 Sync 接口
                      • Pluggable Interfaces

                        Go Micro 为每个分布式系统抽象使用 Go 接口,因此,这些接口是 可插拔的,并 允许 Go Micro 与运行时无关,可以插入任何底层技术
                        1. go-micro安装

                        github地址: https://github.com/asim/go-micro, 如下,点击CLI后,可以查看安装相关命令 :
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第1张
                        通过go install github.com/go-micro/cli/cmd/go-micro@latest安装,成功后,通过 go-micro new service helloworld命令就可以搭建微服务的服务端,客户端,搭建后, 系统会自动生成 .proto, .pb.go等远程调用的文件以及方法
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第2张
                        安装如下:运行命令 go install github.com/go-micro/cli/cmd/go-micro@latest
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第3张

                        命令完成后,在GOPATH的bin目录就可以查看到对应的go-micro.exe执行文件了

                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第4张
                        然后查看是否安装成功,输入命令 :go-micro
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第5张
                        安装成功

                        二.go-micro的使用

                        (一).helloworld简单案例讲解

                        1. 创建服务端

                        在servers目录下运行 :go-micro new service helloworld
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第6张 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第7张 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第8张 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第9张
                        1. 下载项目所需依赖

                        初次使用时,需执行Makefile里面的命令

                        Makefile内容如下:
                        GOPATH:=$(shell go env GOPATH)
                        .PHONY: init
                        init:
                            @go get -u google.golang.org/protobuf/proto
                            @go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
                            @go install github.com/go-micro/generator/cmd/protoc-gen-micro@latest
                        .PHONY: proto
                        proto:
                            @protoc --proto_path=. --micro_out=. --go_out=:. proto/helloworld.proto
                        .PHONY: update
                        update:
                            @go get -u
                        .PHONY: tidy
                        tidy:
                            @go mod tidy
                        .PHONY: build
                        build:
                            @go build -o helloworld *.go
                        .PHONY: test
                        test:
                            @go test -v ./... -cover
                        .PHONY: docker
                        docker:
                            @docker build -t helloworld:latest .
                        windows下依次执行Markfile init里面的命令:
                        #init里面的命令:引入需要的包
                        go get -u google.golang.org/protobuf/proto
                        go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
                        go install github.com/go-micro/generator/cmd/protoc-gen-micro@latest
                        #proto:执行生成对应的protobuf相关文件
                        protoc --proto_path=. --micro_out=. --go_out=:. proto/helloworld.proto
                        linux下通过make命令下载对应依赖或者编译项目
                        make proto update tidy

                        完成上面命令后的目录如下:

                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第8张
                        1. 初始化服务端项目

                        go mod init helloworld
                        go mod tidy

                        如果出现:

                        F:\www\go-data\src\go_code\micro\grpc_demo\server\helloworld>go mod tidy
                        go: finding module for package google.golang.org/protobuf/runtime/protoimpl
                        go: finding module for package go-micro.dev/v4/logger
                        go: finding module for package go-micro.dev/v4
                        go: finding module for package go-micro.dev/v4/server
                        go: finding module for package go-micro.dev/v4/api
                        go: finding module for package google.golang.org/protobuf/proto
                        go: finding module for package google.golang.org/protobuf/reflect/protoreflect
                        go: finding module for package go-micro.dev/v4/client
                        go: found go-micro.dev/v4 in go-micro.dev/v4 v4.10.2
                        go: found go-micro.dev/v4/logger in go-micro.dev/v4/logger v1.18.0
                        go: found go-micro.dev/v4/api in go-micro.dev/v4/api v1.18.0
                        go: found go-micro.dev/v4/client in go-micro.dev/v4/client v1.18.0
                        go: found go-micro.dev/v4/server in go-micro.dev/v4/server v1.18.0
                        go: found google.golang.org/protobuf/proto in google.golang.org/protobuf v1.30.0
                        go: found google.golang.org/protobuf/reflect/protoreflect in google.golang.org/protobuf v1.30.0
                        go: found google.golang.org/protobuf/runtime/protoimpl in google.golang.org/protobuf v1.30.0
                        go: helloworld/proto imports
                                go-micro.dev/v4/api: go-micro.dev/v4/api@v1.18.0: parsing go.mod:
                                module declares its path as: github.com/micro/go-micro
                                        but was required as: go-micro.dev/v4/api
                        

                        说明下载"go-micro.dev/v4"这个包失败了,这时则需运行命令 go get go-micro.dev/v4,如图:

                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第11张

                        然后再次执行步骤3中的命令即可

                        1. 配置服务端consul

                        (1).启动consul
                        在配置consul之前,需要启动consul,命令行执行命令 :consul agent -dev,启动consul服务, 也可以使用 consul集群相关操作进行处理
                        (2).引入consul包
                        然后在servers/helloworld/main.go下引入consul包:
                        可以在import引入包后,执行 go mod tidy ,也可以执行 go get github.com/go-micro/plugins/v4/registry/consul 命令引入
                         github.com/go-micro/plugins/v4/registry/consul
                        (3).实例化consul:
                        consulReg := consul.NewRegistry()
                        (4).注册consul
                        srv := micro.NewService(
                            micro.Address("192.168.1.132:8080"),  // 选择注册服务器地址,默认为本机,也可以选择consul集群中的client
                            micro.Name(service),
                            micro.Version(version),
                            micro.Registry(consulReg),
                        )
                        (5).详细代码
                        package main
                        import (
                            "helloworld/handler"
                            pb "helloworld/proto"
                            "go-micro.dev/v4"
                            "go-micro.dev/v4/logger"
                            "github.com/go-micro/plugins/v4/registry/consul"
                        )
                        var (
                            service = "helloworld"
                            version = "latest"
                        )
                        func main() {
                            //集成consul
                            consulReg := consul.NewRegistry()
                            // Create service
                            srv := micro.NewService(
                                micro.Address("127.0.0.1:8080"),  //指定微服务的ip:  选择注册服务器地址,也可以不配置,默认为本机,也可以选择consul集群中的client
                                micro.Name(service),
                                micro.Version(version),
                                //注册consul
                                micro.Registry(consulReg),
                            )
                            srv.Init(
                                micro.Name(service),
                                micro.Version(version),
                            )
                            // Register handler
                            if err := pb.RegisterHelloworldHandler(srv.Server(), new(handler.Helloworld)); err != nil {
                                logger.Fatal(err)
                            }
                            // Run service
                            if err := srv.Run(); err != nil {
                                logger.Fatal(err)
                            }
                        }
                        (6).结果显示
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第12张 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第13张 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第14张
                        微服务服务端就配置并启动了
                        1. 生成客户端

                        (1).生成客户端目录
                        在client目录下运行 :go-micro new client helloworld
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第15张
                        目录如下: 结构和服务端结构一致,参考服务端结构

                        注意:在这里生成的客户端文件夹名字是helloworld-client

                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第16张
                        里面也存在 Makefile文件,操作和上面服务端一致, 下面就要让 客户端连接上微服务服务端
                        (2).创建客户端proto文件相关
                        这里可以直接把服务端中的proto文件夹复制到helloworld-client文件夹下,然后可以初始化项目,删除go.mod, 执行初始化命令 :go mod init helloworld-client, go mod tidy
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第17张
                        重新初始化helloworld-client: 删除go.mod文件,然后执行: go mod init helloworld-client, go mod tidy
                        (3).完善helloworld-client/main.go文件
                        1).修改helloworld/proto包名字
                        需要把helloworld/proto修改为helloworld-client/proto
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第18张

                        然后也要引入consul包

                        2).引入consul包
                        然后在client/helloworld-client/main.go下引入consul包:
                        可以在import引入包后,执行 go mod tidy ,也可以执行 go get github.com/go-micro/plugins/v4/registry/consul 命令引入
                         github.com/go-micro/plugins/v4/registry/consul
                        3).实例化consul:
                        consulReg := consul.NewRegistry()
                        4).注册consul
                        //集成consul
                        consulReg := consul.NewRegistry(
                            //指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client
                            registry.Addrs("127.0.0.1:8500"),
                        )
                        // Create service
                        srv := micro.NewService(
                            //注册consul
                            micro.Registry(consulReg),
                        )
                        5).详细代码
                        package main
                        import (
                            "context"
                            "time"
                            pb "helloworld-client/proto"
                            "go-micro.dev/v4"
                            "go-micro.dev/v4/logger"   
                            "go-micro.dev/v4/registry"
                            "github.com/go-micro/plugins/v4/registry/consul"
                        )
                        var (
                            service = "helloworld" //需要和微服务服务端对应的service名统一,这样才能调用该微服务
                            version = "latest"
                        )
                        func main() {
                            //集成consul
                            consulReg := consul.NewRegistry(
                                //指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client
                                registry.Addrs("127.0.0.1:8500"),
                            )
                            // Create service
                            srv := micro.NewService(
                                //注册consul
                                micro.Registry(consulReg),
                            )
                            srv.Init()
                            // 创建客户端实例
                            c := pb.NewHelloworldService(service, srv.Client())
                            for {
                                // Call service: CallRequest就是.proto中的
                                rsp, err := c.Call(context.Background(), &pb.CallRequest{Name: "张三"})
                                if err != nil {
                                    logger.Fatal(err)
                                }
                                logger.Info(rsp)
                                //每隔一段时间请求
                                time.Sleep(2 * time.Second)  // 每隔2秒请求
                            }
                        }
                        6).结果显示
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第19张
                        客户端配置操作完成

                        (二).goodsinfo微服务案例讲解

                        1. 创建服务端

                        在servers目录下运行 :go-micro new service goodsinfo
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第20张

                        目录和上面helloworld案例类似,只不过是名字变成了goodsinfo而已

                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第21张

                        然后修改goodsinfo.proto,增加需要的服务方法:这里的写法和[golang 微服务] 4. gRPC介绍,Protobuf结合gRPC 创建微服务 里面的类似:

                        syntax = "proto3";
                        package goodsinfo;
                        option go_package = "./proto;goodsinfo";
                        //商品相关方法
                        service Goodsinfo {
                            //AddGoods: 定义增加商品的微服务, 这里的写法和gRPC中的写法一致
                            rpc AddGoods(AddRequest) returns (AddResponse) {}
                        }
                        //和gRPC中的写法一致
                        message AddRequest {
                            string title = 1;
                            string price = 2;
                            string content = 3;
                        }
                        //和gRPC中的写法一致
                        message AddResponse {
                            string message = 1;
                            bool success = 2;
                        }
                        1. 下载项目所需依赖

                        初次使用时,需执行Makefile里面的命令

                        Makefile内容如下:
                        GOPATH:=$(shell go env GOPATH)
                        .PHONY: init
                        init:
                            @go get -u google.golang.org/protobuf/proto
                            @go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
                            @go install github.com/go-micro/generator/cmd/protoc-gen-micro@latest
                        .PHONY: proto
                        proto:
                            @protoc --proto_path=. --micro_out=. --go_out=:. proto/helloworld.proto
                        .PHONY: update
                        update:
                            @go get -u
                        .PHONY: tidy
                        tidy:
                            @go mod tidy
                        .PHONY: build
                        build:
                            @go build -o helloworld *.go
                        .PHONY: test
                        test:
                            @go test -v ./... -cover
                        .PHONY: docker
                        docker:
                            @docker build -t helloworld:latest .
                        windows下依次执行init里面的命令:
                        #init:引入相关包
                        go get -u google.golang.org/protobuf/proto
                        go install google.golang.org/protobuf/cmd/protoc-gen-go@latest
                        go install github.com/go-micro/generator/cmd/protoc-gen-micro@latest
                        #proto: 生成protobuf相关文件
                        protoc --proto_path=. --micro_out=. --go_out=:. proto/helloworld.proto
                        linux下通过make命令下载对应依赖或者编译项目
                        make proto update tidy

                        完成上面命令后的目录如下:

                        生成了goodsinfo相关handler,以及.pb.go文件
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第22张
                        1. 初始化服务端项目

                        go mod init goodsinfo
                        go mod tidy

                        如果出现:

                        F:\www\go-data\src\go_code\micro\grpc_demo\server\helloworld>go mod tidy
                        go: finding module for package google.golang.org/protobuf/runtime/protoimpl
                        go: finding module for package go-micro.dev/v4/logger
                        go: finding module for package go-micro.dev/v4
                        go: finding module for package go-micro.dev/v4/server
                        go: finding module for package go-micro.dev/v4/api
                        go: finding module for package google.golang.org/protobuf/proto
                        go: finding module for package google.golang.org/protobuf/reflect/protoreflect
                        go: finding module for package go-micro.dev/v4/client
                        go: found go-micro.dev/v4 in go-micro.dev/v4 v4.10.2
                        go: found go-micro.dev/v4/logger in go-micro.dev/v4/logger v1.18.0
                        go: found go-micro.dev/v4/api in go-micro.dev/v4/api v1.18.0
                        go: found go-micro.dev/v4/client in go-micro.dev/v4/client v1.18.0
                        go: found go-micro.dev/v4/server in go-micro.dev/v4/server v1.18.0
                        go: found google.golang.org/protobuf/proto in google.golang.org/protobuf v1.30.0
                        go: found google.golang.org/protobuf/reflect/protoreflect in google.golang.org/protobuf v1.30.0
                        go: found google.golang.org/protobuf/runtime/protoimpl in google.golang.org/protobuf v1.30.0
                        go: helloworld/proto imports
                                go-micro.dev/v4/api: go-micro.dev/v4/api@v1.18.0: parsing go.mod:
                                module declares its path as: github.com/micro/go-micro
                                        but was required as: go-micro.dev/v4/api
                        

                        说明下载"go-micro.dev/v4"这个包失败了,这时则需运行命令 go get go-micro.dev/v4,如图:

                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第11张

                        然后再次执行步骤3中的命令即可

                        修改远程调用的方法handler/goodsinfo.go
                        原始的代码:
                        package handler
                        import (
                            "context"
                            "io"
                            "time"
                            "go-micro.dev/v4/logger"
                            pb "goodsinfo/proto"
                        )
                        type Goodsinfo struct{}
                        func (e *Goodsinfo) Call(ctx context.Context, req *pb.CallRequest, rsp *pb.CallResponse) error {
                            logger.Infof("Received Goodsinfo.Call request: %v", req)
                            rsp.Msg = "Hello " + req.Name
                            return nil
                        }
                        func (e *Goodsinfo) ClientStream(ctx context.Context, stream pb.Goodsinfo_ClientStreamStream) error {
                            var count int64
                            for {
                                req, err := stream.Recv()
                                if err == io.EOF {
                                    logger.Infof("Got %v pings total", count)
                                    return stream.SendMsg(&pb.ClientStreamResponse{Count: count})
                                }
                                if err != nil {
                                    return err
                                }
                                logger.Infof("Got ping %v", req.Stroke)
                                count++
                            }
                        }
                        func (e *Goodsinfo) ServerStream(ctx context.Context, req *pb.ServerStreamRequest, stream pb.Goodsinfo_ServerStreamStream) error {
                            logger.Infof("Received Goodsinfo.ServerStream request: %v", req)
                            for i := 0; i < int(req.Count); i++ {
                                logger.Infof("Sending %d", i)
                                if err := stream.Send(&pb.ServerStreamResponse{
                                    Count: int64(i),
                                }); err != nil {
                                    return err
                                }
                                time.Sleep(time.Millisecond * 250)
                            }
                            return nil
                        }
                        func (e *Goodsinfo) BidiStream(ctx context.Context, stream pb.Goodsinfo_BidiStreamStream) error {
                            for {
                                req, err := stream.Recv()
                                if err == io.EOF {
                                    return nil
                                }
                                if err != nil {
                                    return err
                                }
                                logger.Infof("Got ping %v", req.Stroke)
                                if err := stream.Send(&pb.BidiStreamResponse{Stroke: req.Stroke}); err != nil {
                                    return err
                                }
                            }
                        }
                        
                        修改成我们想要的代码:
                        package handler
                        import (
                            "context"
                            "go-micro.dev/v4/logger"
                            pb "goodsinfo/proto"
                        )
                        type Goodsinfo struct{}
                        func (e *Goodsinfo) AddGoods(ctx context.Context, req *pb.AddRequest, rsp *pb.AddResponse) error {
                            logger.Infof("request: %v", req)
                            //书写返回的逻辑结果
                            rsp.Message = "增加成功"
                            rsp.Success = true
                            return nil
                        }
                        1. 配置服务端consul

                        (1).启动consul
                        在配置consul之前,需要启动consul,命令行执行命令 :consul agent -dev,启动consul服务, 也可以使用 consul集群相关操作进行处理
                        (2).引入consul包
                        然后在servers/goodsinfo/main.go下引入consul包:
                        可以在import引入包后,执行 go mod tidy ,也可以执行 go get github.com/go-micro/plugins/v4/registry/consul 命令引入
                         github.com/go-micro/plugins/v4/registry/consul
                        (3).实例化consul:
                        consulReg := consul.NewRegistry()
                        (4).注册consul
                        srv := micro.NewService(
                            micro.Address("192.168.1.132:8080"),  // 选择注册服务器地址,默认为本机,也可以选择consul集群中的client
                            micro.Name(service),
                            micro.Version(version),
                            micro.Registry(consulReg),
                        )
                        (5).详细代码
                        package main
                        import (
                            "goodsinfo/handler"
                            pb "goodsinfo/proto"
                            "go-micro.dev/v4"
                            "go-micro.dev/v4/logger"
                            "github.com/go-micro/plugins/v4/registry/consul"
                        )
                        var (
                            service = "goodsinfo"
                            version = "latest"
                        )
                        func main() {
                            //集成consul
                            consulReg := consul.NewRegistry()
                            // Create service
                            srv := micro.NewService(
                                micro.Address("127.0.0.1:8080"),  //指定微服务的ip:  选择注册服务器地址,也可以不配置,默认为本机,也可以选择consul集群中的client
                                micro.Name(service),
                                micro.Version(version),
                                //注册consul
                                micro.Registry(consulReg),
                            )
                            srv.Init(
                                micro.Name(service),
                                micro.Version(version),
                            )
                            // Register handler
                            if err := pb.RegisterGoodsinfoHandler(srv.Server(), new(handler.Goodsinfo)); err != nil {
                                logger.Fatal(err)
                            }
                            // Run service
                            if err := srv.Run(); err != nil {
                                logger.Fatal(err)
                            }
                        }
                        (6).结果显示
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第24张 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第25张 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第26张
                        展示和上面helloworld类似,微服务服务端就配置并启动了
                        1. 生成客户端

                        (1).生成客户端目录
                        在client目录下运行 :go-micro new client goodsinfo
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第27张
                        目录如下: 结构和服务端结构一致,参考服务端结构
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第28张
                        里面也存在 Makefile文件,操作和上面服务端一致, 下面就要让 客户端连接上微服务服务端
                        (2).创建客户端proto文件相关
                        这里可以直接把服务端中的proto文件夹复制到goodsinfo-client文件夹下,然后可以初始化项目,删除go.mod, 执行初始化命令 :go mod init goodsinfo-client, go mod tidy
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第29张 [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第30张

                        如果出现:

                        go: goodsinfo-client/proto imports
                                go-micro.dev/v4/api: go-micro.dev/v4/api@v1.18.0: parsing go.mod:
                                module declares its path as: github.com/micro/go-micro
                                        but was required as: go-micro.dev/v4/api

                        则go get go-micro.dev/v4,和上面服务器解决方案一致

                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第31张
                        当然,也可以再次执行Makefile中的命令,和上面服务器一致
                        (3).完善goodsinfo-client/main.go文件
                        1).修改goodsinfo/proto包名字
                        需要把goodsinfo/proto修改为goodsinfo-client/proto
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第32张

                        然后也要引入consul包

                        2).引入consul包
                        然后在client/goodsinfo-client/main.go下引入consul包:
                        可以在import引入包后,执行 go mod tidy ,也可以执行 go get github.com/go-micro/plugins/v4/registry/consul 命令引入
                         github.com/go-micro/plugins/v4/registry/consul
                        3).实例化consul:
                        consulReg := consul.NewRegistry()
                        4).注册consul
                        //集成consul
                        consulReg := consul.NewRegistry(
                            //指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client
                            registry.Addrs("127.0.0.1:8500"),
                            )
                        // Create service
                        srv := micro.NewService(
                            //注册consul
                            micro.Registry(consulReg),
                        )
                        5).详细代码
                        package main
                        import (
                            "context"
                            "go-micro.dev/v4/registry"
                            "time"
                            pb "goodsinfo-client/proto"
                            "go-micro.dev/v4"
                            "go-micro.dev/v4/logger"
                            "github.com/go-micro/plugins/v4/registry/consul"
                        )
                        var (
                            service = "goodsinfo"
                            version = "latest"
                        )
                        func main() {
                            //集成consul
                            consulReg := consul.NewRegistry(
                                //指定微服务的ip:  选择注册服务器地址,默认为本机,也可以选择consul集群中的client
                                registry.Addrs("127.0.0.1:8500"),
                                )
                            // Create service
                            srv := micro.NewService(
                                //注册consul
                                micro.Registry(consulReg),
                            )
                            srv.Init()
                            // 创建客户端服务
                            c := pb.NewGoodsinfoService(service, srv.Client())
                            // Call service
                            rsp, err := c.AddGoods(context.Background(), &pb.AddRequest{
                                Title: "我是一个商品",
                                Price: "20.22",
                                Content: "内容展示",
                            })
                            if err != nil {
                                logger.Fatal(err)
                            }
                            logger.Info(rsp)
                        }
                        
                        6).结果显示
                        [golang 微服务] 7. go-micro框架介绍,go-micro脚手架,go-micro结合consul搭建微服务案例,第33张
                        客户端配置操作完成

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

                        [下一节][golang 微服务] 8.go-micro的负载均衡操作,go Web框(Gin,Beego)调用go-micro微服务