go-micro examples 中grpc 代码学习(开发grpc类型的微服务 和 网关)

这个例子展示了 go-micro/service/grpc 的使用方法。

目录 greeter  -- 问候 微服务

目录 gateway -- grpc 网关 

创建 micro.Service : service := grpc.NewService()

Pre-existing Service

What if you want to add grpc to a pre-existing service? Use the build pattern for plugins but swap out the client/server.???

目录如下:

go-micro examples 中grpc 代码学习(开发grpc类型的微服务 和 网关)_第1张图片

greeter/srv/proto/hello/hello.proto

syntax = "proto3";

package greeter;

service Say {
    rpc Hello(Request) returns (Response) {}
}

message Request {
    string name = 1;
}

message Response {
    string msg = 1;
}

使用protoc 工具 创建 hello.pb.go  ; hello.micro.go;

bogon:grpc zhaozhiliang$ protoc --proto_path=$GOPATH/src:. --micro_out=. --go_out=. greeter/srv/proto/hello.proto

greeter/srv/main.go 代码如下:

package main

import (
	"context"
	"github.com/micro/go-micro"
	"github.com/micro/go-micro/service/grpc"
	"log"
	"time"
	"zhaozhiliang.com/grpc/greeter/srv/proto/hello"
)

type Say struct{}

func (s *Say) Hello(ctx context.Context, req *hello.Request, rsp *hello.Response) (err error) {
	log.Print("Received Say.Hello request")
	rsp.Msg = "Hello " + req.Name
	return
}
func main() {
	service := grpc.NewService(
		micro.Name("greeter"),
		micro.RegisterTTL(time.Second*30),
		micro.RegisterInterval(time.Second*10),
	)

	// optionally setup command line usage
	service.Init()

	// Register Handlers
	hello.RegisterSayHandler(service.Server(), new(Say))

	// Run server
	if err := service.Run(); err != nil {
		log.Fatal(err)
	}
}

greeter/cli/main.go grpc客户端代码

package main

import (
	"context"
	"fmt"
	"github.com/micro/go-micro/metadata"
	"github.com/micro/go-micro/service/grpc"
	"zhaozhiliang.com/grpc/greeter/srv/proto/hello"
)

func main() {
	service := grpc.NewService()
	service.Init()

	//使用 生成的  client
	//如果有 多个服务 怎么创建 cl
	cl := hello.NewSayService("greeter", service.Client())

	//在 context 中设置 任意的 头信息
	ctx := metadata.NewContext(context.Background(), map[string]string{
		"X-User-Id" : "john",
		"X-From-Id" : "script",
	})

	//不用指定端口就可以 调用服务了,服务端使用了 服务注册?
	rsp, err := cl.Hello(ctx, &hello.Request{
		Name : "Liang",
	})

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

	fmt.Println(rsp.Msg)
}

运行服务:

bogon:greeter zhaozhiliang$ go run srv/main.go --registry=mdns

ld: warning: object file (/var/folders/np/kffm4b517r57z3gsd7_py49w0000gn/T/go-link-264028127/000017.o) was built for newer OSX version (10.15) than being linked (10.13)
ld: warning: object file (/var/folders/np/kffm4b517r57z3gsd7_py49w0000gn/T/go-link-264028127/go.o) was built for newer OSX version (10.15) than being linked (10.13)
2020-01-06 16:19:09.288398 I | Server [grpc] Listening on [::]:56408
2020-01-06 16:19:09.288526 I | Broker [http] Connected to [::]:56409
2020-01-06 16:19:09.288894 I | Registering node: greeter-626f0229-a84a-4240-b1a2-09112dbd11cc
2020-01-06 16:20:19.915843 I | Received Say.Hello request

测试服务:

bogon:greeter zhaozhiliang$ go run cli/main.go --registry=mdns
# command-line-arguments
ld: warning: object file (/var/folders/np/kffm4b517r57z3gsd7_py49w0000gn/T/go-link-899183069/000000.o) was built for newer OSX version (10.15) than being linked (10.13)

Hello Liang
bogon:greeter zhaozhiliang$ 

网关相关代码如下:

gateway/proto/hello/hello.proto

syntax = "proto3";

package greeter;

import "google/api/annotations.proto";

service Say {
    rpc Hello(Request) returns (Response) {
        option (google.api.http) = {
            post : "/greeter/hello"
            body: "*"
        };
    }
}

message Request {
    string name = 1;
}

message Response {
    string msg = 1;
}

通过下面的proto命令生成grpc的存根和反向代理

protoc -I/usr/local/include -I. \
  -I$GOPATH/src \
  -I$GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway\@v1.12.1/third_party/googleapis \
  --go_out=plugins=grpc:. \
  hello/hello.proto


protoc -I/usr/local/include -I. \
  -I$GOPATH/src \
  -I$GOPATH/pkg/mod/github.com/grpc-ecosystem/grpc-gateway\@v1.12.1/third_party/googleapis \
  --grpc-gateway_out=logtostderr=true:. \
  hello/hello.proto

greeter/main.go  网关代码如下:

package main

import (
	"context"
	"flag"
	"github.com/golang/glog"
	"github.com/grpc-ecosystem/grpc-gateway/runtime"
	"google.golang.org/grpc"
	"net/http"
	"zhaozhiliang.com/grpc/gateway/proto/hello"
)

var (
	// greeter service address
	endpoint = flag.String("endpoint", "localhost:9090", "greeter service address")
)

func run() error {
	ctx := context.Background()
	ctx, cancel := context.WithCancel(ctx)
	defer cancel()

	mux := runtime.NewServeMux()
	opts := []grpc.DialOption{grpc.WithInsecure()}

	err := greeter.RegisterSayHandlerFromEndpoint(ctx, mux, *endpoint, opts)
	if err != nil {
		return err
	}
	return http.ListenAndServe(":8080", mux)
}

func main() {
	flag.Parse()

	defer glog.Flush()

	if err := run(); err != nil {
		glog.Fatal(err)
	}
}

 

使用:

1. 运行  greeter service

go run ../greeter/srv/main.go --server_address=localhost:9090

2. 运行网关:

go run main.go

3. curl 方式请求 网关(localhost:8080)

curl -d '{"name": "john"}' http://localhost:8080/greeter/hello
bogon:greeter zhaozhiliang$ curl -d '{"name": "john"}' http://localhost:8080/greeter/hello
{"msg":"Hello john"}bogon:greeter zhaozhiliang$ curl -d '{"name": "john"}' http://localhost:8080/greeter/hello
{"error":"connection error: desc = \"transport: Error while dialing dial tcp [::1]:9090: connect: connection refused\"","code":14,"message":"connection error: desc = \"transport: Error while dialing dial tcp [::1]:9090: connect: connection refused\""}bogon:greeter zhaozhiliang$ curl -d '{"name": "john"}' http://localhost:8080/greeter/hello
{"msg":"Hello john"}bogon:greeter zhaozhiliang$ 

本例子使用到的模块:

go.mod 文件内容如下:

module zhaozhiliang.com/grpc

go 1.13

require (
	github.com/golang/protobuf v1.3.2
	github.com/grpc-ecosystem/grpc-gateway v1.12.1
	github.com/micro/go-micro v1.18.0
	google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb
	google.golang.org/grpc v1.26.0
)

 

 

 

 

你可能感兴趣的:(go语言)