mirror of
https://github.com/singchia/frontier.git
synced 2026-04-22 16:07:04 +08:00
238 lines
7.3 KiB
Go
238 lines
7.3 KiB
Go
package config
|
|
|
|
import (
|
|
"flag"
|
|
"io"
|
|
"os"
|
|
|
|
armio "github.com/jumboframes/armorigo/io"
|
|
"github.com/singchia/frontier/pkg/config"
|
|
"github.com/spf13/pflag"
|
|
"gopkg.in/yaml.v2"
|
|
"k8s.io/klog/v2"
|
|
)
|
|
|
|
// daemon related
|
|
type RLimit struct {
|
|
Enable bool `yaml:"enable"`
|
|
NumFile int `yaml:"nofile"`
|
|
}
|
|
|
|
type PProf struct {
|
|
Enable bool `yaml:"enable"`
|
|
Addr string `yaml:"addr"`
|
|
CPUProfileRate int `yaml:"cpu_profile_rate"`
|
|
}
|
|
|
|
type Daemon struct {
|
|
RLimit RLimit `yaml:"rlimit"`
|
|
PProf PProf `yaml:"pprof"`
|
|
}
|
|
|
|
// for rest and grpc
|
|
type ControlPlane struct {
|
|
Listen config.Listen `yaml:"listen"`
|
|
}
|
|
|
|
// TODO tls support
|
|
type Redis struct {
|
|
Mode string `yaml:"mode"` // standalone, sentinel or cluster
|
|
|
|
// Use the specified Username to authenticate the current connection
|
|
// with one of the connections defined in the ACL list when connecting
|
|
// to a Redis 6.0 instance, or greater, that is using the Redis ACL system.
|
|
Username string `yaml:"username,omitempty"`
|
|
|
|
// Optional password. Must match the password specified in the
|
|
// requirepass server configuration option (if connecting to a Redis 5.0 instance, or lower),
|
|
// or the User Password when connecting to a Redis 6.0 instance, or greater,
|
|
// that is using the Redis ACL system.
|
|
Password string `yaml:"password,omitempty"`
|
|
|
|
// Protocol 2 or 3. Use the version to negotiate RESP version with redis-server.
|
|
// Default is 3.
|
|
Protocol int `yaml:"protocol,omitempty"`
|
|
|
|
// ClientName will execute the `CLIENT SETNAME ClientName` command for each conn.
|
|
ClientName string `yaml:"clientname,omitempty"`
|
|
|
|
// connection retry settings
|
|
MaxRetries int `yaml:"max_retries,omitempty"`
|
|
MinRetryBackoff int `yaml:"min_retry_backoff,omitempty"`
|
|
MaxRetryBackoff int `yaml:"max_retry_backoff,omitempty"`
|
|
// connection r/w settings
|
|
DialTimeout int `yaml:"dial_timeout,omitempty"`
|
|
ReadTimeout int `yaml:"read_timeout,omitempty"`
|
|
WriteTimeout int `yaml:"write_timeout,omitempty"`
|
|
// connection pool settings
|
|
PoolFIFO bool `yaml:"pool_fifo,omitempty"`
|
|
PoolSize int `yaml:"pool_size,omitempty"` // applies per cluster node and not for the whole cluster
|
|
PoolTimeout int `yaml:"pool_timeout,omitempty"`
|
|
MinIdleConns int `yaml:"min_idle_conns,omitempty"`
|
|
MaxIdleConns int `yaml:"max_idle,omitempty"`
|
|
MaxActiveConns int `yaml:"max_active_conns,omitempty"` // applies per cluster node and not for the whole cluster
|
|
ConnMaxIdleTime int `yaml:"conn_max_idle_time,omitempty"`
|
|
ConnMaxLifetime int `yaml:"conn_max_life_time,omitempty"`
|
|
DisableIndentity bool `yaml:"disable_identity,omitempty"` // Disable set-lib on connect. Default is false.
|
|
IdentitySuffix string `yaml:"identity_suffix,omitempty"` // Add suffix to client name. Default is empty.
|
|
|
|
Standalone struct {
|
|
// The network type, either tcp or unix.
|
|
// Default is tcp.
|
|
Network string `yaml:"network"`
|
|
// host:port address.
|
|
Addr string `yaml:"addr"`
|
|
// CredentialsProvider allows the username and password to be updated
|
|
// before reconnecting. It should return the current username and password.
|
|
DB int `yaml:"db"`
|
|
} `yaml:"standalone,omitempty"`
|
|
Sentinel struct {
|
|
Addrs []string `yaml:"addrs"`
|
|
MasterName string `yaml:"master_name"`
|
|
DB int `yaml:"db"`
|
|
|
|
// route settings
|
|
// Allows routing read-only commands to the closest master or replica node.
|
|
// This option only works with NewFailoverClusterClient.
|
|
RouteByLatency bool `yaml:"route_by_latency,omitempty"`
|
|
// Allows routing read-only commands to the random master or replica node.
|
|
// This option only works with NewFailoverClusterClient.
|
|
RouteRandomly bool `yaml:"route_randomly,omitempty"`
|
|
// Route all commands to replica read-only nodes.
|
|
ReplicaOnly bool `yaml:"replica_only,omitempty"`
|
|
|
|
// Use replicas disconnected with master when cannot get connected replicas
|
|
// Now, this option only works in RandomReplicaAddr function.
|
|
UseDisconnectedReplicas bool `yaml:"use_disconnected_replicas,omitempty"`
|
|
} `yaml:"sentinel,omitempty"`
|
|
Cluster struct {
|
|
Addrs []string `yaml:"addrs"`
|
|
// The maximum number of retries before giving up. Command is retried
|
|
// on network errors and MOVED/ASK redirects.
|
|
// Default is 3 retries.
|
|
MaxRedirects int `yaml:"max_redirects,omitempty"`
|
|
// Allows routing read-only commands to the closest master or slave node.
|
|
// It automatically enables ReadOnly.
|
|
RouteByLatency bool `yaml:"route_by_latency,omitempty"`
|
|
// Allows routing read-only commands to the random master or slave node.
|
|
// It automatically enables ReadOnly.
|
|
RouteRandomly bool `yaml:"route_randomly,omitempty"`
|
|
} `yaml:"cluster,omitempty"`
|
|
}
|
|
|
|
type FrontierManager struct {
|
|
Listen config.Listen `yaml:"listen"`
|
|
Expiration struct {
|
|
ServiceMeta int `yaml:"service_meta"` // service meta expiration in redis, in seconds, default 86400s
|
|
EdgeMeta int `yaml:"edge_meta"` // edge meta expiration in redis, in seconds, default 86400s
|
|
} `yaml:"expiration,omitempty"`
|
|
}
|
|
|
|
type Configuration struct {
|
|
Daemon Daemon `yaml:"daemon"`
|
|
|
|
ControlPlane ControlPlane `yaml:"control_plane"`
|
|
|
|
FrontierManager FrontierManager `yaml:"frontier_plane"`
|
|
|
|
Redis Redis `yaml:"redis"`
|
|
}
|
|
|
|
func Parse() (*Configuration, error) {
|
|
var (
|
|
argConfigFile = pflag.String("config", "", "config file, default not configured")
|
|
argDaemonRLimitNofile = pflag.Int("daemon-rlimit-nofile", -1, "SetRLimit for number of file of this daemon, default: -1 means ignore")
|
|
// TODO more command-line args
|
|
|
|
config *Configuration
|
|
)
|
|
pflag.Lookup("daemon-rlimit-nofile").NoOptDefVal = "1048576"
|
|
|
|
// set klog
|
|
klogFlags := flag.NewFlagSet("klog", flag.ExitOnError)
|
|
klog.InitFlags(klogFlags)
|
|
|
|
// sync the glog and klog flags.
|
|
pflag.CommandLine.VisitAll(func(f1 *pflag.Flag) {
|
|
f2 := klogFlags.Lookup(f1.Name)
|
|
if f2 != nil {
|
|
value := f1.Value.String()
|
|
if err := f2.Value.Set(value); err != nil {
|
|
klog.Fatal(err, "failed to set flag")
|
|
return
|
|
}
|
|
}
|
|
})
|
|
|
|
pflag.CommandLine.AddGoFlagSet(klogFlags)
|
|
pflag.CommandLine.AddGoFlagSet(flag.CommandLine)
|
|
pflag.Parse()
|
|
|
|
// config file
|
|
if *argConfigFile != "" {
|
|
// TODO the command-line is prior to config file
|
|
data, err := os.ReadFile(*argConfigFile)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
config = &Configuration{}
|
|
if err = yaml.Unmarshal(data, config); err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if config == nil {
|
|
config = &Configuration{}
|
|
}
|
|
// daemon
|
|
config.Daemon.RLimit.NumFile = *argDaemonRLimitNofile
|
|
if config.Daemon.PProf.CPUProfileRate == 0 {
|
|
config.Daemon.PProf.CPUProfileRate = 10000
|
|
}
|
|
return config, nil
|
|
}
|
|
|
|
func genDefaultConfig(writer io.Writer) error {
|
|
conf := &Configuration{
|
|
Daemon: Daemon{
|
|
RLimit: RLimit{
|
|
NumFile: 1024,
|
|
},
|
|
PProf: PProf{
|
|
Enable: true,
|
|
Addr: "0.0.0.0:6061",
|
|
},
|
|
},
|
|
ControlPlane: ControlPlane{
|
|
Listen: config.Listen{
|
|
Network: "tcp",
|
|
Addr: "0.0.0.0:30020",
|
|
},
|
|
},
|
|
FrontierManager: FrontierManager{
|
|
Listen: config.Listen{
|
|
Network: "tcp",
|
|
Addr: "0.0.0.0:30021",
|
|
},
|
|
},
|
|
Redis: Redis{
|
|
Mode: "standalone",
|
|
},
|
|
}
|
|
conf.Redis.Standalone.Network = "tcp"
|
|
conf.Redis.Standalone.Addr = "127.0.0.1:6379"
|
|
conf.Redis.Standalone.DB = 0
|
|
conf.FrontierManager.Expiration.EdgeMeta = 30
|
|
conf.FrontierManager.Expiration.ServiceMeta = 30
|
|
|
|
data, err := yaml.Marshal(conf)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
_, err = armio.WriteAll(data, writer)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|