consumer.go 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package nsqclient
  2. import (
  3. "context"
  4. "fmt"
  5. "time"
  6. nsq "github.com/nsqio/go-nsq"
  7. )
  8. type NsqConsumer struct {
  9. consumer *nsq.Consumer
  10. // handler nsq.Handler
  11. handler func([]byte) error
  12. ctx context.Context
  13. ctxCancel context.CancelFunc
  14. topic string
  15. channel string
  16. }
  17. func NewNsqConsumer(ctx context.Context, topic, channel string, options ...func(*nsq.Config)) (*NsqConsumer, error) {
  18. conf := nsq.NewConfig()
  19. conf.MaxAttempts = 0
  20. conf.MsgTimeout = 10 * time.Minute // 默认一个消息最多能处理十分钟,否则就会重新丢入队列
  21. conf.LookupdPollInterval = 3 * time.Second // 调整consumer的重连间隔时间为3秒
  22. for _, option := range options {
  23. option(conf)
  24. }
  25. consumer, err := nsq.NewConsumer(topic, channel, conf)
  26. if err != nil {
  27. return nil, err
  28. }
  29. return &NsqConsumer{
  30. consumer: consumer,
  31. ctx: ctx,
  32. topic: topic,
  33. channel: channel,
  34. }, nil
  35. }
  36. func DestroyNsqConsumer(c *NsqConsumer) {
  37. if c != nil {
  38. if c.ctxCancel != nil {
  39. c.ctxCancel()
  40. }
  41. }
  42. }
  43. // func (n *NsqConsumer) AddHandler(handler nsq.Handler) {
  44. // n.handler = handler
  45. // }
  46. func (n *NsqConsumer) AddHandler(handler func([]byte) error) {
  47. n.handler = handler
  48. }
  49. func (n *NsqConsumer) Run(qaddr string, concurrency int) error {
  50. return n.RunDistributed([]string{qaddr}, nil, concurrency)
  51. }
  52. func (n *NsqConsumer) RunLookupd(lookupAddr string, concurrency int) error {
  53. return n.RunDistributed(nil, []string{lookupAddr}, concurrency)
  54. }
  55. func (n *NsqConsumer) RunDistributed(qAddr, lAddr []string, concurrency int) error {
  56. n.consumer.ChangeMaxInFlight(concurrency)
  57. // n.consumer.AddConcurrentHandlers(n.handler, concurrency)
  58. n.consumer.AddConcurrentHandlers(nsq.HandlerFunc(func(msg *nsq.Message) error {
  59. return n.handler(msg.Body)
  60. // return nil
  61. }), concurrency)
  62. var err error
  63. if len(qAddr) > 0 {
  64. err = n.consumer.ConnectToNSQDs(qAddr)
  65. } else if len(lAddr) > 0 {
  66. err = n.consumer.ConnectToNSQLookupds(lAddr)
  67. } else {
  68. err = fmt.Errorf("Addr Must NOT Empty")
  69. }
  70. if err != nil {
  71. return err
  72. }
  73. if n.ctx == nil {
  74. n.ctx, n.ctxCancel = context.WithCancel(context.Background())
  75. }
  76. for {
  77. select {
  78. case <-n.ctx.Done():
  79. fmt.Println("[%s] %s,%s", "stop consumer", n.topic, n.channel)
  80. n.consumer.Stop()
  81. fmt.Println("[%s] %s,%s", "stop consumer success", n.topic, n.channel)
  82. return nil
  83. }
  84. }
  85. }