Beispiel #1
0
func startBenchLookupRegUnreg() {
	var wg sync.WaitGroup
	start := time.Now()
	eachCnt := *size * 10
	hostname, _ := os.Hostname()
	for i := 0; i < *concurrency; i++ {
		wg.Add(1)
		go func() {
			defer wg.Done()
			lookupPeer := clusterinfo.NewLookupPeer(*lookupAddress, 1024*1024*10, &levellogger.GLogger{},
				connectCallback("bench_reg_"+strconv.Itoa(i), hostname))
			lookupPeer.Command(nil) // start the connection

			cmd := nsq.Ping()
			resp, err := lookupPeer.Command(cmd)
			if err != nil {
				log.Printf("ping lookup error : %v\n", err)
				return
			} else {
				log.Printf("ping lookup  : %v\n", resp)
			}
			cnt := eachCnt
			for cnt > 0 {
				cnt--
				for _, t := range topics {
					cmd = nsq.UnRegister(t,
						strconv.Itoa(i), "")
					lookupPeer.Command(cmd)
					cmd = nsq.Register(t,
						strconv.Itoa(i), "")
					lookupPeer.Command(cmd)
					for ch := 0; ch < 10; ch++ {
						cmd = nsq.UnRegister(t,
							strconv.Itoa(i), "ch"+strconv.Itoa(ch))
						lookupPeer.Command(cmd)
						cmd = nsq.Register(t,
							strconv.Itoa(i), "ch"+strconv.Itoa(ch))
						lookupPeer.Command(cmd)
					}
				}
			}
		}()
	}
	wg.Wait()
	runSec := time.Now().Sub(start).Seconds() + 1
	log.Printf(" %v request done in %v seconds, qps: %v\n", *concurrency*eachCnt, runSec,
		float64(*concurrency*eachCnt)/runSec)
}
Beispiel #2
0
func (n *NsqdServer) lookupLoop(pingInterval time.Duration, metaNotifyChan chan interface{}, optsNotifyChan chan struct{}, exitChan chan int) {
	var lookupPeers []*clusterinfo.LookupPeer
	var lookupAddrs []string
	syncTopicChan := make(chan *clusterinfo.LookupPeer, 2)
	changed := true

	hostname, err := os.Hostname()
	if err != nil {
		nsqd.NsqLogger().LogErrorf("failed to get hostname - %s", err)
		os.Exit(1)
	}

	// for announcements, lookupd determines the host automatically
	ticker := time.Tick(pingInterval)
	allHosts := make([]string, 0)
	discoveryAddrs := make([]string, 0)
	discoveryAddrs, _ = n.discoverLookupdNodes(discoveryAddrs)

	for {
		if changed {
			allHosts = allHosts[:0]
			allHosts = append(allHosts, n.ctx.getOpts().NSQLookupdTCPAddresses...)
			allHosts = append(allHosts, discoveryAddrs...)
			nsqd.NsqLogger().Logf("all lookup hosts: %v", allHosts)

			var tmpPeers []*clusterinfo.LookupPeer
			var tmpAddrs []string

			for _, lp := range lookupPeers {
				if in(lp.String(), allHosts) {
					tmpPeers = append(tmpPeers, lp)
					tmpAddrs = append(tmpAddrs, lp.String())
					continue
				}
				nsqd.NsqLogger().Logf("LOOKUP(%s): removing peer", lp)
				lp.Close()
			}
			lookupPeers = tmpPeers
			lookupAddrs = tmpAddrs

			for _, host := range allHosts {
				if in(host, lookupAddrs) {
					continue
				}
				nsqd.NsqLogger().Logf("LOOKUP(%s): adding peer", host)
				lookupPeer := clusterinfo.NewLookupPeer(host, n.ctx.getOpts().MaxBodySize, n.ctx.getOpts().Logger,
					connectCallback(n.ctx, hostname, syncTopicChan, exitChan))
				lookupPeer.Command(nil) // start the connection
				lookupPeers = append(lookupPeers, lookupPeer)
				lookupAddrs = append(lookupAddrs, host)
			}
			n.lookupPeers.Store(lookupPeers)
			changed = false
		}

		select {
		case <-ticker:
			// send a heartbeat and read a response (read detects closed conns)
			for _, lp := range lookupPeers {
				nsqd.NsqLogger().LogDebugf("LOOKUPD(%s): sending heartbeat", lp)
				cmd := nsq.Ping()
				_, err := lp.Command(cmd)
				if err != nil {
					nsqd.NsqLogger().Logf("LOOKUPD(%s): ERROR %s - %s", lp, cmd, err)
				}
			}
			discoveryChanged := false
			discoveryAddrs, discoveryChanged = n.discoverLookupdNodes(discoveryAddrs)
			if discoveryChanged {
				changed = true
			}
		case val := <-metaNotifyChan:
			var cmd *nsq.Command
			var branch string

			switch val.(type) {
			case *nsqd.Channel:
				// notify all nsqlookupds that a new channel exists, or that it's removed
				// For channel, we just know the full topic name without
				// knowing the partition
				branch = "channel"
				channel := val.(*nsqd.Channel)
				if channel.Exiting() == true || channel.IsConsumeDisabled() {
					cmd = nsq.UnRegister(channel.GetTopicName(),
						strconv.Itoa(channel.GetTopicPart()), channel.GetName())
				} else {
					cmd = nsq.Register(channel.GetTopicName(),
						strconv.Itoa(channel.GetTopicPart()), channel.GetName())
				}
			case *nsqd.Topic:
				// notify all nsqlookupds that a new topic exists, or that it's removed
				branch = "topic"
				topic := val.(*nsqd.Topic)
				if topic.Exiting() == true || topic.IsWriteDisabled() {
					cmd = nsq.UnRegister(topic.GetTopicName(),
						strconv.Itoa(topic.GetTopicPart()), "")
				} else {
					cmd = nsq.Register(topic.GetTopicName(),
						strconv.Itoa(topic.GetTopicPart()), "")
				}
			}

			errLookupPeers := make([]*clusterinfo.LookupPeer, 0)
			for _, lp := range lookupPeers {
				nsqd.NsqLogger().Logf("LOOKUPD(%s): %s %s", lp, branch, cmd)
				_, err := lp.Command(cmd)
				if err != nil {
					nsqd.NsqLogger().LogErrorf("LOOKUPD(%s): ERROR %s - %s", lp, cmd, err)
					errLookupPeers = append(errLookupPeers, lp)
				}
			}
			if len(errLookupPeers) > 0 {
				go func() {
					time.Sleep(time.Second * 3)
					for _, l := range errLookupPeers {
						select {
						case syncTopicChan <- l:
						case <-exitChan:
							return
						default:
							continue
						}
					}
				}()
			}
		case lp := <-syncTopicChan:
			if in(lp.String(), allHosts) {
			} else {
				nsqd.NsqLogger().Logf("LOOKUP(%s): already removed ", lp)
				lp.Close()
				continue
			}

			nsqd.NsqLogger().Logf("do full sync with lookup: %v", lp)
			var commands []*nsq.Command
			// build all the commands first so we exit the lock(s) as fast as possible
			topicMap := n.ctx.nsqd.GetTopicMapCopy()
			for _, topicParts := range topicMap {
				for _, topic := range topicParts {
					if topic.IsWriteDisabled() {
						continue
					}
					channelMap := topic.GetChannelMapCopy()
					commands = append(commands,
						nsq.Register(topic.GetTopicName(),
							strconv.Itoa(topic.GetTopicPart()), ""))
					for _, channel := range channelMap {
						commands = append(commands,
							nsq.Register(channel.GetTopicName(),
								strconv.Itoa(channel.GetTopicPart()), channel.GetName()))
					}
				}
			}

			for index, cmd := range commands {
				nsqd.NsqLogger().Logf("LOOKUPD(%s): %s", lp, cmd)
				_, err := lp.Command(cmd)
				if err != nil {
					nsqd.NsqLogger().LogErrorf("LOOKUPD(%s): ERROR %s - %s", lp, cmd, err)
					if in(lp.String(), allHosts) {
						go func() {
							time.Sleep(time.Second * 3)
							select {
							case syncTopicChan <- lp:
							case <-exitChan:
								return
							default:
							}
						}()
					}
					break
				}
				// avoid too much command once, we need sleep here
				if index%10 == 0 {
					time.Sleep(time.Millisecond)
				}
			}
		case <-optsNotifyChan:
			nsqd.NsqLogger().Logf("got opts notify, check new lookup")
			changed = true
			discoveryChanged := false
			discoveryAddrs, discoveryChanged = n.discoverLookupdNodes(discoveryAddrs)
			if discoveryChanged {
				changed = true
			}
		case <-exitChan:

			goto exit
		}
	}

exit:
	nsqd.NsqLogger().Logf("LOOKUP: closing")
}