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 */