func main() { flagSet.Parse(os.Args[1:]) if *showVersion { fmt.Println(version.String("nsqlookupd")) return } signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) var cfg map[string]interface{} if *config != "" { _, err := toml.DecodeFile(*config, &cfg) if err != nil { log.Fatalf("ERROR: failed to load config file %s - %s", *config, err.Error()) } } opts := nsqlookupd.NewOptions() options.Resolve(opts, flagSet, cfg) daemon := nsqlookupd.New(opts) daemon.Main() <-signalChan daemon.Exit() }
func (p *program) Start() error { flagSet := nsqFlagset() flagSet.Parse(os.Args[1:]) rand.Seed(time.Now().UTC().UnixNano()) if flagSet.Lookup("version").Value.(flag.Getter).Get().(bool) { fmt.Println(version.String("nsqd")) os.Exit(0) } var cfg config configFile := flagSet.Lookup("config").Value.String() if configFile != "" { _, err := toml.DecodeFile(configFile, &cfg) if err != nil { log.Fatalf("ERROR: failed to load config file %s - %s", configFile, err.Error()) } } cfg.Validate() opts := nsqd.NewOptions() options.Resolve(opts, flagSet, cfg) nsqd := nsqd.New(opts) nsqd.LoadMetadata() err := nsqd.PersistMetadata() if err != nil { log.Fatalf("ERROR: failed to persist metadata - %s", err.Error()) } nsqd.Main() p.nsqd = nsqd return nil }
func New(opts *Options) *NSQLookupd { n := &NSQLookupd{ opts: opts, DB: NewRegistrationDB(), } n.logf(version.String("nsqlookupd")) return n }
func New(opts *Options) *NSQD { n := &NSQD{ flag: flagHealthy, startTime: time.Now(), topicMap: make(map[string]*Topic), idChan: make(chan MessageID, 4096), exitChan: make(chan int), notifyChan: make(chan interface{}), optsNotificationChan: make(chan struct{}, 1), ci: clusterinfo.New(opts.Logger, http_api.NewClient(nil)), } n.swapOpts(opts) if opts.MaxDeflateLevel < 1 || opts.MaxDeflateLevel > 9 { n.logf("FATAL: --max-deflate-level must be [1,9]") os.Exit(1) } if opts.ID < 0 || opts.ID >= 1024 { n.logf("FATAL: --worker-id must be [0,1024)") os.Exit(1) } if opts.StatsdPrefix != "" { _, port, err := net.SplitHostPort(opts.HTTPAddress) if err != nil { n.logf("ERROR: failed to parse HTTP address (%s) - %s", opts.HTTPAddress, err) os.Exit(1) } statsdHostKey := statsd.HostKey(net.JoinHostPort(opts.BroadcastAddress, port)) prefixWithHost := strings.Replace(opts.StatsdPrefix, "%s", statsdHostKey, -1) if prefixWithHost[len(prefixWithHost)-1] != '.' { prefixWithHost += "." } opts.StatsdPrefix = prefixWithHost } if opts.TLSClientAuthPolicy != "" && opts.TLSRequired == TLSNotRequired { opts.TLSRequired = TLSRequired } tlsConfig, err := buildTLSConfig(opts) if err != nil { n.logf("FATAL: failed to build TLS config - %s", err) os.Exit(1) } if tlsConfig == nil && opts.TLSRequired != TLSNotRequired { n.logf("FATAL: cannot require TLS client connections without TLS key and cert") os.Exit(1) } n.tlsConfig = tlsConfig n.logf(version.String("nsqd")) n.logf("ID: %d", opts.ID) return n }
func (p *program) Start() error { //解析用户输入的命令 flagSet := nsqFlagset() flagSet.Parse(os.Args[1:]) rand.Seed(time.Now().UTC().UnixNano()) //输出版本号并结束 if flagSet.Lookup("version").Value.(flag.Getter).Get().(bool) { fmt.Println(version.String("nsqd")) os.Exit(0) } //读取配置文件 var cfg config configFile := flagSet.Lookup("config").Value.String() if configFile != "" { _, err := toml.DecodeFile(configFile, &cfg) if err != nil { log.Fatalf("ERROR: failed to load config file %s - %s", configFile, err.Error()) } } //验证配置文件 cfg.Validate() //载入默认配置选项 opts := nsqd.NewOptions() //整合配置选项(优先级:--???--) options.Resolve(opts, flagSet, cfg) //建立服务(载入基本配置) nsqd := nsqd.New(opts) //启动服务前 恢复数据(从硬盘载入数据) nsqd.LoadMetadata() //将内存中的数据写入到硬盘文件中 (创建新文件 保留旧文件--???--) err := nsqd.PersistMetadata() if err != nil { log.Fatalf("ERROR: failed to persist metadata - %s", err.Error()) } nsqd.Main() p.nsqd = nsqd return nil }
func main() { flagSet := nsqFlagset() flagSet.Parse(os.Args[1:]) rand.Seed(time.Now().UTC().UnixNano()) if flagSet.Lookup("version").Value.(flag.Getter).Get().(bool) { fmt.Println(version.String("nsqd")) return } signalChan := make(chan os.Signal, 1) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) var cfg config configFile := flagSet.Lookup("config").Value.String() if configFile != "" { _, err := toml.DecodeFile(configFile, &cfg) if err != nil { log.Fatalf("ERROR: failed to load config file %s - %s", configFile, err.Error()) } } cfg.Validate() opts := nsqd.NewOptions() options.Resolve(opts, flagSet, cfg) nsqd := nsqd.New(opts) nsqd.LoadMetadata() err := nsqd.PersistMetadata() if err != nil { log.Fatalf("ERROR: failed to persist metadata - %s", err.Error()) } nsqd.Main() <-signalChan nsqd.Exit() }
func (p *program) Start() error { flagSet.Parse(os.Args[1:]) if *showVersion { fmt.Println(version.String("nsqlookupd")) os.Exit(0) } var cfg map[string]interface{} if *config != "" { _, err := toml.DecodeFile(*config, &cfg) if err != nil { log.Fatalf("ERROR: failed to load config file %s - %s", *config, err.Error()) } } opts := nsqlookupd.NewOptions() options.Resolve(opts, flagSet, cfg) daemon := nsqlookupd.New(opts) daemon.Main() p.nsqlookupd = daemon return nil }
func main() { flagSet.Parse(os.Args[1:]) if *showVersion { fmt.Println(version.String("nsqadmin")) return } if *templateDir != "" { log.Printf("WARNING: --template-dir is deprecated and will be removed in the next release (templates are now compiled into the binary)") } exitChan := make(chan int) signalChan := make(chan os.Signal, 1) go func() { <-signalChan exitChan <- 1 }() signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) var cfg map[string]interface{} if *config != "" { _, err := toml.DecodeFile(*config, &cfg) if err != nil { log.Fatalf("ERROR: failed to load config file %s - %s", *config, err) } } opts := nsqadmin.NewOptions() options.Resolve(opts, flagSet, cfg) nsqadmin := nsqadmin.New(opts) nsqadmin.Main() <-exitChan nsqadmin.Exit() }
func (s *httpServer) printStats(stats []TopicStats, health string, startTime time.Time, uptime time.Duration) []byte { var buf bytes.Buffer w := &buf now := time.Now() io.WriteString(w, fmt.Sprintf("%s\n", version.String("nsqd"))) io.WriteString(w, fmt.Sprintf("start_time %v\n", startTime.Format(time.RFC3339))) io.WriteString(w, fmt.Sprintf("uptime %s\n", uptime)) if len(stats) == 0 { io.WriteString(w, "\nNO_TOPICS\n") return buf.Bytes() } io.WriteString(w, fmt.Sprintf("\nHealth: %s\n", health)) for _, t := range stats { var pausedPrefix string if t.Paused { pausedPrefix = "*P " } else { pausedPrefix = " " } io.WriteString(w, fmt.Sprintf("\n%s[%-15s] depth: %-5d be-depth: %-5d msgs: %-8d e2e%%: %s\n", pausedPrefix, t.TopicName, t.Depth, t.BackendDepth, t.MessageCount, t.E2eProcessingLatency)) for _, c := range t.Channels { if c.Paused { pausedPrefix = " *P " } else { pausedPrefix = " " } io.WriteString(w, fmt.Sprintf("%s[%-25s] depth: %-5d be-depth: %-5d inflt: %-4d def: %-4d re-q: %-5d timeout: %-5d msgs: %-8d e2e%%: %s\n", pausedPrefix, c.ChannelName, c.Depth, c.BackendDepth, c.InFlightCount, c.DeferredCount, c.RequeueCount, c.TimeoutCount, c.MessageCount, c.E2eProcessingLatency)) for _, client := range c.Clients { connectTime := time.Unix(client.ConnectTime, 0) // truncate to the second duration := time.Duration(int64(now.Sub(connectTime).Seconds())) * time.Second _, port, _ := net.SplitHostPort(client.RemoteAddress) io.WriteString(w, fmt.Sprintf(" [%s %-21s] state: %d inflt: %-4d rdy: %-4d fin: %-8d re-q: %-8d msgs: %-8d connected: %s\n", client.Version, fmt.Sprintf("%s:%s", client.Name, port), client.State, client.InFlightCount, client.ReadyCount, client.FinishCount, client.RequeueCount, client.MessageCount, duration, )) } } } return buf.Bytes() }
func New(opts *Options) *NSQD { dataPath := opts.DataPath if opts.DataPath == "" { cwd, _ := os.Getwd() dataPath = cwd } n := &NSQD{ startTime: time.Now(), topicMap: make(map[string]*Topic), idChan: make(chan MessageID, 4096), exitChan: make(chan int), notifyChan: make(chan interface{}), optsNotificationChan: make(chan struct{}, 1), ci: clusterinfo.New(opts.Logger, http_api.NewClient(nil, opts.HTTPClientConnectTimeout, opts.HTTPClientRequestTimeout)), dl: dirlock.New(dataPath), } n.swapOpts(opts) n.errValue.Store(errStore{}) err := n.dl.Lock() if err != nil { n.logf("FATAL: --data-path=%s in use (possibly by another instance of nsqd)", dataPath) os.Exit(1) } if opts.MaxDeflateLevel < 1 || opts.MaxDeflateLevel > 9 { n.logf("FATAL: --max-deflate-level must be [1,9]") os.Exit(1) } if opts.ID < 0 || opts.ID >= 1024 { n.logf("FATAL: --worker-id must be [0,1024)") os.Exit(1) } if opts.StatsdPrefix != "" { var port string _, port, err = net.SplitHostPort(opts.HTTPAddress) if err != nil { n.logf("ERROR: failed to parse HTTP address (%s) - %s", opts.HTTPAddress, err) os.Exit(1) } statsdHostKey := statsd.HostKey(net.JoinHostPort(opts.BroadcastAddress, port)) prefixWithHost := strings.Replace(opts.StatsdPrefix, "%s", statsdHostKey, -1) if prefixWithHost[len(prefixWithHost)-1] != '.' { prefixWithHost += "." } opts.StatsdPrefix = prefixWithHost } if opts.TLSClientAuthPolicy != "" && opts.TLSRequired == TLSNotRequired { opts.TLSRequired = TLSRequired } tlsConfig, err := buildTLSConfig(opts) if err != nil { n.logf("FATAL: failed to build TLS config - %s", err) os.Exit(1) } if tlsConfig == nil && opts.TLSRequired != TLSNotRequired { n.logf("FATAL: cannot require TLS client connections without TLS key and cert") os.Exit(1) } n.tlsConfig = tlsConfig n.logf(version.String("nsqd")) n.logf("ID: %d", opts.ID) return n }
func New(opts *Options) *NSQD { //缓存消息的磁盘路径 dataPath := opts.DataPath if opts.DataPath == "" { cwd, _ := os.Getwd() dataPath = cwd } n := &NSQD{ startTime: time.Now(), topicMap: make(map[string]*Topic), idChan: make(chan MessageID, 4096), exitChan: make(chan int), notifyChan: make(chan interface{}), optsNotificationChan: make(chan struct{}, 1), //WEB接听 ci: clusterinfo.New(opts.Logger, http_api.NewClient(nil)), dl: dirlock.New(dataPath), } // 设置原子操作对象(配置信息) --???--是否还可以正常方式读写 (sync/atomic) (原子操作的效率要比锁来的高) n.swapOpts(opts) n.errValue.Store(errStore{}) //阻止数据库文件的外来操作 err := n.dl.Lock() if err != nil { n.logf("FATAL: --data-path=%s in use (possibly by another instance of nsqd)", dataPath) os.Exit(1) } //-max-deflate-level=6: 最大的压缩比率等级 if opts.MaxDeflateLevel < 1 || opts.MaxDeflateLevel > 9 { n.logf("FATAL: --max-deflate-level must be [1,9]") os.Exit(1) } //-worker-id=0: 进程的唯一码(默认是主机名的哈希值) if opts.ID < 0 || opts.ID >= 1024 { n.logf("FATAL: --worker-id must be [0,1024)") os.Exit(1) } //-statsd-prefix="nsq.%s": 发送给统计keys 的前缀(%s for host replacement) if opts.StatsdPrefix != "" { //生成显示前缀 var port string //-http-address="0.0.0.0:4151": 为 HTTP 客户端监听 <addr>:<port> _, port, err = net.SplitHostPort(opts.HTTPAddress) if err != nil { n.logf("ERROR: failed to parse HTTP address (%s) - %s", opts.HTTPAddress, err) os.Exit(1) } statsdHostKey := statsd.HostKey(net.JoinHostPort(opts.BroadcastAddress, port)) prefixWithHost := strings.Replace(opts.StatsdPrefix, "%s", statsdHostKey, -1) if prefixWithHost[len(prefixWithHost)-1] != '.' { prefixWithHost += "." } opts.StatsdPrefix = prefixWithHost } //TLS安全文件传输协议 if opts.TLSClientAuthPolicy != "" && opts.TLSRequired == TLSNotRequired { opts.TLSRequired = TLSRequired } tlsConfig, err := buildTLSConfig(opts) if err != nil { n.logf("FATAL: failed to build TLS config - %s", err) os.Exit(1) } if tlsConfig == nil && opts.TLSRequired != TLSNotRequired { n.logf("FATAL: cannot require TLS client connections without TLS key and cert") os.Exit(1) } n.tlsConfig = tlsConfig n.logf(version.String("nsqd")) n.logf("ID: %d", opts.ID) return n }
func New(opts *Options) *NSQAdmin { n := &NSQAdmin{ opts: opts, notifications: make(chan *AdminAction), } if len(opts.NSQDHTTPAddresses) == 0 && len(opts.NSQLookupdHTTPAddresses) == 0 { n.logf("--nsqd-http-address or --lookupd-http-address required.") os.Exit(1) } if len(opts.NSQDHTTPAddresses) != 0 && len(opts.NSQLookupdHTTPAddresses) != 0 { n.logf("use --nsqd-http-address or --lookupd-http-address not both") os.Exit(1) } // verify that the supplied address is valid verifyAddress := func(arg string, address string) *net.TCPAddr { addr, err := net.ResolveTCPAddr("tcp", address) if err != nil { n.logf("FATAL: failed to resolve %s address (%s) - %s", arg, address, err) os.Exit(1) } return addr } if opts.HTTPClientTLSCert != "" && opts.HTTPClientTLSKey == "" { n.logf("FATAL: --http-client-tls-key must be specified with --http-client-tls-cert") os.Exit(1) } if opts.HTTPClientTLSKey != "" && opts.HTTPClientTLSCert == "" { n.logf("FATAL: --http-client-tls-cert must be specified with --http-client-tls-key") os.Exit(1) } n.httpClientTLSConfig = &tls.Config{ InsecureSkipVerify: opts.HTTPClientTLSInsecureSkipVerify, } if opts.HTTPClientTLSCert != "" && opts.HTTPClientTLSKey != "" { cert, err := tls.LoadX509KeyPair(opts.HTTPClientTLSCert, opts.HTTPClientTLSKey) if err != nil { n.logf("FATAL: failed to LoadX509KeyPair %s, %s - %s", opts.HTTPClientTLSCert, opts.HTTPClientTLSKey, err) os.Exit(1) } n.httpClientTLSConfig.Certificates = []tls.Certificate{cert} } if opts.HTTPClientTLSRootCAFile != "" { tlsCertPool := x509.NewCertPool() caCertFile, err := ioutil.ReadFile(opts.HTTPClientTLSRootCAFile) if err != nil { n.logf("FATAL: failed to read TLS root CA file %s - %s", opts.HTTPClientTLSRootCAFile, err) os.Exit(1) } if !tlsCertPool.AppendCertsFromPEM(caCertFile) { n.logf("FATAL: failed to AppendCertsFromPEM %s", opts.HTTPClientTLSRootCAFile) os.Exit(1) } n.httpClientTLSConfig.ClientCAs = tlsCertPool } // require that both the hostname and port be specified for _, address := range opts.NSQLookupdHTTPAddresses { verifyAddress("--lookupd-http-address", address) } for _, address := range opts.NSQDHTTPAddresses { verifyAddress("--nsqd-http-address", address) } if opts.ProxyGraphite { url, err := url.Parse(opts.GraphiteURL) if err != nil { n.logf("FATAL: failed to parse --graphite-url='%s' - %s", opts.GraphiteURL, err) os.Exit(1) } n.graphiteURL = url } n.logf(version.String("nsqadmin")) return n }