优化服务退出流程,增加中间件文档

This commit is contained in:
孟帅
2023-05-15 18:37:40 +08:00
parent fdefb42253
commit c511a2e6b3
30 changed files with 335 additions and 97 deletions

View File

@@ -7,9 +7,9 @@ package cmd
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcmd"
"hotgo/internal/service"
"os"
)
var (
@@ -20,17 +20,17 @@ var (
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
service.AuthClient().Start(ctx)
// 退出信号监听
signalListen(ctx, func(sig os.Signal) {
service.AuthClient().Stop(ctx)
})
serverWg.Add(1)
// 信号监听
signalListen(ctx, signalHandlerForOverall)
select {
case <-serverCloseSignal:
// ...
service.AuthClient().Stop(ctx)
serverWg.Done()
}
g.Log().Debug(ctx, "auth successfully closed ..")
return
},
}

View File

@@ -13,8 +13,7 @@ import (
)
var (
serverCloseSignal chan struct{}
Main = &gcmd.Command{
Main = &gcmd.Command{
Description: `默认启动所有服务`,
Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
return All.Func(ctx, parser)
@@ -76,10 +75,10 @@ var (
select {
case <-serverCloseSignal:
// ...
serverWg.Wait()
}
g.Log().Debug(ctx, "service successfully closed ..")
g.Log().Debug(ctx, "all service successfully closed ..")
return
},
}
@@ -89,5 +88,4 @@ func init() {
if err := Main.AddCommand(All, Http, Queue, Cron, Auth, Tools, Help); err != nil {
panic(err)
}
serverCloseSignal = make(chan struct{}, 1)
}

View File

@@ -7,10 +7,10 @@ package cmd
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gcmd"
"hotgo/internal/crons"
"hotgo/internal/service"
"os"
)
var (
@@ -25,17 +25,18 @@ var (
// tcp客户端
service.CronClient().Start(ctx)
// 退出信号监听
signalListen(ctx, func(sig os.Signal) {
service.CronClient().Stop(ctx)
crons.StopALL()
serverCloseSignal <- struct{}{}
})
serverWg.Add(1)
// 信号监听
signalListen(ctx, signalHandlerForOverall)
select {
case <-serverCloseSignal:
// ...
service.CronClient().Stop(ctx)
crons.StopALL()
serverWg.Done()
}
g.Log().Debug(ctx, "cron successfully closed ..")
return
},
}

View File

@@ -3,7 +3,6 @@
// @Copyright Copyright (c) 2023 HotGo CLI
// @Author Ms <133814250@qq.com>
// @License https://github.com/bufanyun/hotgo/blob/master/LICENSE
//
package cmd
import (
@@ -11,6 +10,12 @@ import (
"github.com/gogf/gf/v2/os/gproc"
"hotgo/utility/simple"
"os"
"sync"
)
var (
serverCloseSignal = make(chan struct{}, 1)
serverWg = sync.WaitGroup{}
)
func signalHandlerForOverall(sig os.Signal) {

View File

@@ -10,13 +10,11 @@ import (
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/net/ghttp"
"github.com/gogf/gf/v2/os/gcmd"
"hotgo/internal/crons"
"hotgo/internal/library/addons"
"hotgo/internal/library/casbin"
"hotgo/internal/router"
"hotgo/internal/service"
"hotgo/internal/websocket"
"os"
)
var (
@@ -77,13 +75,20 @@ var (
// https
setSSL(ctx, s)
// 退出信号监听
signalListen(ctx, func(sig os.Signal) {
s.Shutdown()
crons.StopALL()
websocket.Stop()
service.TCPServer().Stop(ctx)
})
serverWg.Add(1)
// 信号监听
signalListen(ctx, signalHandlerForOverall)
go func() {
select {
case <-serverCloseSignal:
websocket.Stop()
service.TCPServer().Stop(ctx)
s.Shutdown() // 主服务建议放在最后一个关闭
g.Log().Debug(ctx, "http successfully closed ..")
serverWg.Done()
}
}()
// Just run the server.
s.Run()

View File

@@ -25,12 +25,14 @@ var (
g.Log().Debug(ctx, "start queue consumer success..")
})
serverWg.Add(1)
// 信号监听
signalListen(ctx, signalHandlerForOverall)
select {
case <-serverCloseSignal:
// ...
serverWg.Done()
}
g.Log().Debug(ctx, "queue successfully closed ..")

View File

@@ -7,7 +7,9 @@ package consts
import "github.com/gogf/gf/v2/util/gconv"
// RequestEncryptKey 请求加密密钥用于敏感数据加密16位字符前后端需保持一致。安全起见请修改此值
// RequestEncryptKey
// 请求加密密钥用于敏感数据加密16位字符前后端需保持一致
// 安全起见,生产环境运行时请注意修改
var RequestEncryptKey = []byte("f080a463654b2279")
// 配置数据类型

View File

@@ -27,6 +27,7 @@ func Build(ctx context.Context, sk Skeleton, conf *model.BuildAddonConfig) (err
"@{.description}": sk.Description,
"@{.author}": sk.Author,
"@{.version}": sk.Version,
"@{.hgVersion}": consts.VersionApp, // HG 版本
}
)

View File

@@ -195,7 +195,9 @@ func (client *Client) connect() {
reconnect:
conn := client.dial()
if conn == nil {
client.Logger.Debugf(client.Ctx, "client dial failed")
if !client.stopFlag {
client.Logger.Debugf(client.Ctx, "client dial failed")
}
return
}
@@ -311,6 +313,11 @@ func (client *Client) Stop() {
client.Close()
}
// IsStop 是否已停止
func (client *Client) IsStop() bool {
return client.stopFlag
}
// Destroy 销毁当前连接
func (client *Client) Destroy() {
client.stopCron()

View File

@@ -294,6 +294,11 @@ func (server *Server) Close() {
server.wgLn.Wait()
}
// IsClose 服务是否关闭
func (server *Server) IsClose() bool {
return server.closeFlag
}
// Write 向指定客户端发送消息
func (server *Server) Write(conn *gtcp.Conn, data interface{}) (err error) {
if server.closeFlag {

View File

@@ -99,6 +99,8 @@ func Logout(r *ghttp.Request) (err error) {
claims, err := parseToken(ctx, header)
if err != nil {
g.Log().Debugf(ctx, "logout parseToken err:%+v", err)
err = errorLogin
return
}
@@ -138,10 +140,13 @@ func ParseLoginUser(r *ghttp.Request) (user *model.Identity, err error) {
claims, err := parseToken(ctx, header)
if err != nil {
g.Log().Debugf(ctx, "parseToken err:%+v", err)
err = errorLogin
return
}
var (
// 认证key
authKey = GetAuthKey(header)
// 登录token
tokenKey = GetTokenKey(claims.App, authKey)
@@ -285,7 +290,7 @@ func GetAuthorization(r *ghttp.Request) string {
// GetAuthKey 认证key
func GetAuthKey(token string) string {
return gmd5.MustEncryptString(token)
return gmd5.MustEncryptString("hotgo" + token)
}
// GetTokenKey 令牌缓存key

View File

@@ -227,18 +227,18 @@ func (s *sAdminMember) UpdateMobile(ctx context.Context, in adminin.MemberUpdate
return err
}
var memberInfo *entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&memberInfo); err != nil {
var mb *entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&mb); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if memberInfo == nil {
if mb == nil {
err = gerror.New("用户信息不存在")
return err
}
if memberInfo.Mobile == in.Mobile {
if mb.Mobile == in.Mobile {
err = gerror.New("新旧手机号不能一样")
return
}
@@ -249,10 +249,10 @@ func (s *sAdminMember) UpdateMobile(ctx context.Context, in adminin.MemberUpdate
}
// 存在原绑定号码,需要进行验证
if memberInfo.Mobile != "" {
if mb.Mobile != "" {
err = service.SysSmsLog().VerifyCode(ctx, sysin.VerifyCodeInp{
Event: consts.SmsTemplateBind,
Mobile: memberInfo.Mobile,
Mobile: mb.Mobile,
Code: in.Code,
})
if err != nil {
@@ -264,8 +264,7 @@ func (s *sAdminMember) UpdateMobile(ctx context.Context, in adminin.MemberUpdate
dao.AdminMember.Columns().Mobile: in.Mobile,
}
_, err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Data(update).Update()
if err != nil {
if _, err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Data(update).Update(); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
@@ -281,13 +280,13 @@ func (s *sAdminMember) UpdateProfile(ctx context.Context, in adminin.MemberUpdat
return err
}
var memberInfo *entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&memberInfo); err != nil {
var mb *entity.AdminMember
if err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Scan(&mb); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
if memberInfo == nil {
if mb == nil {
err = gerror.New("用户信息不存在")
return err
}
@@ -302,8 +301,7 @@ func (s *sAdminMember) UpdateProfile(ctx context.Context, in adminin.MemberUpdat
dao.AdminMember.Columns().Address: in.Address,
}
_, err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Data(update).Update()
if err != nil {
if _, err = dao.AdminMember.Ctx(ctx).Where("id", memberId).Data(update).Update(); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return err
}
@@ -718,7 +716,9 @@ func (s *sAdminMember) MemberLoginStat(ctx context.Context, in adminin.MemberLog
// GetIdByCode 通过邀请码获取用户ID
func (s *sAdminMember) GetIdByCode(ctx context.Context, in adminin.GetIdByCodeInp) (res *adminin.GetIdByCodeModel, err error) {
err = dao.AdminMember.Ctx(ctx).Fields(adminin.GetIdByCodeModel{}).Where("invite_code", in.Code).Scan(&res)
if err = dao.AdminMember.Ctx(ctx).Fields(adminin.GetIdByCodeModel{}).Where("invite_code", in.Code).Scan(&res); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
}
return
}
@@ -728,6 +728,9 @@ func (s *sAdminMember) Select(ctx context.Context, in adminin.MemberSelectInp) (
Fields("id as value,real_name as label,username,avatar").
Handler(handler.FilterAuthWithField("id")).
Scan(&res)
if err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
}
return
}

View File

@@ -12,7 +12,6 @@ import (
"hotgo/internal/dao"
"hotgo/internal/library/token"
"hotgo/internal/model"
"hotgo/internal/model/do"
"hotgo/internal/model/entity"
"hotgo/internal/model/input/adminin"
"hotgo/internal/model/input/sysin"
@@ -255,16 +254,6 @@ func (s *sAdminSite) handleLogin(ctx context.Context, mb *entity.AdminMember) (r
return nil, err
}
update := do.AdminMember{
LastActiveAt: user.LoginAt,
}
// 更新登录信息
if _, err = dao.AdminMember.Ctx(ctx).Data(update).Where(do.AdminMember{Id: mb.Id}).Update(); err != nil {
err = gerror.Wrap(err, consts.ErrorORM)
return
}
res = &adminin.LoginModel{
Username: user.Username,
Id: user.Id,

View File

@@ -20,9 +20,9 @@ func (s *sHook) accessLog(r *ghttp.Request) {
if r.IsFileRequest() {
return
}
var ctx = contexts.Detach(r.Context())
modelCtx := contexts.Get(ctx)
if modelCtx == nil {
if contexts.Get(ctx) == nil {
return
}

View File

@@ -79,7 +79,6 @@ func (s *sHook) lastAdminActive(r *ghttp.Request) {
_, err := g.Model("admin_member").
Ctx(ctx).
Where("id", member.Id).
WhereLT("last_active_at", gtime.Now()).
Data(g.Map{"last_active_at": gtime.Now()}).
Update()
if err != nil {

View File

@@ -101,16 +101,16 @@ func responseJson(r *ghttp.Request) {
if err = r.GetError(); err != nil {
// 记录到自定义错误日志文件
g.Log().Warningf(ctx, "exception:%v", err)
g.Log().Stdout(false).Printf(ctx, "exception:%v", err)
code = gerror.Code(err).Code()
// 是否输出错误到页面
if g.Cfg().MustGet(ctx, "hotgo.debug", true).Bool() {
message = err.Error()
message = gerror.Current(err).Error()
data = charset.ParseErrStack(err)
} else {
message = consts.ErrorMessage(err)
message = consts.ErrorMessage(gerror.Current(err))
}
} else {
data = r.GetHandlerResponse()

View File

@@ -105,7 +105,7 @@ func (s *sSysLog) AutoLog(ctx context.Context) error {
var err error
defer func() {
if err != nil {
panic(err)
g.Log().Error(ctx, "autoLog err:%+v", err)
}
}()

View File

@@ -75,7 +75,7 @@ func (s *sAuthClient) Start(ctx context.Context) {
// Stop 停止服务
func (s *sAuthClient) Stop(ctx context.Context) {
if s.client != nil {
if s.client != nil && !s.client.IsStop() {
s.client.Stop()
g.Log().Debug(ctx, "AuthClient stop..")
}

View File

@@ -76,7 +76,7 @@ func (s *sCronClient) Start(ctx context.Context) {
// Stop 停止服务
func (s *sCronClient) Stop(ctx context.Context) {
if s.client != nil {
if s.client != nil && !s.client.IsStop() {
s.client.Stop()
g.Log().Debug(ctx, "CronClient stop..")
}

View File

@@ -53,15 +53,17 @@ func (s *sTCPServer) Start(ctx context.Context) {
})
// 服务监听
if err := s.serv.Listen(); err != nil {
g.Log().Warningf(ctx, "TCPServer Listen err:%v", err)
if err = s.serv.Listen(); err != nil {
if !s.serv.IsClose() {
g.Log().Warningf(ctx, "TCPServer Listen err:%v", err)
}
}
})
}
// Stop 关闭服务
func (s *sTCPServer) Stop(ctx context.Context) {
if s.serv != nil {
if s.serv != nil && !s.serv.IsClose() {
s.serv.Close()
g.Log().Debug(ctx, "TCPServer stop..")
}

View File

@@ -2,11 +2,9 @@ package adminin
import (
"context"
"github.com/gogf/gf/v2/encoding/gbase64"
"github.com/gogf/gf/v2/frame/g"
"github.com/gogf/gf/v2/os/gtime"
"hotgo/internal/consts"
"hotgo/utility/encrypt"
"hotgo/utility/simple"
)
// RegisterInp 账号注册
@@ -20,18 +18,11 @@ type RegisterInp struct {
func (in *RegisterInp) Filter(ctx context.Context) (err error) {
// 解密密码
str, err := gbase64.Decode([]byte(in.Password))
password, err := simple.DecryptText(in.Password)
if err != nil {
return err
}
str, err = encrypt.AesECBDecrypt(str, consts.RequestEncryptKey)
if err != nil {
return err
}
password := string(str)
if err = g.Validator().Data(password).Rules("password").Messages("密码长度在6~18之间").Run(ctx); err != nil {
return
}

View File

@@ -12,7 +12,7 @@
### 迁移或安装
1安装 HotGo (2.1.4及以上)
1安装 HotGo (@{.hgVersion}及以上)
项目介绍https://github.com/bufanyun/hotgo

View File

@@ -18,20 +18,30 @@ import (
"hotgo/utility/encrypt"
)
// DecryptText 解密文本
func DecryptText(text string) (string, error) {
str, err := gbase64.Decode([]byte(text))
if err != nil {
return "", err
}
str, err = encrypt.AesECBDecrypt(str, consts.RequestEncryptKey)
if err != nil {
return "", err
}
return string(str), nil
}
// CheckPassword 检查密码
func CheckPassword(input, salt, hash string) (err error) {
// 解密密码
password, err := gbase64.Decode([]byte(input))
password, err := DecryptText(input)
if err != nil {
return err
}
password, err = encrypt.AesECBDecrypt(password, consts.RequestEncryptKey)
if err != nil {
return err
}
if hash != gmd5.MustEncryptString(string(password)+salt) {
if hash != gmd5.MustEncryptString(password+salt) {
err = gerror.New("用户密码不正确")
return
}