6、應用開發

1、開發一個生產者應用,如下:

package com.cattsoft;
import java.util.Properties;
import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;

public class KafkaProducer {

    static String message = "kafka message producer!";

    public static void main(String[] args) {
        System.out.println("生產消息開始!!!");
        Properties props = new Properties();
        /* 發送實際數據的socket連接將基於返回的metadata數據信息而建立 */
        props.setProperty("metadata.broker.list", "172.168.10.48:9092,172.168.10.49:9092,172.168.10.54:9092");
        /* 消息的序列化類別。默認編碼器輸入一個字節byte[],然後返回相同的字節byte[] */
        props.setProperty("serializer.class", "kafka.serializer.StringEncoder");

        /*
         * 此選項置頂了消息是否在後臺線程中異步發送。正確的值: (1) async: 異步發送 (2) sync: 同步發送
         * 通過將producer設置爲異步,我們可以批量處理請求(有利於提高吞吐率)但是這也就造成了客戶端機器丟掉未發送數據的可能性
         */
        props.setProperty("producer.type", "asyc");

        /*
         * 僅僅for sync 0:
         * 表示producer從來不等待來自broker的確認信息(和0.7一樣的行爲)。這個選擇提供了最小的時延但同時風險最大(
         * 因爲當server宕機時,數據將會丟失)。 1:表示獲得leader
         * replica已經接收了數據的確認信息。這個選擇時延較小同時確保了server確認接收成功。
         * -1:producer會獲得所有同步replicas都收到數據的確認,同時時延最大。
         */
        props.put("request.required.acks", "1");
        /* 確認超時時間 */
        props.put("request.timeout.ms", 1000);
        /* broker盡力實現request.required.acks需求時的等待時間,否則會發送錯誤到客戶端 */
        props.put("request.timeout.ms", 10000);
        /* 此項參數可以設置壓縮數據的codec,可選codec爲:“none”, “gzip”, “snappy” */
        props.put("compression.codec", "none");
        /* 在設置了壓縮的情況下,可以指定特定的topic壓縮,爲指定則全部壓縮 */
        props.put("compressed.topics", null);
        /* 消息發送最大嘗試次數 */
        props.put("message.send.max.retries", 3);

        /* 批量消息的數量,僅僅for asyc */
        props.put("batch.num.messages", 100);

        /*
         * 當應用async模式時,用戶緩存數據的最大時間間隔。例如,設置爲100時,將會批量處理100ms之內消息。這將改善吞吐率,
         * 但是會增加由於緩存產生的延遲。
         */
        props.put("queue.buffering.max.ms", 5000);

        /* producer 緩存的消息的最大數量,僅僅for asyc */
        props.put("queue.buffering.max.message", 1000);

        /* 必須實現kafka.producer.Partitioner,根據Key提供一個分區策略 */
        props.put("partitioner.class", "kafka.producer.DefaultPartitioner");

        ProducerConfig config = new ProducerConfig(props);
        Producer<String, String> producer = new Producer<String, String>(config);
        String topic = "ADAPTER_QUEUE_SOLR_S1000";

        try {
            int i = 0;
            int count = 100;
            while (i < count) {
                KeyedMessage<String, String> data = new KeyedMessage<String, String>(topic, message);
                producer.send(data);
                i++;
            }
            System.out.println("生成消息完成!");
        } catch (Exception e) {
            e.printStackTrace();
        }
        producer.close();
    }
}

2、開發一個消費者應用

package com.cattsoft;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import kafka.consumer.ConsumerConfig;
import kafka.consumer.ConsumerIterator;
import kafka.consumer.KafkaStream;
import kafka.javaapi.consumer.ConsumerConnector;

public class KafkaConsumer extends Thread {
    private final ConsumerConnector consumer;
    private final String topic;

    public KafkaConsumer(String topic) {
            consumer =(ConsumerConnector) kafka.consumer.Consumer
                    .createJavaConsumerConnector(createConsumerConfig());   
            this.topic =topic;
        }

    private ConsumerConfig createConsumerConfig() {
        Properties props = new Properties();

        /* 指定zookeeper的連接的字符串 */
        props.put("zookeeper.connect", "130.60.23.193:2181,130.60.23.194:2181,130.60.23.195:2181");
        props.put("group.id", "zk999");
        // 如果true,consumer定期地往zookeeper寫入每個分區的offset
        props.put("auto.commit.enable", "true");
        /* consumer向zookeeper提交offset的頻率,單位是秒 */
        props.put("auto.commit.interval.ms", 60 * 1000);

        /*
         * zookeeper
         * 會話的超時限制。如果consumer在這段時間內沒有向zookeeper發送心跳信息,則它會被認爲掛掉了,並且reblance將會產生
         */
        props.put("zookeeper.session.timeout.ms", "50000");
        /* 客戶端在建立通zookeeper連接中的最大等待時間 */
        props.put("zookeeper.connection.timeout.ms", "20000");
        /* rebalance時的最大嘗試次數 */
        /*
         * 當新的consumer加入到consumer group時,
         * consumers集合試圖重新平衡分配到每個consumer的partitions數目。
         * 如果consumers集合改變了,當分配正在執行時,這個重新平衡會失敗並重入
         */
        props.put("rebalance.max.retries", "5");
        /* 在重試reblance之前backoff時間 */
        props.put("rebalance.backoff.ms", "12000");

        /*
         * zookeeper中沒有初始化的offset時,如果offset是以下值的迴應:
         * smallest:自動復位offset爲smallest的offset largest:自動復位offset爲largest的offset
         * anything else:向consumer拋出異常
         */
        props.put("auto.offset.reset", "largest");

        /* ZK follower可以落後ZK leader的最大時間 */
        props.put("zookeeper.sync.time.ms", "1200");

        /* 這個參數避免在沒有新數據的情況下重複頻繁的拉數據。 如果拉到空數據,則多推後這個時間 */
        props.put("backoff.increment.ms", 1000);
        return new ConsumerConfig(props);
    }

    public void run() {
        Map<String, Integer> topickMap = new HashMap<String, Integer>();
        topickMap.put(topic, 1);
        Map<String, List<KafkaStream<byte[], byte[]>>> streamMap = consumer.createMessageStreams(topickMap);
        KafkaStream<byte[], byte[]> stream = streamMap.get(topic).get(0);
        ConsumerIterator<byte[], byte[]> it = stream.iterator();
        System.out.println("*********Results********");
        int i = 1;
        while (it.hasNext()) {
            System.out.println(
                    Thread.currentThread() + " 接收到的第幾個消息  " + i++ + " ------ " + new String(it.next().message()));
            try {
                Thread.sleep(800);
                this.consumer.commitOffsets();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        KafkaComsuerUtil consumerThread = new KafkaComsuerUtil("ADAPTER_QUEUE_SOLR_S1000");
        consumerThread.start();
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章