优雅退出注销服务

为什么需要优雅注销服务

当往服务中心注册了服务之后,由于调试,可能会重复注册同一个服务。当时之前服务由于健康检查,并不会立即退出注销,这就会多线多个“重复的服务”

整合优雅退出服务

package consul

import (
"fmt"

"github.com/hashicorp/consul/api"
)
// register.go 工具
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 {
return &Registry{
Host: host,
Port: port,
}
}

func (r *Registry) Register(address string, port int, name string, tags []string, id string) error {
cfg := api.DefaultConfig()
cfg.Address = fmt.Sprintf("%s:%d", r.Host, r.Port)

client, err := api.NewClient(cfg)
if err != nil {
panic(err)
}
//生成对应的检查对象
check := &api.AgentServiceCheck{
// GRPC: fmt.Sprintf("%s:%d", global.AppConf.Grpc.IP, global.AppConf.Grpc.Port),
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)
if err != nil {
panic(err)
}
return nil
}

func (r *Registry) DeRegister(serviceId string) error {
cfg := api.DefaultConfig()
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
}

package main

import (
"fmt"
"github.com/nacos-group/nacos-sdk-go/inner/uuid"
"go.uber.org/zap"
"os"
"os/signal"
"shop_api/good-web/global"
"shop_api/good-web/initialize"
"shop_api/good-web/utils/register/consul"
"syscall"
)
// main.go 优雅退出
func main() {
router := initialize.Routers()

registerClient := consul.NewRegistryClient(global.AppConf.Consul.IP, global.AppConf.Consul.Port)
// 生成UUID
u, err := uuid.NewV4()
if err != nil {
panic("failed new uuid:" + err.Error())
}
serverId := u.String()
err = registerClient.Register(global.AppConf.System.Host, global.AppConf.System.Port,
global.AppConf.System.Name, global.AppConf.System.Tags, serverId)
if err != nil {
panic(err.Error())
}
zap.S().Infof("启动服务器,端口:%d", global.AppConf.System.Port)
// gin会卡住现场
go func() {
if err := router.Run(fmt.Sprintf("%s:%d", global.AppConf.System.Host, global.AppConf.System.Port)); err != nil {
zap.S().Panic(err)
}
}()

//接收终止信号
quit := make(chan os.Signal)
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
<-quit
// 注销服务
if err = registerClient.DeRegister(serverId); err != nil {
zap.S().Info("注销失败")
}
zap.S().Info("注销成功")
}