package main import ( "errors" "flag" "fmt" "log" "net" "net/url" "os" "os/signal" "runtime" "speech-nlu-parse/service/speechNlu" "strings" "syscall" "time" "speech-nlu-parse/dao" "speech-nlu-parse/global" "speech-nlu-parse/middleware" "speech-nlu-parse/pkg/consul" "speech-nlu-parse/pkg/logger" "speech-nlu-parse/pkg/proto" "speech-nlu-parse/pkg/setting" "speech-nlu-parse/service" grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware" "google.golang.org/grpc" "google.golang.org/grpc/health/grpc_health_v1" "google.golang.org/grpc/reflection" "gopkg.in/natefinch/lumberjack.v2" ) var ( serverName string serverTag string ip string port int consulAddr string config string runMode string isHelp bool isVersion bool buildTime string buildVersion string author string consulToken string consulUrl string ) func setup() error { // 命令行读取参数 err := setupFlag() if err != nil { log.Fatalf("init.setupFlag err: %v", err) return err } // 判断help if isHelp { fmt.Println("编译后\n" + "Linux可执行: ./tencent-nlu-parse [command=xxx]\n" + "Windows可执行: ./tencent-nlu-parse.exe [command=xxx]\n\n" + "option:") flag.PrintDefaults() return errors.New("missing params.") } if isVersion { fmt.Println("build_time: ", buildTime) fmt.Println("build_version: ", buildVersion) fmt.Println("go_version: ", runtime.Version()) fmt.Println("author: ", author) return errors.New("missing params.") } err = setupSetting() if err != nil { log.Fatalf("init.setupSetting err: %v", err) return err } err = setupLogger() if err != nil { log.Fatalf("init.setupLogger err: %v", err) return err } return nil } func main() { // 初始化配置 if err := setup(); err != nil { log.Fatalf("[FATAL] Setup failed: %v", err) } // 初始化 RabbitMQ 消费者 consumer, err := speechNlu.NewConsumer( global.RabbitMqSetting.Url, global.RabbitMqSetting.ExchangeName, global.RabbitMqSetting.ExchangeType, ) if err != nil { log.Fatalf("[FATAL] Create consumer failed: %v", err) } defer func() { if err := consumer.Shutdown(); err != nil { log.Printf("[WARN] Consumer shutdown error: %v", err) } }() // 初始化 gRPC lis, err := net.Listen("tcp", fmt.Sprintf(":%d", global.ServerSetting.Port)) if err != nil { log.Fatalf("[FATAL] Listen failed: %v", err) } server := grpc.NewServer( grpc.StreamInterceptor(grpc_middleware.ChainStreamServer( middleware.StreamGSError500(), )), grpc.UnaryInterceptor(grpc_middleware.ChainUnaryServer( middleware.UnaryGSError500(), )), ) proto.RegisterTencentNluServer(server, &service.TencentNlu{}) grpc_health_v1.RegisterHealthServer(server, &consul.HealthImpl{}) reflection.Register(server) // 启动 gRPC 服务 go func() { global.Logger.Info("service is running......") if err := server.Serve(lis); err != nil { log.Fatalf("[FATAL] gRPC serve error: %v", err) } }() // 阻塞等待信号 stop := make(chan os.Signal, 1) signal.Notify(stop, os.Interrupt, syscall.SIGTERM) <-stop // 优雅关闭 log.Println("[INFO] Shutting down...") server.GracefulStop() log.Println("[INFO] Server stopped") } func setupFlag() error { flag.BoolVar(&isHelp, "help", false, "帮助") flag.StringVar(&serverName, "name", "", "注册到注册中心的服务名") flag.StringVar(&serverTag, "tag", "", "注册到注册中心的标签") flag.StringVar(&ip, "ip", "", "IP") flag.IntVar(&port, "port", 0, "端口") flag.StringVar(&consulUrl, "consul", "http://172.28.124.106:8500", "consul服务地址") flag.StringVar(&config, "config", "env/v2,speech_nlu_parse/conf", "指定要使用的配置文件路径") flag.BoolVar(&isVersion, "version", false, "编译信息") flag.StringVar(&consulToken, "token", "092288b5-824f-854c-39aa-a958afd9a633", "consul token") flag.StringVar(&runMode, "mode", "", "启动模式(debug|release|test)") flag.Parse() return nil } func setupSetting() error { // 设置 consul 地址 token及路径 s, err := setting.NewSetting(consulUrl, consulToken, strings.Split(config, ",")...) if err != nil { return err } err = s.ReadSection("Server", &global.ServerSetting) if err != nil { return err } err = s.ReadSection("Logger", &global.LoggerSetting) if err != nil { return err } err = s.ReadSection("Device", &global.DeviceSetting) if err != nil { return err } err = s.ReadSection("gree", &global.InternalRemoteSetting) if err != nil { return err } err = s.ReadSection("DB", &global.DBSetting) if err != nil { return err } err = s.ReadSection("MusicDomain", &global.MusicDomainSetting) if err != nil { return err } err = s.ReadSection("Auth", &global.AuthSetting) if err != nil { return err } err = s.ReadSection("DingDang", &global.TencentSetting) if err != nil { return err } err = s.ReadSection("Others", &global.OthersSetting) if err != nil { return err } err = s.ReadSection("Services", &global.ServiceSetting) if err != nil { return err } // 改由配置文件读取 err = s.ReadSection("DevLimited", &global.DevLimitedArr) if err != nil { return err } err = s.ReadSection("tencentV2", &global.TencentGwSetting) if err != nil { return err } err = s.ReadSection("Speech", &global.SpeechSetting) if err != nil { return err } err = s.ReadSection("RabbitMq", &global.RabbitMqSetting) if err != nil { return err } consulUrlParse, err := url.Parse(consulUrl) if err != nil { return err } global.ServerSetting.ConsulAddr = consulUrlParse.Host // 初始化依赖服务的信息 global.InitServiceMap(consulUrl, consulToken) // global.CheckServiceMap() // global.PrintServiceMap() // 初始化设备差异化配置, 需要先加载设置设置 global.InitLimitedSetting() // 初始化数据库连接, 依赖于设置 err = dao.InitDB(global.DBSetting.Dsn) if err != nil { return err } // 从数据库中加载, 依赖于数据库连接 err = global.InitDingDangBot() if err != nil { return err } global.ServerSetting.Interval *= time.Second global.ServerSetting.Deregister *= time.Minute if serverName != "" { global.ServerSetting.Name = serverName } if serverTag != "" { global.ServerSetting.Tag = strings.Split(serverTag, ",") } if ip != "" { global.ServerSetting.IP = ip } if port != 0 { global.ServerSetting.Port = port } if consulToken != "" { global.ServerSetting.ConsulToken = consulToken } if consulToken != "" { global.ServerSetting.ConsulToken = consulToken } if runMode != "" { global.ServerSetting.RunMode = runMode } global.ConsulObj, err = consul.NewConsulObj(consulUrl, consulToken) if err != nil { return err } return nil } func setupLogger() error { fileName := global.LoggerSetting.LogSavePath + "/" + global.LoggerSetting.LogFileName + "_" + time.Now().Format("20060102150405") + global.LoggerSetting.LogFileExt global.Logger = logger.NewLogger(&lumberjack.Logger{ Filename: fileName, MaxSize: global.LoggerSetting.MaxSize, MaxAge: global.LoggerSetting.MaxAge, MaxBackups: global.LoggerSetting.MaxBackups, Compress: global.LoggerSetting.Compress, }, global.ServerSetting.RunMode, global.ServerSetting.Name) return nil }