func (pc *ProxyConfig) apply() { log.SetLevelByString(pc.logLevel) if pc.logFile != "" { err := log.SetOutputByName(pc.logFile) if err != nil { log.Fatalf("ProxyConfig SetOutputByName %s failed %s ", pc.logFile, err.Error()) } log.SetRotateByDay() } if pc.name == "" { log.Fatal("ProxyConfig name must not empty") } if pc.port == 0 { log.Fatal("ProxyConfig port must not 0") } if pc.cpu > runtime.NumCPU() { log.Warningf("ProxyConfig cpu %d exceed %d, adjust to %d ", pc.cpu, runtime.NumCPU(), runtime.NumCPU()) pc.cpu = runtime.NumCPU() } if pc.maxConn > 10000 { log.Warningf("ProxyConfig maxconn %d exceed 10000, adjust to 10000", pc.maxConn) pc.maxConn = 10000 } runtime.GOMAXPROCS(pc.cpu) if pc.poolSize <= 0 || pc.poolSize > 30 { log.Warning("ProxyConfig poolSize %d , adjust to 10 ", pc.poolSize) pc.poolSize = 10 } if pc.cpuFile != "" { f, err := os.Create(pc.cpuFile) if err != nil { log.Fatal(err) } log.Warning("Archer start CPUProfile ", pc.cpuFile) pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } if pc.memFile != "" { f, err := os.Create(pc.memFile) if err == nil { log.Warning("Archer start HeapProfile ", pc.memFile) pprof.WriteHeapProfile(f) } } go func() { log.Warning(http.ListenAndServe(":6061", nil)) }() }
func main() { autoflags.Define(&config) flag.Parse() log.SetLevelByString(config.LogLevel) // to avoid pprof being optimized by gofmt log.Debug(pprof.Handler("profile")) if len(config.LogFile) != 0 { log.SetOutputByName(config.LogFile) log.SetRotateByDay() } if config.LogEveryN <= 0 { proxy.LogEveryN = 1 } else { proxy.LogEveryN = config.LogEveryN } log.Infof("%#v", config) sigChan := make(chan os.Signal) signal.Notify(sigChan, os.Interrupt, os.Kill) log.Infof("pid %d", os.Getpid()) if len(config.DebugAddr) != 0 { http.HandleFunc("/setloglevel", handleSetLogLevel) go func() { log.Fatal(http.ListenAndServe(config.DebugAddr, nil)) }() log.Infof("debug service listens on %s", config.DebugAddr) } // shuffle startup nodes startupNodes := strings.Split(config.StartupNodes, ",") indexes := rand.Perm(len(startupNodes)) for i, startupNode := range startupNodes { startupNodes[i] = startupNodes[indexes[i]] startupNodes[indexes[i]] = startupNode } connPool := proxy.NewConnPool(config.BackendIdleConnections, config.ConnectTimeout, config.ReadPrefer != proxy.READ_PREFER_MASTER) dispatcher := proxy.NewDispatcher(startupNodes, config.SlotsReloadInterval, connPool, config.ReadPrefer) if err := dispatcher.InitSlotTable(); err != nil { log.Fatal(err) } proxy := proxy.NewProxy(config.Addr, dispatcher, connPool) go proxy.Run() sig := <-sigChan log.Infof("terminated by %#v", sig) proxy.Exit() }
func NewProxyConfig(filename string) *ProxyConfig { c, err := config.NewConfig("ini", filename) if err != nil { log.Fatal("read config file failed ", err) } loglevel := c.DefaultString("log::loglevel", "info") log.SetLevelByString(loglevel) logfile := c.DefaultString("log::logfile", "") if logfile != "" { err := log.SetOutputByName(logfile) if err != nil { log.Fatal("Set log Output failed ", err) } log.Info("Set log Output to file ", logfile) log.SetRotateByDay() } cpus := c.DefaultInt("proxy::cpus", 4) log.Info("set runtime GOMAXPROCS to ", cpus) runtime.GOMAXPROCS(cpus) pc := &ProxyConfig{ Id: c.DefaultString("product::id", ""), Name: c.DefaultString("product::name", ""), Port: c.DefaultString("proxy::port", ""), SlaveOk: c.DefaultBool("proxy::slaveok", false), IdleTime: c.DefaultInt64("proxy::idletime", 300), MaxConn: c.DefaultInt64("proxy::maxconn", 60000), Statsd: c.DefaultString("proxy::statsd", ""), Zk: c.DefaultString("zk::zk", ""), ZkPath: c.DefaultString("zk::zkpath", ""), MulOpParallel: c.DefaultInt("proxy::mulparallel", 10), PoolSizePerNode: c.DefaultInt("proxy::poolsizepernode", 30), StatsdPrefix: c.DefaultString("proxy::prefix", "redis.proxy."), FileName: filename, } pc.Config = c nodes := c.DefaultString("proxy::nodes", "") if nodes == "" { log.Fatal("proxy nodes must not empty ") } pc.Nodes = strings.Split(nodes, ",") if pc.Id == "" || pc.Name == "" || pc.Port == "" { log.Fatal("id name or port must not empty") } if pc.PoolSizePerNode < MinPoolSizePerNode || pc.PoolSizePerNode > MaxPoolSizePerNode { log.Info("Adjust PoolSizePerNode to 30") pc.PoolSizePerNode = 30 } if pc.MulOpParallel < MinMulOpParallel || pc.MulOpParallel > MaxMulOpParallel { log.Info("Adjust MulOpParallel to 10") pc.MulOpParallel = 10 } if pc.MaxConn < MinMaxConn || pc.MaxConn > MaxMaxConn { log.Info("Adjust MaxConn to 60000") pc.MaxConn = 60000 } if pc.IdleTime < MinIdleTime || pc.IdleTime > MaxIdleTime { log.Info("Adjust MaxConn to 300") pc.IdleTime = 300 } fcpu := c.DefaultString("debug::cpufile", "") if fcpu != "" { f, err := os.Create(fcpu) if err != nil { log.Fatal(err) } pprof.StartCPUProfile(f) defer pprof.StopCPUProfile() } fmem := c.DefaultString("debug::memfile", "") if fmem != "" { f, err := os.Create(fmem) if err != nil { log.Fatal(err) } pprof.WriteHeapProfile(f) } return pc }