[golang マイクロサービス] 7. Go-micro フレームワークの紹介、go-micro スキャフォールディング、go-micro と consul を組み合わせてマイクロサービス ケースを構築する

1. 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の主な機能

  • 認証

認証は第一級市民として組み込まれており、認証と認可により、各サービスに ID と証明書を提供することで安全なゼロトラスト ネットワークが可能になります。これにはルールベースのアクセス制御も含まれます
  • 動的構成

どこ から でも動的構成をロードおよび ホットリロードでき ます。構成インターフェースは、 任意のソース (環境変数、ファイル、etcd など) から アプリケーション レベルの構成をロードする方法を提供します。ソースはマージでき、フォールバックも定義できます。
  • データストレージ

レコードの読み取り、書き込み削除のための シンプルな データ ストレージ インターフェイスです。デフォルトで、 メモリファイル、および CockroachDBのサポート が含まれています 。状態と永続性は、プロトタイピング以外の中核となる要件になります。マイクロは、それをフレームワークに組み込むことを望んでいます。中央
  • サービスディスカバリ

自動サービス登録 名前解決 サービス検出は マイクロサービス開発の中核 です サービス A がサービス B と通信する必要がある場合、サービスの場所が必要です デフォルトの検出メカニズムは、 zeroconf システムである マルチキャスト DNS (mdns ) です
  • 負荷分散

サービス ディスカバリに基づく クライアント側の負荷分散 では、任意の数の サービス インスタンス アドレスを取得したら、 ランダム ハッシュ負荷分散を使用して ルーティング先のノードを決定し、 サービス全体に均等に分散する 方法が必要になります。 問題のうち、次の場合に 別のノードを再試行する
  • メッセージのエンコーディング

コンテンツ タイプ に基づく 動的メッセージ エンコーディング 。 クライアントとサーバーは コーデック コンテンツ タイプを 使用して Go タイプをシームレスにエンコードおよびデコードします。あらゆる種類のメッセージをエンコードして別のクライアントから送信できます。デフォルトでは、クライアントとサーバーがこれを処理します。デフォルトで protobuf jsonが含まれています
  • RPC クライアント/サーバー

RPC ベースのリクエスト/レスポンス 双方向ストリームの サポート、同期通信の抽象化を提供、サービスへのリクエストは 自動的に解析され、負荷分散され、ダイヤルされ、ストリーミングされます。
  • 非同期メッセージング

PubSub は、 非同期通信 イベント駆動型アーキテクチャ の第一級市民として組み込まれています 。 イベント通知は マイクロサービス開発の中核モード です 。デフォルトのメッセージ システムは HTTP イベント メッセージ エージェントです。
  • イベントの流れ

PubSub は非同期通知 に最適です が、より高度なユースケースでは イベント ストリームが 優先され、 永続的なストレージ を提供し、オフセットと確認応答から消費されます。Go Micro には NATS Jetstream および Redis ストリーム のサポート が含まれています
  • 同期する

分散システムは通常 、結果整合性のある 方法で構築されます 。 分散ロック と リーダーシップ (リーダー) の サポート が同期インターフェイスとして組み込まれています。 結果整合性のあるデータベース または スケジュールを使用する場合は、 同期インターフェイスを使用してください。
  • プラグイン可能なインターフェース

Go Micro は分散システムの抽象化ごとに Go インターフェイスを使用するため、これらのインターフェイスは プラグイン可能で あり、 Go Micro がランタイムに依存せず 、基盤となるテクノロジーにプラグインできるようになります。
  1. go-microのインストール

github アドレス: https://github.com/asim/go-micro、 次のように、 CLI をクリックすると 、インストール関連のコマンドを表示できます
go install github.com/go-micro/cli/cmd/go-micro@latest インストールを実行し、成功した後、 go-micro new service helloworld コマンドを使用してマイクロサービスのサーバーとクライアントを構築できます 。システムは、.proto や .pb.go などのリモート呼び出し用のファイルとメソッドを自動的に生成します。
インストールは次のとおりです。 go install github.com/go-micro/cli/cmd/go-micro@latest コマンドを実行します。

コマンドが完了すると、GOPATH の bin ディレクトリにある対応する go-micro.exe 実行ファイルを表示できます。

次に、インストールが成功したかどうかを確認し、コマンド go-microを入力します。
インストール成功

2. go-microの使用

(1). helloworldの簡単なケース説明

  1. サーバーを作成する

サーバーディレクトリで実行 : go-micro 新しいサービス helloworld
  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

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

  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/[email protected]: 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,如图:

然后再次执行步骤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).结果显示

微服务服务端就配置并启动了
  1. 生成客户端

(1).生成客户端目录

在client目录下运行 :go-micro new client helloworld
目录如下: 结构和服务端结构一致,参考服务端结构
注意:在这里生成的客户端文件夹名字是helloworld-client
里面也存在 Makefile文件,操作和上面服务端一致, 下面就要让 客户端连接上微服务服务端

(2).创建客户端proto文件相关

这里可以直接把服务端中的proto文件夹复制到helloworld-client文件夹下,然后可以初始化项目,删除go.mod, 执行初始化命令 :go mod init helloworld-client, go mod tidy
重新初始化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

然后也要引入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).结果显示
客户端配置操作完成

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

  1. 创建服务端

在servers目录下运行 :go-micro new service goodsinfo

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

然后修改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文件
  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/[email protected]: 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,如图:

然后再次执行步骤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).结果显示

展示和上面helloworld类似,微服务服务端就配置并启动了
  1. 生成客户端

(1).生成客户端目录

在client目录下运行 :go-micro new client goodsinfo
目录如下: 结构和服务端结构一致,参考服务端结构
里面也存在 Makefile文件,操作和上面服务端一致, 下面就要让 客户端连接上微服务服务端

(2).创建客户端proto文件相关

这里可以直接把服务端中的proto文件夹复制到goodsinfo-client文件夹下,然后可以初始化项目,删除go.mod, 执行初始化命令 :go mod init goodsinfo-client, go mod tidy

如果出现:

go: goodsinfo-client/proto imports
        go-micro.dev/v4/api: go-micro.dev/v4/[email protected]: 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,和上面服务器解决方案一致

当然,也可以再次执行Makefile中的命令,和上面服务器一致

(3).完善goodsinfo-client/main.go文件

1).修改goodsinfo/proto包名字
需要把goodsinfo/proto修改为goodsinfo-client/proto

然后也要引入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 微服务] 6. GRPC微服务集群+Consul集群+grpc-consul-resolver案例演示

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

おすすめ

転載: blog.csdn.net/zhoupenghui168/article/details/131252892