250 lines
6.2 KiB
Go
250 lines
6.2 KiB
Go
package main
|
||
|
||
import (
|
||
"context"
|
||
"fmt"
|
||
"net"
|
||
"net/http"
|
||
"os"
|
||
"os/exec"
|
||
"os/signal"
|
||
"runtime"
|
||
"service/api/consts"
|
||
"service/app/mix/conf"
|
||
"service/app/mix/controller"
|
||
"service/app/mix/mediafiller"
|
||
"service/app/mix/service"
|
||
"service/library/apollo"
|
||
"service/library/configcenter"
|
||
"service/library/contentaudit/imageaudit"
|
||
"service/library/contentaudit/textaudit"
|
||
videomoderation "service/library/contentaudit/video_moderation"
|
||
"service/library/dingtalk"
|
||
"service/library/httpengine"
|
||
"service/library/logger"
|
||
"service/library/middleware"
|
||
"service/library/redis"
|
||
"service/library/servicediscovery"
|
||
"service/library/sms"
|
||
"service/library/validator"
|
||
"strings"
|
||
"syscall"
|
||
"time"
|
||
)
|
||
|
||
func main() {
|
||
defer func() {
|
||
logger.Recover()
|
||
}()
|
||
|
||
// 加载配置
|
||
// 1.默认配置
|
||
configPath := consts.ProductionConfigPath
|
||
|
||
//if os.Getenv("PROJECT_ENV") == "production" {
|
||
// configPath = consts.ProductionConfigPath
|
||
//}
|
||
cfg := new(conf.ConfigSt)
|
||
err := configcenter.LoadConfig(configPath, cfg)
|
||
if err != nil {
|
||
msg := fmt.Sprintf("LoadConfig fail, path: %v, err: %v", configPath, err)
|
||
PrintAndExit(msg)
|
||
}
|
||
|
||
// 初始化日志
|
||
logger.InitLogger(cfg.Log)
|
||
|
||
//初始化apollo
|
||
err = apollo.Init(cfg.Apollo)
|
||
if err != nil {
|
||
msg := fmt.Sprintf("Apollo init fail, path: %v, err: %v", configPath, err)
|
||
PrintAndExit(msg)
|
||
}
|
||
|
||
//初始化redis
|
||
err = redis.Init(cfg.RedisConfig)
|
||
if err != nil {
|
||
msg := fmt.Sprintf("Redis init fail, path: %v, err: %v", configPath, err)
|
||
PrintAndExit(msg)
|
||
}
|
||
|
||
// 初始化服务发现
|
||
err = servicediscovery.Init(cfg.SD)
|
||
if err != nil {
|
||
msg := fmt.Sprintf("Init servicediscovery fail, path: %v, err: %v", configPath, err)
|
||
PrintAndExit(msg)
|
||
}
|
||
|
||
// 初始化短信服务
|
||
err = sms.Init(cfg.Dysmsapi)
|
||
if err != nil {
|
||
msg := fmt.Sprintf("Sms init fail, path: %v, err: %v", configPath, err)
|
||
PrintAndExit(msg)
|
||
}
|
||
|
||
// 初始化钉钉机器人
|
||
dingtalk.InitDefaultDingTalkClient(cfg.DingTalkRobot)
|
||
|
||
// 初始化服务
|
||
service.DefaultService = service.NewService()
|
||
service.DefaultConfigService = service.NewConfigService()
|
||
service.DefaultCronService = service.NewCronService()
|
||
service.DefaultScriptsService = service.NewScriptsService()
|
||
service.DefaultImageAuditTaskResultHandler = service.NewImageAuditTaskResultHandler()
|
||
service.DefaultTextAuditTaskResultHandler = service.NewTextAuditTaskResultHandler()
|
||
service.DefaultVideoModerationTaskResultHandler = service.NewVideoModerationTaskResultHandler()
|
||
err = service.DefaultService.Init(cfg)
|
||
if err != nil {
|
||
msg := fmt.Sprintf("Service init fail, err: %v", err)
|
||
PrintAndExit(msg)
|
||
}
|
||
err = service.DefaultCronService.Init(cfg)
|
||
if err != nil {
|
||
msg := fmt.Sprintf("CronService init fail, err: %v", err)
|
||
PrintAndExit(msg)
|
||
}
|
||
|
||
// 连接到审核任务数据库接口
|
||
service.DefaultService.ConnectToImageAudit()
|
||
service.DefaultService.ConnectToTextAudit()
|
||
service.DefaultService.ConnectToVideoModeration()
|
||
//service.DefaultService.Run()
|
||
|
||
// 启动图像审核服务
|
||
imageaudit.Init(cfg.ImageAudit)
|
||
|
||
// 启动文字审核服务
|
||
textaudit.Init(cfg.TextAudit)
|
||
|
||
// 启动视频审核服务
|
||
videomoderation.Init(cfg.VideoModeration)
|
||
|
||
// 初始化媒体填充服务
|
||
mediafiller.Init(cfg.ServerInfo)
|
||
|
||
// 初始化http server
|
||
ip := GetIp()
|
||
port := cfg.App.Port
|
||
router := httpengine.NewRouter()
|
||
middleware.InitJwtAuthenticator(service.DefaultService.OpVerifyToken)
|
||
validator.InitDefaultNotNullValidator()
|
||
controller.Init(router)
|
||
srv := &http.Server{
|
||
Addr: fmt.Sprintf("%s:%d", ip, port),
|
||
Handler: router,
|
||
}
|
||
|
||
go func() {
|
||
if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||
logger.Fatal("listen: %v", err)
|
||
return
|
||
}
|
||
}()
|
||
|
||
// 注册服务
|
||
go func() {
|
||
err := registerSD(ip, port)
|
||
if err != nil {
|
||
logger.Fatal("registerSD: %v", err)
|
||
return
|
||
}
|
||
setServerStatusFD(ServerStatusFDRun)
|
||
}()
|
||
|
||
quit := make(chan os.Signal, 1)
|
||
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
|
||
<-quit
|
||
|
||
if err := servicediscovery.DeRegister(ip, port); err != nil {
|
||
logger.Fatal("DeRegister fail: %v", err)
|
||
}
|
||
|
||
ctx, cancel := context.WithTimeout(context.Background(), 1*time.Second)
|
||
if err := srv.Shutdown(ctx); err != nil {
|
||
logger.Fatal("Server Shutdown:", err)
|
||
}
|
||
defer cancel()
|
||
select {
|
||
case <-ctx.Done():
|
||
logger.Info("timeout of 1 seconds.")
|
||
}
|
||
|
||
logger.Info("Server exited")
|
||
setServerStatusFD(ServerStatusFDStop)
|
||
}
|
||
|
||
func PrintAndExit(msg string) {
|
||
_, file, line, _ := runtime.Caller(1)
|
||
errorMsg := fmt.Sprintf("file %s, line %d, %s\n", file, line, msg)
|
||
_, _ = fmt.Fprintf(os.Stderr, errorMsg)
|
||
logger.Fatal(errorMsg)
|
||
time.Sleep(1) //wait logger flush
|
||
//os.Exit(1)
|
||
}
|
||
|
||
func GetIp() string {
|
||
addrs, err := net.InterfaceAddrs()
|
||
if err != nil {
|
||
PrintAndExit("get ip fail")
|
||
return "127.0.0.1"
|
||
}
|
||
retIp := ""
|
||
for _, address := range addrs {
|
||
// 检查ip地址判断是否回环地址
|
||
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
|
||
if ipnet.IP.To4() != nil {
|
||
ip := ipnet.IP.String()
|
||
if strings.HasPrefix(ip, "172.") {
|
||
retIp = ip
|
||
break
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return retIp
|
||
}
|
||
|
||
func registerSD(ip string, port int) error {
|
||
// 要等服务起来后再注册到consul,否则会有问题
|
||
// 方法:调用 healthcheck
|
||
idx := 0
|
||
timer := time.NewTimer(time.Second * 5)
|
||
timerRetry := time.NewTicker(time.Second * 1)
|
||
for {
|
||
select {
|
||
case <-timer.C:
|
||
return fmt.Errorf("registerSD fail, ip: %v, port: %v", ip, port)
|
||
case <-timerRetry.C:
|
||
idx += 1
|
||
resp, err := http.Get(fmt.Sprintf("http://%s:%v/healthcheck", ip, port))
|
||
if err != nil {
|
||
logger.Error("healthcheck fail, err: %v", err)
|
||
continue
|
||
}
|
||
if resp.StatusCode == http.StatusOK {
|
||
if err := servicediscovery.Register(ip, port); err != nil {
|
||
logger.Error("registerSD fail, ip: %v, port: %v, err: %v", ip, port, err)
|
||
continue
|
||
}
|
||
return nil
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
func setServerStatusFD(status string) {
|
||
serverStatusFdPath := "/app/SERVER_STATUS_FD"
|
||
cmd := exec.Command("sh", "-c", fmt.Sprintf("echo %s > %s", status, serverStatusFdPath))
|
||
err := cmd.Run()
|
||
if err != nil {
|
||
logger.Info("run cmd fail, p: %v, err: %v", serverStatusFdPath, err)
|
||
return
|
||
}
|
||
logger.Info("SetServerStatusFD success: %v", status)
|
||
}
|
||
|
||
const (
|
||
ServerStatusFDRun = "RUN" // 服务运行中
|
||
ServerStatusFDStop = "STOP" // 服务停止
|
||
)
|