gin-注册中心注册-符合go语言的设计理念的鸭子类型(重要)
一.目录
1. 新建目录
goods-web/utils/register/consul/register.go
2.目录截图
二.注册配置
1. 概述
1. 创建目录:为了后续支持其他注册中心,保证程序的拓展性,目前只支持consul
2. 利用go语言的特性,实现struct和interfact类型,符合go语言的设计理念的鸭子类型
2. register.go配置(重要)
package consul
import (
"fmt"
"github.com/hashicorp/consul/api"
)
type Registry struct {
Host string
Port int
}
type RegistryClient interface {
Register(address string, port int, name string, tags []string, id string) error
DeRegister(serviceId string) error
}
func NewRegistryClient(host string, port int) RegistryClient {
//只要是实现了接口中的Register,DeRegister,就可以返回struct:Registry
return &Registry{host, port}
}
func (r *Registry) DeRegister(serviceId string) error {
return nil
}
func (r *Registry) Register(address string, port int, name string, tags []string, id string) error {
//服务注册
cfg := api.DefaultConfig()
//注册中心的地址
//cfg.Address = "192.168.1.103:8500"
cfg.Address = fmt.Sprintf("%s:%d", r.Host, r.Port)
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}
//生成对应的检查对象
check := &api.AgentServiceCheck{
HTTP: fmt.Sprintf("%s:%d/health", address, port),
Timeout: "5s",
Interval: "5s",
DeregisterCriticalServiceAfter: "10s",
}
//生成注册对象
registration := new(api.AgentServiceRegistration)
registration.Name = name
registration.ID = id
registration.Port = port
registration.Tags = tags
registration.Address = address
registration.Check = check
//注册
err = client.Agent().ServiceRegister(registration)
//client.Agent().ServiceDeregister()
if err != nil {
panic(err)
}
return nil
}
3.使用
main中
register_client := consul.NewRegistryClient(global.ServerConfig.ConsulInfo.Host, global.ServerConfig.ConsulInfo.Port)
err := register_client.Register(global.ServerConfig.Host, global.ServerConfig.Port, global.ServerConfig.Name, global.ServerConfig.Tags, serviceId)
if err != nil {
zap.S().Panic("【goods-web】注册失败")
}
三.取消注册
1.配置register.go
package consul
import (
"fmt"
"github.com/hashicorp/consul/api"
)
type Registry struct {
Host string
Port int
}
type RegistryClient interface {
Register(address string, port int, name string, tags []string, id string) error
DeRegister(serviceId string) error
}
func NewRegistryClient(host string, port int) RegistryClient {
//只要是实现了接口中的Register,DeRegister,就可以返回struct:Registry
return &Registry{host, port}
}
func (r *Registry) DeRegister(serviceId string) error {
//服务注册
cfg := api.DefaultConfig()
//注册中心的地址
//cfg.Address = "192.168.1.103:8500"
cfg.Address = fmt.Sprintf("%s:%d", r.Host, r.Port)
client, err := api.NewClient(cfg)
if err != nil {
return err
}
err = client.Agent().ServiceDeregister(serviceId)
return err
}
func (r *Registry) Register(address string, port int, name string, tags []string, id string) error {
//服务注册
cfg := api.DefaultConfig()
//注册中心的地址
//cfg.Address = "192.168.1.103:8500"
cfg.Address = fmt.Sprintf("%s:%d", r.Host, r.Port)
client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}
//生成对应的检查对象
check := &api.AgentServiceCheck{
HTTP: fmt.Sprintf("http://%s:%d/health", address, port),
Timeout: "5s",
Interval: "5s",
DeregisterCriticalServiceAfter: "10s",
}
//生成注册对象
registration := new(api.AgentServiceRegistration)
registration.Name = name
registration.ID = id
registration.Port = port
registration.Tags = tags
registration.Address = address
registration.Check = check
//注册
err = client.Agent().ServiceRegister(registration)
//client.Agent().ServiceDeregister()
if err != nil {
panic(err)
}
return nil
}
2. 使用 main.go
//放到携程中去
go func() {
if err := Router.Run(fmt.Sprintf(":%d", global.ServerConfig.Port)); err != nil {
zap.S().Panic("启动失败:", err.Error())
}
}()
// 接受终止信号
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
if err = registerClient.DeRegister(serviceId); err != nil {
zap.S().Panic("注销失败", err.Error())
} else {
zap.S().Panic("注销成功")
}
完整代码
package main
import (
"fmt"
"github.com/satori/go.uuid"
"github.com/spf13/viper"
"go.uber.org/zap"
"mxshop-api/goods-web/global"
"mxshop-api/goods-web/utils"
"mxshop-api/goods-web/utils/register/consul"
"os"
"os/signal"
"syscall"
"mxshop-api/goods-web/initialize"
)
func main() {
//初始化logger
initialize.InitLogger()
//初始化配置文件
initialize.InitConfig()
//初始化routes
Router := initialize.Routers()
//初始化翻译
if err := initialize.InitTrans("zh"); err != nil {
panic(err)
}
//初始化srv的链接
initialize.InitSrvConn()
//如果是本地开发环境,端口固定
viper.AutomaticEnv()
debug := viper.GetBool("MXSHOP_DEBUG")
fmt.Println(debug)
if !debug {
port, err := utils.GetFreePort()
if err == nil {
global.ServerConfig.Port = port
}
}
/*
1. S()可以获取一个全局的sugar,可以让我们自己设置一个全局的logger
2. 日志是分级别的,debug, info , warn, error, fetal
3. S函数和L函数很有用, 提供了一个全局的安全访问logger的途径
*/
//生成uuid值,并转换为str
serviceId := fmt.Sprintf("%s", uuid.NewV4())
registerClient := consul.NewRegistryClient(global.ServerConfig.ConsulInfo.Host, global.ServerConfig.ConsulInfo.Port)
err := registerClient.Register(global.ServerConfig.Host, global.ServerConfig.Port, global.ServerConfig.Name, global.ServerConfig.Tags, serviceId)
if err != nil {
zap.S().Panic("【goods-web】注册失败")
}
zap.S().Infof("启动服务")
//port := 8881
//放到携程中去
go func() {
if err := Router.Run(fmt.Sprintf(":%d", global.ServerConfig.Port)); err != nil {
zap.S().Panic("启动失败:", err.Error())
}
}()
// 接受终止信号
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
if err = registerClient.DeRegister(serviceId); err != nil {
zap.S().Panic("注销失败", err.Error())
} else {
zap.S().Panic("注销成功")
}
}


浙公网安备 33010602011771号