You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
192 lines
5.1 KiB
192 lines
5.1 KiB
package initialize
|
|
|
|
import (
|
|
"context"
|
|
"crypto/tls"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"github.com/TremblingV5/DouTok/pkg/constants"
|
|
"github.com/TremblingV5/DouTok/pkg/dtnetwork"
|
|
"time"
|
|
|
|
"github.com/TremblingV5/DouTok/applications/api/initialize/rpc"
|
|
"github.com/cloudwego/hertz/pkg/app/server"
|
|
"github.com/cloudwego/hertz/pkg/app/server/registry"
|
|
"github.com/cloudwego/hertz/pkg/common/config"
|
|
"github.com/cloudwego/hertz/pkg/common/hlog"
|
|
"github.com/cloudwego/hertz/pkg/common/utils"
|
|
"github.com/hertz-contrib/gzip"
|
|
h2config "github.com/hertz-contrib/http2/config"
|
|
"github.com/hertz-contrib/http2/factory"
|
|
"github.com/hertz-contrib/obs-opentelemetry/provider"
|
|
hertztracing "github.com/hertz-contrib/obs-opentelemetry/tracing"
|
|
"github.com/hertz-contrib/registry/etcd"
|
|
)
|
|
|
|
var (
|
|
ServiceAddr string
|
|
EtcdAddress string
|
|
hertzCfg HertzCfg
|
|
)
|
|
|
|
type HertzCfg struct {
|
|
UseNetpoll bool `json:"UseNetpoll" yaml:"UseNetpoll"`
|
|
Http2 Http2 `json:"Http2" yaml:"Http2"`
|
|
Tls Tls `json:"Tls" yaml:"Tls"`
|
|
}
|
|
|
|
type Tls struct {
|
|
Enable bool `json:"Enable" yaml:"Enable"`
|
|
Cfg tls.Config
|
|
Cert string `json:"CertFile" yaml:"CertFile"`
|
|
Key string `json:"KeyFile" yaml:"KeyFile"`
|
|
ALPN bool `json:"ALPN" yaml:"ALPN"`
|
|
}
|
|
|
|
type Http2 struct {
|
|
Enable bool `json:"Enable" yaml:"Enable"`
|
|
DisableKeepalive bool `json:"DisableKeepalive" yaml:"DisableKeepalive"`
|
|
ReadTimeout Duration `json:"ReadTimeout" yaml:"ReadTimeout"`
|
|
}
|
|
|
|
type Duration struct {
|
|
time.Duration
|
|
}
|
|
|
|
func (d Duration) MarshalJSON() ([]byte, error) {
|
|
return json.Marshal(d.String())
|
|
}
|
|
|
|
func (d *Duration) UnmarshalJSON(b []byte) error {
|
|
var v interface{}
|
|
if err := json.Unmarshal(b, &v); err != nil {
|
|
return err
|
|
}
|
|
switch value := v.(type) {
|
|
case float64:
|
|
d.Duration = time.Duration(value)
|
|
return nil
|
|
case string:
|
|
var err error
|
|
d.Duration, err = time.ParseDuration(value)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
default:
|
|
return errors.New("invalid duration")
|
|
}
|
|
}
|
|
|
|
// 初始化 API 配置
|
|
func Init() {
|
|
InitViper()
|
|
rpc.InitRPC()
|
|
InitJwt()
|
|
InitRedisClient()
|
|
}
|
|
|
|
func InitHertzCfg() {
|
|
ServiceAddr = fmt.Sprintf("%s:%d", ViperConfig.Viper.GetString("Server.Address"), ViperConfig.Viper.GetInt("Server.Port"))
|
|
EtcdAddress = fmt.Sprintf("%s:%d", ViperConfig.Viper.GetString("Etcd.Address"), ViperConfig.Viper.GetInt("Etcd.Port"))
|
|
|
|
hertzV, err := json.Marshal(ViperConfig.Viper.Sub("Hertz").AllSettings())
|
|
if err != nil {
|
|
hlog.Fatalf("Error marshalling Hertz config %s", err)
|
|
}
|
|
if err := json.Unmarshal(hertzV, &hertzCfg); err != nil {
|
|
hlog.Fatalf("Error unmarshalling Hertz config %s", err)
|
|
}
|
|
}
|
|
|
|
// 初始化 Hertz
|
|
func InitHertz() (*server.Hertz, func()) {
|
|
InitHertzCfg()
|
|
|
|
opts := []config.Option{server.WithHostPorts(ServiceAddr)}
|
|
|
|
opts = append(opts, server.WithMaxRequestBodySize(1024*1024*1024))
|
|
|
|
// 服务注册
|
|
if ViperConfig.Viper.GetBool("Etcd.Enable") {
|
|
r, err := etcd.NewEtcdRegistry([]string{EtcdAddress})
|
|
if err != nil {
|
|
hlog.Fatal(err)
|
|
}
|
|
opts = append(opts, server.WithRegistry(r, ®istry.Info{
|
|
ServiceName: constants.ApiServerName,
|
|
Addr: utils.NewNetAddr("tcp", ServiceAddr),
|
|
Weight: 10,
|
|
Tags: nil,
|
|
}))
|
|
}
|
|
|
|
var p provider.OtelProvider
|
|
if ViperConfig.Viper.GetBool("Otel.Enable") {
|
|
//链路追踪
|
|
p = provider.NewOpenTelemetryProvider(
|
|
provider.WithServiceName(constants.ApiServerName),
|
|
provider.WithExportEndpoint(fmt.Sprintf("%s:%s", ViperConfig.Viper.GetString("Otel.Host"), ViperConfig.Viper.GetString("Otel.Port"))),
|
|
provider.WithInsecure(),
|
|
)
|
|
}
|
|
|
|
tracer, tracerCfg := hertztracing.NewServerTracer()
|
|
opts = append(opts, tracer)
|
|
|
|
// 网络库
|
|
hertzNet := dtnetwork.GetTransporter(hertzCfg.UseNetpoll)
|
|
|
|
opts = append(opts, server.WithTransport(hertzNet))
|
|
|
|
// TLS & Http2
|
|
tlsEnable := hertzCfg.Tls.Enable
|
|
h2Enable := hertzCfg.Http2.Enable
|
|
hertzCfg.Tls.Cfg = tls.Config{
|
|
MinVersion: tls.VersionTLS12,
|
|
CurvePreferences: []tls.CurveID{tls.X25519, tls.CurveP256},
|
|
CipherSuites: []uint16{
|
|
tls.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305,
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384,
|
|
tls.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256,
|
|
},
|
|
}
|
|
if tlsEnable {
|
|
cert, err := tls.LoadX509KeyPair(hertzCfg.Tls.Cert, hertzCfg.Tls.Key)
|
|
if err != nil {
|
|
hlog.Error(err)
|
|
}
|
|
hertzCfg.Tls.Cfg.Certificates = append(hertzCfg.Tls.Cfg.Certificates, cert)
|
|
opts = append(opts, server.WithTLS(&hertzCfg.Tls.Cfg))
|
|
|
|
if alpn := hertzCfg.Tls.ALPN; alpn {
|
|
opts = append(opts, server.WithALPN(alpn))
|
|
}
|
|
} else if h2Enable {
|
|
opts = append(opts, server.WithH2C(h2Enable))
|
|
}
|
|
|
|
// Hertz
|
|
h := server.Default(opts...)
|
|
h.Use(gzip.Gzip(gzip.DefaultCompression),
|
|
hertztracing.ServerMiddleware(tracerCfg))
|
|
|
|
// Protocol
|
|
if h2Enable {
|
|
h.AddProtocol("h2", factory.NewServerFactory(
|
|
h2config.WithReadTimeout(hertzCfg.Http2.ReadTimeout.Duration),
|
|
h2config.WithDisableKeepAlive(hertzCfg.Http2.DisableKeepalive)))
|
|
if tlsEnable {
|
|
hertzCfg.Tls.Cfg.NextProtos = append(hertzCfg.Tls.Cfg.NextProtos, "h2")
|
|
}
|
|
}
|
|
|
|
if ViperConfig.Viper.GetBool("Otel.Enable") {
|
|
return h, func() {
|
|
}
|
|
}
|
|
return h, func() {
|
|
_ = p.Shutdown(context.Background()) //nolint
|
|
}
|
|
}
|
|
|