package main import ( "encoding/json" "flag" "fmt" "go_dreamfactory/comm" "go_dreamfactory/lego/core" "go_dreamfactory/lego/sys/log" "io/ioutil" "os" "os/exec" "gopkg.in/yaml.v3" ) /* 服务类型:区服启动程序 服务描述:通过读取游戏json配置,启动服务程序 */ var ( gmpath = flag.String("p", "./gm.json", "区服配置json") //启动服务的Id ) func main() { flag.Parse() if err := log.OnInit(nil, log.SetFileName("./log/cmd.log"), log.SetLoglevel(log.DebugLevel), log.SetIsDebug(true)); err != nil { panic(fmt.Sprintf("Sys log Init err:%v", err)) } else { log.Infof("Sys log Init success !") } if config, err := readergmconf(*gmpath); err != nil { log.Error("读取区服配置失败!", log.Field{Key: "err", Value: err}) } else { var ( maintes []*core.ServiceSttings = make([]*core.ServiceSttings, 0) workers []*core.ServiceSttings = make([]*core.ServiceSttings, 0) gateways []*core.ServiceSttings = make([]*core.ServiceSttings, 0) ) for i, v := range config.Services { if sseting, err := convertServiceSttings(config, i, v); err != nil { log.Error("转换服务配置异常!", log.Field{Key: "v", Value: v}, log.Field{Key: "err", Value: err}) return } else { if err = writeServiceConfig(fmt.Sprintf("./conf/%s.yaml", sseting.Id), sseting); err != nil { log.Error("写入服务配置失败!", log.Field{Key: "sseting", Value: sseting}, log.Field{Key: "err", Value: err}) return } switch sseting.Type { case comm.Service_Gateway: //网关服务 gateways = append(gateways, sseting) break case comm.Service_Worker: //业务服务 workers = append(workers, sseting) break case comm.Service_Mainte: //维护服务 maintes = append(maintes, sseting) break default: err = fmt.Errorf("服务类型异常 stype:%s", sseting.Type) return } } } //优先启动 维护服 for _, v := range maintes { startService(v) } // 业务服 for _, v := range workers { startService(v) } // 网关服 for _, v := range gateways { startService(v) } } } //读取游戏配置文件 func readergmconf(path string) (config *comm.GameConfig, err error) { config = &comm.GameConfig{} var ( jsonFile *os.File byteValue []byte ) if jsonFile, err = os.Open(path); err != nil { return } else { defer jsonFile.Close() if byteValue, err = ioutil.ReadAll(jsonFile); err != nil { return } err = json.Unmarshal(byteValue, config) } return } //转换游戏服务配置 func convertServiceSttings(config *comm.GameConfig, id int, sconfig *comm.ServiceConfig) (sseting *core.ServiceSttings, err error) { sseting = &core.ServiceSttings{} sseting.Modules = make(map[string]map[string]interface{}) sseting.Sys = make(map[string]map[string]interface{}) sseting.Sys["rpcx"] = map[string]interface{}{ "ConsulServers": config.ConsulAddr, } switch sconfig.ServiceType { case comm.Service_Gateway: //网关服务 sseting.Type = comm.Service_Gateway sseting.Sys["rpcx"]["RpcxStartType"] = 1 sseting.Modules["gateway"] = map[string]interface{}{ "ListenPort": sconfig.ListenPort, "SpanServiceTag": config.BelongCrossServerId, } break case comm.Service_Worker: //业务服务 sseting.Type = comm.Service_Worker sseting.Sys["rpcx"]["RpcxStartType"] = 0 break case comm.Service_Mainte: //维护服务 sseting.Type = comm.Service_Mainte sseting.Sys["rpcx"]["RpcxStartType"] = 0 sseting.Modules["web"] = map[string]interface{}{ "WebDir": "./dist", "Port": sconfig.ListenPort, "Key": "@234%67g12q4*67m12#4l67!", } break default: err = fmt.Errorf("服务类型异常 stype:%s", sseting.Type) return } sseting.Id = fmt.Sprintf("%s_s%d", config.AreaId, id) sseting.Tag = config.AreaId sseting.Ip = sconfig.Host sseting.Port = int(sconfig.Port) sseting.Sys["log"] = map[string]interface{}{ "FileName": fmt.Sprintf("./log/%s.log", sseting.Id), "Loglevel": sconfig.Loglevel, "MaxAgeTime": sconfig.MaxAgeTime, } sseting.Sys["configure"] = map[string]interface{}{ "ConfigurePath": "./json", } sseting.Sys["db"] = map[string]interface{}{} sseting.Sys["db"]["Loacl"] = map[string]interface{}{ "Enabled": true, "RedisIsCluster": config.LoaclDB.RedisIsCluster, "RedisAddr": config.LoaclDB.RedisAddr, "RedisPassword": config.LoaclDB.RedisPassword, "RedisDB": config.LoaclDB.RedisDB, "MongodbUrl": config.LoaclDB.MongodbUrl, "MongodbDatabase": config.LoaclDB.MongodbDatabase, } if !config.IsCross { //不是跨服区服务 需要配置所属跨服db sseting.Sys["db"]["Cross"] = map[string]interface{}{ "Enabled": true, "RedisIsCluster": config.CrossDB.RedisIsCluster, "RedisAddr": config.CrossDB.RedisAddr, "RedisPassword": config.CrossDB.RedisPassword, "RedisDB": config.CrossDB.RedisDB, "MongodbUrl": config.CrossDB.MongodbUrl, "MongodbDatabase": config.CrossDB.MongodbDatabase, } } return } //启动服务程序 func startService(sseting *core.ServiceSttings) (err error) { var ( cmd *exec.Cmd ) switch sseting.Type { case comm.Service_Gateway: //网关服务 cmd = exec.Command("./stup.sh", "start", sseting.Id, "gateway", fmt.Sprintf("./conf/%s.yaml", sseting.Id)) break case comm.Service_Worker: //业务服务 cmd = exec.Command("./stup.sh", "start", sseting.Id, "worker", fmt.Sprintf("./conf/%s.yaml", sseting.Id)) break case comm.Service_Mainte: //维护服务 cmd = exec.Command("./stup.sh", "start", sseting.Id, "mainte", fmt.Sprintf("./conf/%s.yaml", sseting.Id)) break default: err = fmt.Errorf("服务类型异常 stype:%s", sseting.Type) return } err = cmd.Start() return } //写入服务配置文件 func writeServiceConfig(filename string, sseting *core.ServiceSttings) (err error) { var data []byte if data, err = yaml.Marshal(sseting); err != nil { return } else { err = ioutil.WriteFile(filename, data, 0777) } return }