Installation and use of go-micro
Installation and application
installation
Micro
# go get
$ go get github.com/micro/micro/v2
# docker install
$ docker pull microhq/micro
Go-Micro
Go Micro is an RPC framework for Go development of microservices (use 2.x)
$ go get github.com/micro/go-micro/v2
protobuf
If you use code generation, you also need to use protoc-gen-go
$ go get github.com/micro/protobuf/{
proto,protoc-gen-go}
gRPC gateway
protobuf
mkdir tmp
cd tmp
git clone https://github.com/google/protobuf
cd protobuf
./autogen.sh
./configure
make
make check
sudo make install
Install plugin
go get -u github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway
go get -u github.com/micro/protobuf/protoc-gen-go
Test service
# 运行 greeter 服务,需要 consul 依赖
$ go get github.com/micro/examples/greeter/srv && srv
# 服务清单
$ micro list services
consul
go.micro.srv.greeter
# 获取服务
$ micro get service go.micro.srv.greeter
service go.micro.srv.greeter
version 1.0.0
Id Address Port Metadata
go.micro.srv.greeter-34c55534-368b-11e6-b732-68a86d0d36b6 192.168.1.66 62525 server=rpc,registry=consul,transport=http,broker=http
Endpoint: Say.Hello
Metadata: stream=false
Request: {
name string
}
Response: {
msg string
}
# 查询服务
$ micro query go.micro.srv.greeter Say.Hello '{"name": "John"}'
{
"msg": "Hello John"
}
Micro command
Create service
# 新建一个 helloworld 的服务
$ micro new helloworld
Start and run services
# 在本地运行该服务并确保其正常工作.
# 启动服务器
micro server
# 设置为本地环境
micro env set local
# 启动你的服务
micro run name
service status
# 检查状态
micro status
# 检查是否已注册
micro services
# 检查日志
micro logs helloworld
End of service
micro kill helloworld
Deployment service
# 将代码上传到 Github 才能完成部署
# 初始化 git
cd helloworld && git init && git add . && git commit -m "My helloworld service"
# 在 github 创建一个新的仓库并推送上去
# assuming you created it, add the remote origin
git remote add origin https://github.com/$user/helloworld.git
# 推送
git push origin master
# 设置环境为平台模式
micro env set platform
# 确保已经登陆到平台
micro login
# 现在可以运行了
micro run github.com/$user/helloworld
Call service
Check that the service is running and call the service. In addition, because it is built from source code, it may take several minutes to start (we will optimize this situation later)
# 检查服务状态
micro status
# 检查服务注册情况
micro services
# 调用指定的服务
micro helloworld --name=Alice
Pay attention to the symbols used to call the service. Micro supports dynamic CLI commands, which means that anything in your namespace will become a subcommand.
micro [service] [endpoint] [args]
Where the endpoint is submitted, we assume it is the service name + the "call" method, for example, helloworld becomes Helloworld. call. If this is a greeting method, we will assume Helloworld. The greeting and c are in c.micro helloworld greet
We assume that a method with a service name + "Call" is an endpoint. For example, helloworld will be Helloworld.Call. If it is the Greet method, we will assume that the command corresponding to Helloworld.Greet is micro helloworld greet.
Parameters can be passed as flags--name represents the Name field parameter.
If you want a simpler way using pure json and raw methods
micro call helloworld Helloworld.Call '{"name": "Alice"}'
Go-micro framework application
Greeter service
Created a Greeter microservice using go-grpc.
- The prototype is as follows:
syntax = "proto3";
package go.micro.srv.greeter;
service Say {
rpc Hello(Request) returns (Response) {
}
}
message Request {
string name = 1;
}
message Response {
string msg = 1;
}
- The services are as follows:
package main
import (
"log"
"time"
hello "github.com/micro/examples/greeter/srv/proto/hello"
"github.com/micro/go-grpc"
"github.com/micro/go-micro"
"golang.org/x/net/context"
)
type Say struct{
}
func (s *Say) Hello(ctx context.Context, req *hello.Request, rsp *hello.Response) error {
log.Print("Received Say.Hello request")
rsp.Msg = "Hello " + req.Name
return nil
}
func main() {
service := grpc.NewService(
micro.Name("go.micro.srv.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)
}
}
GRPC gateway
The grpc gateway uses the same protocol as the service, and adds an http option
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 use the following commands to generate grpc stub and reverse proxy
protoc -I/usr/local/include -I. \
-I$GOPATH/src \
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--go_out=plugins=grpc:. \
path/to/your_service.proto
protoc -I/usr/local/include -I. \
-I$GOPATH/src \
-I$GOPATH/src/github.com/grpc-ecosystem/grpc-gateway/third_party/googleapis \
--grpc-gateway_out=logtostderr=true:. \
path/to/your_service.proto
We used the following code to create a sample api for the greeter service. Similar code will be written to register other endpoints. Please note that the gateway needs the port address of the greeter service.
package main
import (
"flag"
"net/http"
"github.com/golang/glog"
"github.com/grpc-ecosystem/grpc-gateway/runtime"
"golang.org/x/net/context"
"google.golang.org/grpc"
hello "github.com/micro/examples/grpc/gateway/proto/hello"
)
var (
// the go.micro.srv.greeter address
endpoint = flag.String("endpoint", "localhost:9090", "go.micro.srv.greeter address")
)
func run() error {
ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)
defer cancel()
mux := runtime.NewServeMux()
opts := []grpc.DialOption{
grpc.WithInsecure()}
err := hello.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)
}
}
Run example
Run the greeter service. Specify mdns because we don't need discovery.
go run examples/grpc/greeter/srv/main.go --registry=mdns --server_address=localhost:9090
Run the gateway. It will default to the greeter service at the endpoint localhost:9090.
go run examples/grpc/gateway/main.go
Use curl to initiate a request on the (localhost:8080) gateway.
curl -d '{"name": "john"}' http://localhost:8080/greeter/hello
Execute protocommand to generate the current pb files go to achieve:
protoc --go_out=plugins=micro:. ./proto/hello.proto
protoc --go_out=. --micro_out=. ./proto/hello.proto
Write a go service
-
Define API
We use protobuf file to define service API interface. This is a very convenient way to strictly define the API and provide specific types for the server and client.// this is greeter.proto syntax = "proto3"; service Greeter { rpc Hello(HelloRequest) returns (HelloResponse) { } } message HelloRequest { string name = 1; } message HelloResponse { string greeting = 2; }
Here, we define a service handler named Greeter, where the method Hello uses the parameter HelloRequest type and returns HelloResponse.
-
Generate API interface
Use protoc and protoc-gen-go to generate a specific go implementation for this definition.protoc --go_out=plugins=micro:. greeter.proto
-
Write a service
package main import ( "log" "github.com/micro/go-micro" proto "github.com/micro/examples/service/proto" "golang.org/x/net/context" ) type Greeter struct{ } func (g *Greeter) Hello(ctx context.Context, req *proto.HelloRequest, rsp *proto.HelloResponse) error { rsp.Greeting = "Hello " + req.Name return nil } func main() { service := micro.NewService( micro.Name("greeter"), micro.Version("latest"), ) service.Init() proto.RegisterGreeterHandler(service.Server(), new(Greeter)) if err := service.Run(); err != nil { log.Fatal(err) } }
-
Write a client
// create the greeter client using the service name and client greeter := proto.NewGreeterClient("greeter", service.Client()) // request the Hello method on the Greeter handler rsp, err := greeter.Hello(context.TODO(), &proto.HelloRequest{ Name: "John", }) if err != nil { fmt.Println(err) return } fmt.Println(rsp.Greeter)
Service Communication
The communication between the two microservices is based on the C/S model, that is, the service requester acts as the Client and the service receiver acts as the Server.