gomicro服务发现

安装工具

安装golang

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#下载地址 https://studygolang.com/dl

wget https://studygolang.com/dl/golang/go1.12.5.linux-amd64.tar.gz

#gopath
mkdir -p ~/goproject/src
mkdir -p ~/goproject/bin
mkdir -p ~/goproject/pkg

#配置环境 ~/.bashrc
export GOROOT=<go root path>
export GOPATH=<gopath>
export PATH=$PATH:$GOROOT/bin:/$GOPATH/bin
export GOPROXY=https://goproxy.cn

安装protoc

安装protoc-gen-go

1
go get -u github.com/golang/protobuf/{proto,protoc-gen-go}

安装protoc-gen-micro

1
go get -u github.com/micro/{micro,protoc-gen-micro}

安装Consul

micro默认使用consul作为微服务发现

下载地址:https://www.consul.io/downloads.html

1
2
3
wget https://releases.hashicorp.com/consul/1.5.0/consul_1.5.0_linux_amd64.zip
unzip consul_1.5.0_linux_amd64.zip
sudo mv consul $GOPATH/bin/

启动cansul,修改-data-dir目录路径

1
2
consul agent -server -node wyy-server -bind=127.0.0.1  -data-dir ~/consul -ui
# ./consul agent -server -bootstrap-expect 1 -data-dir /tmp/consul -node=chenxun-server -bind=192.168.145.130 -ui

目录结构

1
2
3
4
5
6
7
8
9
10
gomicro/
├── hello
│ ├── client
│ │ └── client.go
│ └── server
│ └── server.go
└── protoc
├── micro.micro.go
├── micro.pb.go
└── micro.proto

consul服务发现例子

micro.proto

1
2
3
4
5
6
7
8
9
10
11
12
syntax = "proto3";

service Greeter {
rpc Hello(HelloRequest) returns (HelloResponse) {}
}
message HelloRequest {
string name = 1;
}

message HelloResponse {
string greeting = 2;
}

生成代码

1
protoc --proto_path=$GOPATH/src:. --micro_out=. --go_out=. micro.proto

server.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
package main

import (
"context"
"fmt"
"log"
"github.com/micro/cli"
micro "github.com/micro/go-micro"
proto "gomicro/protoc" //这里写你的proto文件放置路劲

"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/registry/consul"
)

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() {
// 我这里用的etcd 做为服务发现,如果使用consul可以去掉
//reg := etcdv3.NewRegistry(func(op *registry.Options){
// op.Addrs = []string{
// "http://192.168.3.34:2379", "http://192.168.3.18:2379", "http://192.168.3.110:2379",
// }
//})

// 修改consul地址,如果是本机,这段代码和后面的那行使用代码都是可以不用的
reg := consul.NewRegistry(func(op *registry.Options){
op.Addrs = []string{
"127.0.0.1:8500",
}
})

// Create a new service. Optionally include some options here.
service := micro.NewService(
micro.Registry(reg),
micro.Name("greeter"),
micro.Version("latest"),
//读取命令行
micro.Flags(cli.StringFlag{
Name: "environment",
Usage: "The environment",
}),
//通过 service.Init 来解析参数,附加的处理可以通过 micro.Action 解决
micro.Action(func(c *cli.Context) {
//if c.Bool("run_client") {
// os.Exit(0)
//}
}),
micro.AfterStop(func() error {
log.Println("micro.AfterStop test ...")
return nil
}),
micro.AfterStart(func() error {
log.Println("micro.AfterStart test ...")
return nil
}),
)

// Init will parse the command line flags.
service.Init()

// Register handler
proto.RegisterGreeterHandler(service.Server(), new(Greeter))

// Run the server
if err := service.Run(); err != nil {
fmt.Println(err)
}
}

client.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main

import (
"context"
"fmt"

micro "github.com/micro/go-micro"
proto "gomicro/protoc" //这里写你的proto文件放置路劲

"github.com/micro/go-micro/registry"
"github.com/micro/go-micro/registry/consul"
)

func main() {

// 修改consul地址,如果是本机,这段代码和后面的那行使用代码都是可以不用的
reg := consul.NewRegistry(func(op *registry.Options){
op.Addrs = []string{
"127.0.0.1:8500",
}
})

// Create a new service. Optionally include some options here.
service := micro.NewService(micro.Registry(reg),micro.Name("greeter.client"))
service.Init()

// Create new greeter client
greeter := proto.NewGreeterService("greeter", service.Client())

// Call the greeter
rsp, err := greeter.Hello(context.TODO(), &proto.HelloRequest{Name: "John"})
if err != nil {
fmt.Println(err)
}

// Print response
fmt.Println(rsp.Greeting)
}

运行

1
2
go run examples/service/main.go
go run examples/client/main.go

浏览器输入127.0.0.1:8500,可以查看在consul中注册的服务

etcd服务发现例子

项目地址:https://github.com/etcd-io/etcd

1
git clone https://github.com/etcd-io/etcd.git $GOPATH/src/go.etcd.io/etcd/

运行etcd

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
ETCD_VER=v3.3.13

# choose either URL
GOOGLE_URL=https://storage.googleapis.com/etcd
GITHUB_URL=https://github.com/etcd-io/etcd/releases/download
DOWNLOAD_URL=${GOOGLE_URL}

rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
rm -rf /tmp/etcd-download-test && mkdir -p /tmp/etcd-download-test

curl -L ${DOWNLOAD_URL}/${ETCD_VER}/etcd-${ETCD_VER}-linux-amd64.tar.gz -o /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz
tar xzvf /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz -C /tmp/etcd-download-test --strip-components=1
rm -f /tmp/etcd-${ETCD_VER}-linux-amd64.tar.gz

/tmp/etcd-download-test/etcd --version
ETCDCTL_API=3 /tmp/etcd-download-test/etcdctl version


# start a local etcd server
/tmp/etcd-download-test/etcd

# write,read to etcd
ETCDCTL_API=3 /tmp/etcd-download-test/etcdctl --endpoints=localhost:2379 put foo bar
ETCDCTL_API=3 /tmp/etcd-download-test/etcdctl --endpoints=localhost:2379 get foo

micro.proto

1
2
3
4
5
6
7
8
9
10
11
12
syntax = "proto3";

service Greeter {
rpc Hello(HelloRequest) returns (HelloResponse) {}
}
message HelloRequest {
string name = 1;
}

message HelloResponse {
string greeting = 2;
}

生成代码

1
protoc --proto_path=$GOPATH/src:. --micro_out=. --go_out=. micro.proto

server.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
package main

import (
"context"
"fmt"
"log"
"github.com/micro/cli"
micro "github.com/micro/go-micro"
proto "gomicro/protoc" //这里写你的proto文件放置路劲

"github.com/micro/go-micro/registry"
//"github.com/micro/go-micro/registry/consul"
"github.com/micro/go-plugins/registry/etcdv3"

)

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() {
// 我这里用的etcd 做为服务发现,如果使用consul可以去掉
reg := etcdv3.NewRegistry(func(op *registry.Options){
op.Addrs = []string{
"127.0.0.1:2379",
}
})

// 修改consul地址,如果是本机,这段代码和后面的那行使用代码都是可以不用的
// reg := consul.NewRegistry(func(op *registry.Options){
// op.Addrs = []string{
// "127.0.0.1:8500",
// }
//})

// Create a new service. Optionally include some options here.
service := micro.NewService(
micro.Registry(reg),
micro.Name("greeter"),
micro.Version("latest"),
//读取命令行
micro.Flags(cli.StringFlag{
Name: "environment",
Usage: "The environment",
}),
//通过 service.Init 来解析参数,附加的处理可以通过 micro.Action 解决
micro.Action(func(c *cli.Context) {
//if c.Bool("run_client") {
// os.Exit(0)
//}
}),
micro.AfterStop(func() error {
log.Println("micro.AfterStop test ...")
return nil
}),
micro.AfterStart(func() error {
log.Println("micro.AfterStart test ...")
return nil
}),
)

// Init will parse the command line flags.
service.Init()

// Register handler
proto.RegisterGreeterHandler(service.Server(), new(Greeter))

// Run the server
if err := service.Run(); err != nil {
fmt.Println(err)
}
}

client.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package main

import (
"context"
"fmt"

micro "github.com/micro/go-micro"
proto "gomicro/protoc" //这里写你的proto文件放置路劲

"github.com/micro/go-micro/registry"
//"github.com/micro/go-micro/registry/consul"
"github.com/micro/go-plugins/registry/etcdv3"
)

func main() {
// 我这里用的etcd 做为服务发现,如果使用consul可以去掉
reg := etcdv3.NewRegistry(func(op *registry.Options){
op.Addrs = []string{
"127.0.0.1:2379",
}
})
// 修改consul地址,如果是本机,这段代码和后面的那行使用代码都是可以不用的
//reg := consul.NewRegistry(func(op *registry.Options){
// op.Addrs = []string{
// "127.0.0.1:8500",
// }
//})

// Create a new service. Optionally include some options here.
service := micro.NewService(micro.Registry(reg),micro.Name("greeter.client"))
service.Init()

// Create new greeter client
greeter := proto.NewGreeterService("greeter", service.Client())

// Call the greeter
rsp, err := greeter.Hello(context.TODO(), &proto.HelloRequest{Name: "John"})
if err != nil {
fmt.Println(err)
}

// Print response
fmt.Println(rsp.Greeting)
}

运行

1
2
go run examples/service/main.go
go run examples/client/main.go