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

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, &registry.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
}
}