Files
bl/logic/main.go
xinian 0daeb70900
All checks were successful
ci/woodpecker/push/my-first-workflow Pipeline was successful
fix: 修复日志格式化字符串错误和任务奖励逻辑
2026-04-10 10:28:22 +08:00

182 lines
4.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"fmt"
"log"
"os"
"runtime"
"strconv"
"strings"
"time"
_ "github.com/gogf/gf/contrib/nosql/redis/v2"
"github.com/gogf/gf/v2/os/gcmd"
"github.com/gogf/gf/v2/os/gproc"
"blazing/logic/service/player"
"blazing/cool"
"github.com/shirou/gopsutil/v4/mem"
"blazing/modules/base/service"
blservice "blazing/modules/player/service"
"net/http"
_ "net/http/pprof"
)
// PprofWeb 启动pprof性能分析web服务
// PprofWeb 启动pprof web服务仅重试2个端口保证监听成功
func PprofWeb() {
// 开启pprof跟踪
runtime.SetMutexProfileFraction(1)
runtime.SetBlockProfileRate(1)
// 定义2个重试端口主端口9909 + 备用端口9910
ports := []int{9909, 9910}
// 遍历端口尝试监听
for _, port := range ports {
addr := ":" + strconv.Itoa(port)
fmt.Printf("[INFO] 尝试启动pprof服务监听端口: %d\n", port)
// 尝试监听并处理错误
err := http.ListenAndServe(addr, nil)
// 只有端口被占用等致命错误才重试下一个端口
if err != nil {
fmt.Printf("[WARN] 端口%d监听失败: %v\n", port, err)
continue
}
// 监听成功则直接返回
return
}
// 所有端口都失败时的兜底
errMsg := "[FATAL] 端口9909/9910均监听失败pprof服务启动失败"
fmt.Println(errMsg)
// 可选根据业务需求决定是否panic
// panic(errMsg)
}
func cleanup() {
fmt.Println("执行优雅清理资源...")
player.Mainplayer.Range(func(key uint32, value *player.ClientData) bool {
value.Player.Kick(true)
return false
})
//fight.Fightpool.ReleaseTimeout(0)
fmt.Println("资源清理完成,程序即将退出")
}
// signalHandlerForMain 主进程信号处理函数
func signalHandlerForMain(sig os.Signal) {
cleanup()
fmt.Println("MainProcess is shutting down due to signal:", sig.String())
}
// main 程序主入口函数
func main() {
// item := model.NeweggConfig()
// item.GeneratedPetIDs = []model.GeneratedPetID{
// {PetID: 1, Prob: 0.01},
// {PetID: 2, Prob: 0.01},
// {PetID: 3, Prob: 0.01},
// {PetID: 4, Prob: 0.01},
// {PetID: 5, Prob: 0.01},
// {PetID: 6, Prob: 0.01},
// }
// item.MalePet = 1
// item.FemalePet = 2
// _, err := g.DB(item.GroupName()).Model(item.TableName()).FieldsEx("id").Data(item).Insert()
// if err != nil {
// panic(err)
// }
//loadAccounts()
// if cool.IsRedisMode {
// go cool.ListenFunc(gctx.New())
// }
// 解析命令行参数
cool.Config.GameOnlineID = gcmd.GetOpt("id", "1").Uint32()
go Start() //注入service
// if cool.Config.GameOnlineID == 2 { //只分析1服务器的
// go PprofWeb()
// }
//go PprofWeb()
go monitorMemAndQuit()
fmt.Println("Process start, pid:", os.Getpid())
gproc.AddSigHandlerShutdown(
signalHandlerForMain,
)
gproc.Listen()
}
const (
memThresholdRatio = 0.9 // 内存占用阈值70%
checkInterval = 10 * time.Second // 内存检测间隔,可按需调整
)
// 监控内存,超阈值则优雅退出程序
func monitorMemAndQuit() {
var memStats runtime.MemStats
for {
// 1. 获取系统总内存和可用内存
sysMem, err := mem.VirtualMemory()
if err != nil {
log.Printf("获取系统内存失败:%v\n", err)
time.Sleep(checkInterval)
continue
}
// 2. 获取Go进程当前堆内存占用进程实际使用的核心内存
runtime.ReadMemStats(&memStats)
procUsedMem := memStats.HeapInuse // 进程堆内存占用(字节)
sysTotalMem := sysMem.Total // 系统总内存(字节)
// 3. 计算进程内存占系统总内存的比例
usedRatio := float64(procUsedMem) / float64(sysTotalMem)
// 格式化输出MB方便查看
procUsedMB := procUsedMem / 1024 / 1024
sysTotalMB := sysTotalMem / 1024 / 1024
log.Printf("当前内存:进程占用%vMB / 系统总%vMB占比%.1f%%",
procUsedMB, sysTotalMB, usedRatio*100)
// 4. 超70%阈值,执行优雅退出
if usedRatio >= memThresholdRatio {
log.Fatalf("内存占比达%.1f%%超过90%%阈值,程序开始退出", usedRatio*100)
// ########## 可选:这里添加你的优雅清理逻辑 ##########
// 如:关闭数据库连接、释放文件句柄、保存业务状态、推送退出告警等
cleanup()
// 退出程序返回非0码方便进程管理工具识别并重启
os.Exit(1)
}
time.Sleep(checkInterval)
}
}
// loadAccounts 从CSV文件加载账号信息
func loadAccounts() {
t1, _ := os.Getwd()
data, err := os.ReadFile(t1 + "/b.csv")
if err != nil {
panic(err)
}
lines := strings.Split(string(data), "\n")
for _, line := range lines {
line = strings.TrimSpace(line)
if line == "" {
continue
}
t := service.NewBaseSysUserService().GetEamil(line)
blservice.NewUserService(uint32(t.ID)).Info.Reg(t.Username, 0)
}
//fmt.Printf("加载 %d 个账号\n", len(accounts))
}