github.com/teng231/kafclient@v1.2.9/publisher.go (about)

     1  package kafclient
     2  
     3  import (
     4  	"encoding/json"
     5  	"errors"
     6  	"log"
     7  	"strings"
     8  
     9  	"github.com/Shopify/sarama"
    10  )
    11  
    12  func makeKafkaConfigPublisher(partitioner sarama.PartitionerConstructor) *sarama.Config {
    13  	config := sarama.NewConfig()
    14  	config.Producer.Retry.Max = 5
    15  	config.Producer.RequiredAcks = sarama.WaitForAll
    16  	config.Producer.Return.Successes = true
    17  	// config.Producer.Partitioner = sarama.NewManualPartitioner()
    18  	config.Producer.Partitioner = partitioner
    19  	// publisherConfig = config
    20  	return config
    21  }
    22  
    23  func newPublisher(topic string, brokerURLs ...string) (sarama.SyncProducer, error) {
    24  	config := makeKafkaConfigPublisher(sarama.NewRandomPartitioner)
    25  	prd, err := sarama.NewSyncProducer(brokerURLs, config)
    26  	if err != nil {
    27  		return nil, err
    28  	}
    29  	return prd, nil
    30  }
    31  
    32  func newAsyncPublisher(topic string, brokerURLs ...string) (sarama.AsyncProducer, error) {
    33  	config := makeKafkaConfigPublisher(sarama.NewRandomPartitioner)
    34  	prd, err := sarama.NewAsyncProducer(brokerURLs, config)
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	return prd, nil
    39  }
    40  
    41  func newPublisherWithConfigPartitioner(topic *Topic, brokerURLs ...string) (sarama.SyncProducer, error) {
    42  	var config *sarama.Config
    43  	if topic.Partition == nil {
    44  		config = makeKafkaConfigPublisher(sarama.NewRandomPartitioner)
    45  	} else if ToInt32(topic.Partition) >= 0 {
    46  		config = makeKafkaConfigPublisher(sarama.NewManualPartitioner)
    47  	}
    48  	prd, err := sarama.NewSyncProducer(brokerURLs, config)
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	return prd, nil
    53  }
    54  
    55  // InitPublisher init with addr is url of lookupd
    56  func (ps *Client) InitPublisher(brokerURLs ...string) {
    57  	ps.brokerURLs = brokerURLs
    58  	// ps.producers = make(map[string]sarama.SyncProducer)
    59  }
    60  
    61  // Publish sync publish message
    62  func (p *Client) Publish(topic string, messages ...interface{}) error {
    63  	if strings.Contains(topic, "__consumer_offsets") {
    64  		return errors.New("topic fail")
    65  	}
    66  
    67  	if _, ok := p.mProducer.Load(topic); !ok {
    68  		producer, err := newPublisher(topic, p.brokerURLs...)
    69  		if err != nil {
    70  			log.Print("[sarama]:", err, "]: topic", topic)
    71  			return err
    72  		}
    73  		p.mProducer.Store(topic, producer)
    74  	}
    75  	listMsg := make([]*sarama.ProducerMessage, 0)
    76  	for _, msg := range messages {
    77  		bin, err := json.Marshal(msg)
    78  		if err != nil {
    79  			log.Printf("[sarama] error: %v[sarama] msg: %v", err, msg)
    80  		}
    81  		msg := &sarama.ProducerMessage{
    82  			Topic:     topic,
    83  			Value:     sarama.StringEncoder(bin),
    84  			Partition: -1,
    85  		}
    86  		// asyncProducer.(sarama.AsyncProducer).Input() <- msg
    87  		listMsg = append(listMsg, msg)
    88  	}
    89  	syncProducer, ok := p.mProducer.Load(topic)
    90  	if !ok {
    91  		log.Print("not found any sync Producer")
    92  	}
    93  	err := syncProducer.(sarama.SyncProducer).SendMessages(listMsg)
    94  	return err
    95  }
    96  
    97  // AsyncPublish async publish message
    98  func (p *Client) AsyncPublish(topic string, messages ...interface{}) error {
    99  	if strings.Contains(topic, "__consumer_offsets") {
   100  		return errors.New("topic fail")
   101  	}
   102  
   103  	if _, ok := p.mProducer.Load(topic); !ok {
   104  		producer, err := newAsyncPublisher(topic, p.brokerURLs...)
   105  		if err != nil {
   106  			log.Print("[sarama]:", err, "]: topic", topic)
   107  			return err
   108  		}
   109  		p.mProducer.Store(topic, producer)
   110  	}
   111  	asyncProducer, _ := p.mProducer.Load(topic)
   112  	for _, msg := range messages {
   113  		bin, err := json.Marshal(msg)
   114  		if err != nil {
   115  			log.Printf("[sarama] error: %v[sarama] msg: %v", err, msg)
   116  		}
   117  		msg := &sarama.ProducerMessage{
   118  			Topic:     topic,
   119  			Value:     sarama.StringEncoder(bin),
   120  			Partition: -1,
   121  		}
   122  		asyncProducer.(sarama.AsyncProducer).Input() <- msg
   123  	}
   124  	return nil
   125  }
   126  
   127  // PublishWithConfig sync publish message with select config
   128  // Sender config help config producerMessage
   129  func (p *Client) PublishWithConfig(topic *Topic, config *SenderConfig, messages ...interface{}) error {
   130  	if strings.Contains(topic.Name, "__consumer_offsets") {
   131  		return errors.New("topic fail")
   132  	}
   133  	if _, ok := p.mProducer.Load(topic); !ok {
   134  		producer, err := newPublisherWithConfigPartitioner(topic, p.brokerURLs...)
   135  		if err != nil {
   136  			log.Print("[sarama]:", err, "]: topic", topic)
   137  			return err
   138  		}
   139  		p.mProducer.Store(topic, producer)
   140  	}
   141  	listMsg := make([]*sarama.ProducerMessage, 0)
   142  	for _, msg := range messages {
   143  		bin, err := json.Marshal(msg)
   144  		if err != nil {
   145  			log.Printf("[sarama] error: %v[sarama] msg: %v", err, msg)
   146  		}
   147  		pmsg := &sarama.ProducerMessage{
   148  			Topic:     topic.Name,
   149  			Value:     sarama.StringEncoder(bin),
   150  			Partition: -1,
   151  		}
   152  		if topic.Partition != nil {
   153  			pmsg.Partition = ToInt32(topic.Partition)
   154  		}
   155  
   156  		if config != nil {
   157  			pmsg.Metadata = config.Metadata
   158  			if len(config.Headers) > 0 {
   159  				for k, v := range config.Headers {
   160  					pmsg.Headers = append(pmsg.Headers, sarama.RecordHeader{Key: []byte(k), Value: []byte(v)})
   161  				}
   162  			}
   163  		}
   164  		listMsg = append(listMsg, pmsg)
   165  
   166  	}
   167  	syncProducer, ok := p.mProducer.Load(topic)
   168  	if !ok {
   169  		log.Print("not found any sync Producer")
   170  	}
   171  	err := syncProducer.(sarama.SyncProducer).SendMessages(listMsg)
   172  	return err
   173  }