本文介绍微服务核心模块,服务注册与发现。
什么是服务注册
将服务运行的IP与端口发送到服务中心注册,注册中心将运行服务的节点信息记录。
什么是服务发现
当需要调用某个服务提供的接口时,去注册中心,获取到对应服务的节点信息,发起请求调用服务。
注册中心
常用的服务注册中心有Etcd,Consul,Zookeeper等。下面分别介绍
目录结构
1 | soa |
Serivce
公共的服务定义
1 | package service |
Etcd
ETCD是一个高可用的分布式键值数据库,可用于共享配置、服务的注册和发现。ETCD采用Raft一致性算法,基于Go语言实现。ETCD作为后起之秀,又非常大的优势。
- 部署
通过docker 部署1
2
3
4
5
6
7
8
9
10
11// 启动一个服务
docker run -d -p 2379:2379 -p 2380:2380 --name etcd-server quay.io/coreos/etcd:v3.3.20
// 进入服务内部
docker exec -ti etcd-server /bin/sh
// 将一个为hello的key,设置为world
etcdctl set hello world
// 获取
etcdctl get hello
安装官方包
1 | go get github.com/coreos/etcd/client |
- Demo
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
53package etcd
import (
"context"
"fmt"
"github.com/coreos/etcd/client"
"github.com/ebar-go/ego/component/soa/service"
"net"
"strconv"
)
var instance client.Client
// InitClient 初始化Client
func InitClient(config client.Config) error {
var err error
instance , err = client.New(config)
return err
}
// Register 服务注册
func Register(node service.Node) error {
kapi := client.NewKeysAPI(instance)
key := node.Name + "/" + node.ID
val := net.JoinHostPort(node.Address, strconv.Itoa(node.Port))
resp, err := kapi.Set(context.Background(), key, val, nil)
fmt.Println(resp)
return err
}
// Deregister 服务注销
func Deregister(node service.Node) error {
kapi := client.NewKeysAPI(instance)
key := node.Name + "/" + node.ID
resp, err := kapi.Delete(context.Background(), key, nil)
fmt.Println(resp)
return err
}
// Discover 服务发现
func Discover(name string) error {
kapi := client.NewKeysAPIWithPrefix(instance, name)
resp, err := kapi.Get(context.Background(), "*", nil)
fmt.Println(resp)
// TODO 待完成,因为我用docker拉取3.3.13版本以上的镜像,死都拉不下来。。特么的
return err
}
Consul
Consul是一个高可用的分布式服务注册中心,由HashiCorp公司推出,Golang实现的开源共享的服务工具。Consul在分布式服务注册与发现方面有自己的特色,解决方案更加“一站式”,不再需要依赖其他工具。
- 部署
通过docker部署1
docker run -d -p 8500:8500 --name consul-server consul agent -server -bootstrap -ui -client='0.0.0.0'
安装扩展包
1 | go get github.com/hashicorp/consul/api |
- Demo
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
76/**
集成consul组件,包含实例化consul客户端,服务发现,服务注册,服务注销,负载均衡等方法
*/
package consul
import (
"fmt"
"github.com/ebar-go/ego/component/soa/service"
consulapi "github.com/hashicorp/consul/api"
)
var client *consulapi.Client
// InitClient 初始化consul客户端
func InitClient(config *consulapi.Config) error {
var err error
client, err = consulapi.NewClient(config)
return err
}
// DefaultConfig 默认配置
func DefaultConfig() *consulapi.Config {
return consulapi.DefaultConfig()
}
// Discover 服务发现
func Discover(name string) (*service.Group, error) {
services, _, err := client.Health().Service(name, "", true, &consulapi.QueryOptions{})
if err != nil {
return nil, fmt.Errorf("service: %s not found,%s", name, err.Error())
}
if len(services) == 0 {
return nil, fmt.Errorf("service name : %s not found", name)
}
group := new(service.Group)
for _, item := range services {
group.Add(service.Node{
ID: item.Service.ID,
Name: item.Service.Service,
Address: item.Service.Address,
Port: item.Service.Port,
Tags: item.Service.Tags,
})
}
return group, nil
}
// Register 注册服务
func Register(node service.Node) error {
registration := new(consulapi.AgentServiceRegistration)
registration.ID = node.ID
registration.Name = node.Name
registration.Port = node.Port
registration.Tags = node.Tags
registration.Address = node.Address
check := new(consulapi.AgentServiceCheck)
check.HTTP = fmt.Sprintf("http://%s:%d%s", registration.Address, registration.Port, "/check")
check.Timeout = "3s"
check.Interval = "3s"
check.DeregisterCriticalServiceAfter = "30s" //check失败后30秒删除本服务
registration.Check = check
return client.Agent().ServiceRegister(registration)
}
// Deregister 注销服务
func Deregister(node service.Node) error {
return client.Agent().ServiceDeregister(node.ID)
}
- 本文作者: Hongker
- 本文链接: https://hongker.github.io/2020/04/12/service-register-discover/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!