微服务之注册中心

什么是注册中心

注册中心的作用一句话概括就是存放和调度服务,实现服务和注册中心,服务和服务之间的相互通信

常见的几种注册中心

名称 优点 缺点 接口 一致性算法
zookeeper 1. 功能强大,不仅仅是服务发现2、提供watch机制,实时获取服务状态3、支持dubbo等框架 1、不支健康检查2、需要在服务中集成sdk,复杂度高3、不支持多数据中心 sdk Paxos
consul 1、简单易用,不需要集成sdk2、自带健康检查3、支持多数据中心4、提供web管理界面 1、不能实时获取服务msg变化 http/dns Raft
etcd 1、简单易用、不需要集成sdk2、可配置性强 1、没有健康检查2、需要配合第三方工具一起完成服务发现3、不支持多数据中心 http Raft

consul的安装和配置

Docker安装

# 8500 http端口 8600 dns端口
docker run -d -p 8500:8500 -p 8300:8300 -p 8301:8301 -p 8302:8302 -p 8600:8600/udp consul consul agent -dev -client=0.0.0.0

webui:访问localhost:8500

访问dns

linux: 安装dig

yum install bind-utils

dig @192.168.28.145 -p 8600 consul.service.consul SRV

go整合consul

注册服务

func Register(address, name string, port int, tags []string, id string) {
cfg := api.DefaultConfig()
cfg.Address = "192.168.28.145:8500"
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}

// 生成对应的检查对象
check := &api.AgentServiceCheck{
HTTP: "http://192.168.28.145:8021/health",
Timeout: "5s",
Interval: "5s",
DeregisterCriticalServiceAfter: "10",
}
// 生成注册对象
registerion := &api.AgentServiceRegistration{
Name: name,
ID: id,
Port: port,
Tags: tags,
Address: address,
Check: check,
}
err = client.Agent().ServiceRegister(registerion)
if err != nil {
panic(err)
}
}

获得所有的服务

func AllService() {
cfg := api.DefaultConfig()
cfg.Address = "192.168.28.145:8500"
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}
data, err := client.Agent().Services()
for k, _ := range data {
fmt.Println(k)
}
}

服务过滤

func FilterService() {
cfg := api.DefaultConfig()
cfg.Address = "192.168.28.145:8500"
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}
data, err := client.Agent().ServicesWithFilter(`Service=="user-web"`)
for k, _ := range data {
fmt.Println(k)
}
}

grpc整合

import (
"google.golang.org/grpc/health"
"google.golang.org/grpc/health/grpc_health_v1"
)
//注册服务健康检查
grpc_health_v1.RegisterHealthServer(server, health.NewServer())

grpc服务注册

func ConsulRegister(address, name string, port int, tags []string, id string) error {
cfg := api.DefaultConfig()
cfg.Address = global.AppConf.Consul.IP
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}

// 生成对应的检查对象
check := &api.AgentServiceCheck{
GRPC: fmt.Sprintf("http://%s:50051/health", global.AppConf.Consul.IP),
Timeout: "5s",
Interval: "5s",
DeregisterCriticalServiceAfter: "10",
}
// 生成注册对象
registerion := &api.AgentServiceRegistration{
Name: name,
ID: id,
Port: port,
Tags: tags,
Address: address,
Check: check,
}
err = client.Agent().ServiceRegister(registerion)
if err != nil {
return err
}
return nil
}

gin集成consul


func GetUserListHandler(c *gin.Context) {
// 从注册服务中心拉取
cfg := api.DefaultConfig()
cfg.Address = fmt.Sprintf("%s:%d", global.AppConf.Consul.IP, global.AppConf.Consul.Port)
userSrcHost := ""
userSrvPort := 0
client, err := api.NewClient(cfg)
if err != nil {
zap.S().Errorw("[GetUserList] 查询 【用户列表失败,拉取服务失败】err:%s", err.Error())
return
}
data, err := client.Agent().ServicesWithFilter(fmt.Sprintf("Service==%s", global.AppConf.System.Name))
if err != nil {
zap.S().Errorw("[GetUserList] 查询 【查询User服务失败】err:%s", err.Error())
return
}
for _, service := range data {
userSrcHost = service.Address
userSrvPort = service.Port
}

userConn, err := grpc.Dial(fmt.Sprintf("%s:%d", userSrcHost, userSrvPort), grpc.WithTransportCredentials(insecure.NewCredentials()))
//userConn, err := grpc.Dial(fmt.Sprintf("%s:%d", setting.Conf.GrpcServer.Host, setting.Conf.GrpcServer.Port), grpc.WithInsecure())
if err != nil {
println(err.Error())
zap.S().Errorw("[GetUserList] 连接 【用户服务失败】", "msg", err.Error())
}
claims, _ := c.Get("claims")
currentUser := claims.(*jwt_request.CustomClaims)
zap.S().Infof("访问用户:%d", currentUser.ID)
userClient := proto.NewUserClient(userConn)
pn := c.DefaultQuery("pn", "0")
pnInt, _ := strconv.Atoi(pn)
pSize := c.DefaultQuery("psize", "0")
pSizeInt, _ := strconv.Atoi(pSize)
rsp, err := userClient.GetUserList(context.Background(), &proto.PageInfo{
Pn: uint32(pnInt),
PSize: uint32(pSizeInt),
})
if err != nil {
zap.S().Errorw("[GetUserList] 查询 【用户列表失败】")
convert.HandleGrpcError2Http(err, c)
return
}
result := make([]response.UserResponse, 0)
for _, value := range rsp.Data {
result = append(result, response.UserResponse{
Id: value.Id,
NickName: value.Nickname,
Birthday: response.JsonTime(time.Unix(int64(value.BirthDay), 0)),
Gender: value.Gender,
Mobile: value.Mobile,
})
}
R.SuccessWithDetailed(c, "获取用户列表成功", result)
}