mirror of
https://github.com/ZxwyWebSite/lx-source.git
synced 2025-05-23 21:37:42 +08:00
157 lines
4.8 KiB
Go
157 lines
4.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"io/fs"
|
|
"lx-source/src/env"
|
|
"lx-source/src/server"
|
|
"net/http"
|
|
"os"
|
|
"os/signal"
|
|
"strings"
|
|
"sync"
|
|
"sync/atomic"
|
|
"syscall"
|
|
"time"
|
|
|
|
"github.com/ZxwyWebSite/ztool"
|
|
"github.com/ZxwyWebSite/ztool/logs"
|
|
"github.com/gin-gonic/gin"
|
|
)
|
|
|
|
// 初始化
|
|
func init() {
|
|
ztool.Cmd_FastPrint(ztool.Str_FastConcat(`
|
|
__ __ __ ______ ______ __ __ ____ ______ ______
|
|
/ / / / / / / ____/ / __ / / / / / / __ \ / ____/ / ____/
|
|
/ / / /_/ / __ / /___ / / / / / / / / / /_/ / / / / /___
|
|
/ / \_\ \ /_/ /___ / / / / / / / / / / ___/ / / / ____/
|
|
/ /___ / / / / ____/ / / /_/ / / /_/ / / / \ / /___ / /___
|
|
/_____/ /_/ /_/ /_____/ /_____/ /_____/ /_/ \_\ /_____/ /_____/
|
|
=======================================================================
|
|
Version: `, env.Version, ` Github: https://github.com/ZxwyWebSite/lx-source
|
|
`, "\n"))
|
|
env.RunPath, _ = os.Getwd()
|
|
var confPath string
|
|
flag.StringVar(&confPath, `c`, ztool.Str_FastConcat(env.RunPath, `/data/conf.ini`), `指定配置文件路径`)
|
|
etag := flag.String(`e`, ``, `扩展启动参数`)
|
|
perm := flag.Uint(`p`, 0, `自定义文件权限(8进制前面加0)`)
|
|
flag.Parse()
|
|
if perm != nil && *perm != 0 {
|
|
ztool.Fbj_DefPerm = fs.FileMode(*perm)
|
|
fp := env.Loger.NewGroup(`FilePerm`)
|
|
// if ztool.Fbj_DefPerm > 777 {
|
|
// fp.Fatal(`请在实际权限前面加0`)
|
|
// }
|
|
fp.Info(`设置默认文件权限为 %o (%v)`, *perm, ztool.Fbj_DefPerm).Free()
|
|
}
|
|
env.Cfg.MustInit(confPath)
|
|
parseEtag(etag)
|
|
// fmt.Printf("%+v\n", env.Config)
|
|
env.Loger.NewGroup(`ServHello`).Info(`欢迎使用 LX-SOURCE 洛雪音乐自定义源`).Free()
|
|
if !env.Config.Main.Debug {
|
|
gin.SetMode(gin.ReleaseMode)
|
|
} else {
|
|
logs.Levell = logs.LevelDebu // logs.Level = 3
|
|
env.Loger.NewGroup(`DebugMode`).Debug(`已开启调试模式, 将输出更详细日志 (配置文件中 [Main].Debug 改为 false 关闭)`).Free()
|
|
}
|
|
genAuth()
|
|
if env.Config.Main.SysLev {
|
|
sl := env.Loger.NewGroup(`(beta)SysLev`)
|
|
if err := ztool.Sys_SetPriorityLev(ztool.Sys_GetPid(), ztool.Sys_PriorityHighest); err != nil {
|
|
sl.Error(`系统优先级设置失败: %v`, err)
|
|
} else {
|
|
sl.Warn(`成功设置较高优先级,此功能可能导致系统不稳定`)
|
|
}
|
|
sl.Free()
|
|
}
|
|
if env.Config.Main.Timeout != env.DefCfg.Main.Timeout {
|
|
ztool.Net_client.Timeout = time.Second * time.Duration(env.Config.Main.Timeout) // 自定义请求超时
|
|
env.Loger.NewGroup(`InitNet`).Info(`请求超时已设为 %s`, ztool.Net_client.Timeout).Free()
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
defer env.Defer.Do()
|
|
// 初始化基础功能
|
|
initMain()
|
|
|
|
// 载入必要模块
|
|
env.Inits.Do()
|
|
env.Loger.NewGroup(`ServInit`).Info(`服务端启动, 监听地址 %s`, strings.Join(env.Config.Main.Listen, `|`)).Free()
|
|
loadFileLoger()
|
|
env.Defer.Add(env.Tasker.Run(env.Loger)) // wait
|
|
|
|
// 启动Http服务
|
|
listenAndServe(server.InitRouter(), env.Config.Main.Listen)
|
|
}
|
|
|
|
// 监听多端口
|
|
func listenAndServe(handler http.Handler, addrs []string) {
|
|
// 前置检测
|
|
length := len(addrs)
|
|
ss := env.Loger.NewGroup(`ServStart`)
|
|
if length == 0 {
|
|
ss.Fatal(`监听地址列表为空`)
|
|
}
|
|
// ss.Info(`服务端启动,请稍候...`)
|
|
srvlist := make(map[int]*http.Server, length) // 伪数组,便于快速删除数据
|
|
lock := new(sync.Mutex)
|
|
var failnum int32
|
|
length32 := int32(length)
|
|
// 启动服务
|
|
for i := 0; i < length; i++ {
|
|
lock.Lock()
|
|
srvlist[i] = &http.Server{Addr: addrs[i], Handler: handler}
|
|
lock.Unlock()
|
|
go func(n int) {
|
|
server := srvlist[n]
|
|
// ss.Info(`开始监听 %v`, server.Addr)
|
|
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
ss.Error(`监听%q失败: %s`, server.Addr, err) // 监听":1011"失败: http: Server closed
|
|
fn := atomic.AddInt32(&failnum, 1)
|
|
if fn == length32 {
|
|
ss.Fatal(`所有地址监听失败,程序被迫退出`)
|
|
}
|
|
lock.Lock()
|
|
delete(srvlist, n)
|
|
lock.Unlock()
|
|
}
|
|
}(i)
|
|
}
|
|
// time.Sleep(time.Millisecond * 300)
|
|
// if len(srvlist) == 0 {
|
|
// ss.Fatal(`所有地址监听失败,程序被迫退出`)
|
|
// }
|
|
// ss.Free()
|
|
// 安全退出
|
|
quit := make(chan os.Signal, 1)
|
|
signal.Notify(quit, os.Interrupt, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
|
|
<-quit
|
|
sc := env.Loger.NewGroup(`ServClose`)
|
|
sc.Info(`等待结束活动连接...`)
|
|
// 停止服务
|
|
var unsafenum int32
|
|
wg := new(sync.WaitGroup)
|
|
for i := range srvlist {
|
|
wg.Add(1)
|
|
go func(n int) {
|
|
server := srvlist[n]
|
|
ctx, cancel := context.WithTimeout(context.Background(), 8*time.Second)
|
|
if err := server.Shutdown(ctx); err != nil {
|
|
sc.Warn(`连接%q未安全退出: %s`, server.Addr, err) // 连接":1011"未安全退出: timeout
|
|
atomic.AddInt32(&unsafenum, 1)
|
|
}
|
|
cancel()
|
|
wg.Done()
|
|
}(i)
|
|
}
|
|
wg.Wait()
|
|
if unsafenum != 0 {
|
|
sc.Warn(`未安全退出 :(`)
|
|
} else {
|
|
sc.Info(`已安全退出 :)`)
|
|
}
|
|
}
|