-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
125 lines (112 loc) · 3.3 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package main
import (
"errors"
"flag"
"net/http"
"os"
"os/signal"
"syscall"
"time"
"connectrpc.com/grpcreflect"
"git.fiblab.net/sim/protos/v2/go/city/routing/v2/routingv2connect"
easy "git.fiblab.net/utils/logrus-easy-formatter"
"github.com/sirupsen/logrus"
"golang.org/x/net/http2"
"golang.org/x/net/http2/h2c"
)
var (
// 配置信息
mongoURI = flag.String("mongo_uri", "", "mongo db uri")
mapPathStr = flag.String("map", "", "map database and collection [format: {fspath} or {db}.{col}]")
roadStatusPathStr = flag.String("road-statuses", "", "roadstatuses database and collection, can be empty [format: {fspath} or {db}.{col}]")
cacheDir = flag.String("cache", "", "input cache dir path (empty means disable cache)")
grpcEndpoint = flag.String("listen", "localhost:52101", "gRPC listening address")
logLevel = flag.String("log-level", "info", "log level [debug, info, warn, error, fatal, panic]")
// 性能测试
benchmark = flag.Bool("benchmark", false, "benchmark mode")
pprofAddr = flag.String("pprof", "localhost:52102", "pprof listening address")
LOG_LEVELS = map[string]logrus.Level{
"debug": logrus.DebugLevel,
"info": logrus.InfoLevel,
"warn": logrus.WarnLevel,
"error": logrus.ErrorLevel,
"fatal": logrus.FatalLevel,
"panic": logrus.PanicLevel,
}
)
func main() {
logrus.SetFormatter(&easy.Formatter{
TimestampFormat: "2006-01-02 15:04:05.0000",
LogFormat: "[%module%] [%time%] [%lvl%] %msg%\n",
})
flag.Parse()
if level, ok := LOG_LEVELS[*logLevel]; ok {
logrus.SetLevel(level)
} else {
logrus.Fatalf("invalid log level: %s", *logLevel)
}
mapPath, err := NewPath(*mapPathStr)
if err != nil {
logrus.Fatalf("invalid map path: %s", err)
}
roadStatusPath, err := NewPath(*roadStatusPathStr)
if err != nil {
logrus.Fatalf("invalid road status path: %s", err)
}
// 启动导航服务
server := NewRoutingServer(
*mongoURI,
mapPath, roadStatusPath,
*cacheDir,
)
if *pprofAddr != "" {
// 启动pprof
startHTTPDebugger(*pprofAddr)
}
if *benchmark {
// 性能测试
runBenchmark(server)
return
}
// 启动tcp监听和初始化connect服务端
mux := http.NewServeMux()
mux.Handle(routingv2connect.NewRoutingServiceHandler(server))
// 接口反射(可选,主要支持Postman调试)
reflector := grpcreflect.NewStaticReflector(
routingv2connect.RoutingServiceName,
)
mux.Handle(grpcreflect.NewHandlerV1(reflector))
mux.Handle(grpcreflect.NewHandlerV1Alpha(reflector))
addr := *grpcEndpoint
// port := addr[strings.LastIndex(addr, ":")+1:]
// 使用HTTP/2 w.o. TLS
s := &http.Server{
Addr: addr,
Handler: h2c.NewHandler(mux, &http2.Server{}),
}
// 优雅退出
// 创建监听退出chan
signalCh := make(chan os.Signal, 1)
//监听指定信号 ctrl+c kill
signal.Notify(signalCh, syscall.SIGINT, syscall.SIGTERM)
go func() {
<-signalCh
log.Info("stopping...")
go func() {
<-signalCh
os.Exit(1) // 强制结束
}()
// 退出connect-go
s.Close()
// 退出导航服务
server.Close()
os.Exit(0)
}()
// 启动gRPC server
log.Infof("server listening at %v", s.Addr)
if err := s.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) {
log.Fatalf("failed to serve: %v", err)
}
time.Sleep(1 * time.Second) // 延迟等待"优雅退出"
log.Info("routing closes")
}