github.com/qxnw/lib4go@v0.0.0-20180426074627-c80c7e84b925/mq/kafka/kafka.consumer.go (about)

     1  package kafka
     2  
     3  /*
     4  import (
     5  	"fmt"
     6  	"os"
     7  	"os/signal"
     8  	"strings"
     9  
    10  	"github.com/Shopify/sarama"
    11  	"github.com/qxnw/lib4go/concurrent/cmap"
    12  	"github.com/qxnw/lib4go/mq"
    13  )
    14  
    15  //KafkaConsumer kafka consumer
    16  type KafkaConsumer struct {
    17  	address   string
    18  	consumers cmap.ConcurrentMap
    19  	quitChan  chan struct{}
    20  	*mq.OptionConf
    21  }
    22  type kafkaConsumer struct {
    23  	consumer sarama.Consumer
    24  	msgQueue chan *sarama.ConsumerMessage
    25  }
    26  
    27  //NewKafkaConsumer 初始化kafka Consumer
    28  func NewKafkaConsumer(address string, opts ...mq.Option) (kafka *KafkaConsumer, err error) {
    29  	kafka = &KafkaConsumer{address: address, quitChan: make(chan struct{}, 0)}
    30  	kafka.OptionConf = &mq.OptionConf{}
    31  	kafka.consumers = cmap.New(2)
    32  	for _, opt := range opts {
    33  		opt(kafka.OptionConf)
    34  	}
    35  	return
    36  }
    37  
    38  //Connect 连接到服务器
    39  func (k *KafkaConsumer) Connect() error {
    40  	return nil
    41  }
    42  
    43  //Consume 订阅消息
    44  func (k *KafkaConsumer) Consume(queue string, call func(mq.IMessage)) (err error) {
    45  	fmt.Println("启动接受消息")
    46  	_, cnsmr, _ := k.consumers.SetIfAbsentCb(queue, func(i ...interface{}) (interface{}, error) {
    47  		c := &kafkaConsumer{}
    48  		//c.consumer = kafka.NewBrokerConsumer(k.address, queue, 0, 0, 1048576)
    49  		//c.msgQueue = make(chan *kafka.Message, 10000)
    50  		c.consumer, err = sarama.NewConsumer(strings.Split(k.address, ","), nil)
    51  		c.msgQueue = make(chan *sarama.ConsumerMessage, 10000)
    52  		return c, nil
    53  	})
    54  	consumer := cnsmr.(*kafkaConsumer)
    55  
    56  	var (
    57  		chanmsg = make(chan *sarama.ConsumerMessage, 10000)
    58  		closing = make(chan struct{})
    59  	)
    60  
    61  	go func() {
    62  		signals := make(chan os.Signal, 1)
    63  		signal.Notify(signals, os.Kill, os.Interrupt)
    64  		<-signals
    65  		fmt.Println("Initiating shutdown of consumer...")
    66  		close(closing)
    67  	}()
    68  
    69  	pc, err := consumer.consumer.ConsumePartition(queue, 0, sarama.OffsetNewest)
    70  	if err != nil {
    71  		fmt.Printf("Failed to start consumer for partition %d: %s", 0, err)
    72  	}
    73  
    74  	go func(pc sarama.PartitionConsumer) {
    75  		<-closing
    76  		pc.AsyncClose()
    77  	}(pc)
    78  
    79  	fmt.Println("22222222222")
    80  	go func(pc sarama.PartitionConsumer) {
    81  		for {
    82  			select {
    83  			case message := <-pc.Messages():
    84  				chanmsg <- message
    85  			}
    86  		}
    87  	}(pc)
    88  
    89  	go func() {
    90  		fmt.Println("接受消息,使用对应函数")
    91  	LOOP:
    92  		for {
    93  			select {
    94  			case msg, ok := <-chanmsg:
    95  				if ok {
    96  					go call(NewKafkaMessage(msg))
    97  				} else {
    98  					break LOOP
    99  				}
   100  			}
   101  		}
   102  	}()
   103  
   104  	//close(chanmsg)
   105  
   106  	//if err := consumer.consumer.Close(); err != nil {
   107  	//fmt.Println("Failed to close consumer: ", err)
   108  	//}
   109  	return nil
   110  }
   111  
   112  //UnConsume 取消注册消费
   113  func (k *KafkaConsumer) UnConsume(queue string) {
   114  	if c, ok := k.consumers.Get(queue); ok {
   115  		consumer := c.(*kafkaConsumer)
   116  		close(consumer.msgQueue)
   117  	}
   118  }
   119  
   120  //Close 关闭当前连接
   121  func (k *KafkaConsumer) Close() {
   122  	close(k.quitChan)
   123  	k.consumers.IterCb(func(key string, value interface{}) bool {
   124  		consumer := value.(*kafkaConsumer)
   125  		close(consumer.msgQueue)
   126  		return true
   127  	})
   128  }
   129  
   130  type kafkaConsumerResolver struct {
   131  }
   132  
   133  func (s *kafkaConsumerResolver) Resolve(address string, opts ...mq.Option) (mq.MQConsumer, error) {
   134  	return NewKafkaConsumer(address, opts...)
   135  }
   136  func init() {
   137  	mq.RegisterCosnumer("kafka", &kafkaConsumerResolver{})
   138  }
   139  */