kafka发送与接收数据(含奇葩报错解决方案)

首先说明一下,小白在学习这一块的时候,记得导入包的时候要看清包名,网上有一些博客没有具体导入的包名称,可能会导致在本机上导包后出现各种各样奇葩的强制类型转化.

kafka的相关内容与概念在这里就不再赘述了,咱们直接通过一个小案例来感受一下kafka的魅力,

本篇博客分为五个部分:

  1. 配置情况;
  2. 在搭建好的linux服务器上创建一个topic;
  3. 作为producer(生产者),给kafka上新创建的topic发送一条信息;
  4. 奇葩报错的解决方案
  5. 作为consumer(消费者),接收kafka的topic上的消息;

一:配置情况:

1.在这里我使用四台虚拟机:

>>win8.1的虚拟机作为编程的场所 (在虚拟机上可以随便折腾)

>>三台linux系列的centos虚拟机,ip地址分别是:192.168.0.207,192.168.0.204,192.168.0.171

2.zookeeper端口使用默认端口:2181

3.kafka端口使用默认端口:9092

4.将虚拟机设置为桥接模式(否则得不到三个不同的ip)

5.一个热爱技术的心


二:在搭建好的linux服务器上创建一个topic:

1.首先需要使用三台linux虚拟机安装zookeeper和kafka的集群,在这里推荐一篇我个人认为不错的博文,大家可以参考一下,同时感谢博主的付出:http://www.cnblogs.com/luotianshuai/p/5206662.html

2.由于没有zookeeper的支持,不可以新增topic,因此确保自己的三台linux服务器运行./zkServer.sh statusjps 后,可以出现下图的内容



3.选取任意一台服务器(这里我选用的是ip为192.168.0.204的服务器),来创建topic:

  • cd 到目标位置 ----kafka/kafka_2.11-0.11.0.0/bin
  • 运行命令: ./kafka-topics.sh --create --zookeeper192.168.0.204:2181--replication-factor 2 --partitions 1 --topic mytopic ,这里的ip地址改为你的ip地址,可以在linux服务器上运行ifconfig 命令(windows上是 ipconfig ),最后的那个 "mytopic"是自定义的topic名称,可以更换,但是要记住这个topic名称,一会要用到
  • 没有任何提醒的话,就说明成功了,现在使用命令来检查一下  ./kafka-topics.sh --describe --zookeeper localhost:2181 --topic mytopic ,如果出现下面的图片内容,就证明成功了:

这里的序号表示集群中主机的id,比如 Leader:2 就表示这个这个topic的leader是id = 2 的那台主机.之前在配置时配置过,所以这个序号不同也是正常的

三:作为producer(生产者),给kafka的一个topic发送信息:

准备工作就绪了,要开始打码了,首先配置maven的pom.xml文件:



    4.0.0

    kafka
    kafka
    1.0-SNAPSHOT

	
    
        
            org.apache.kafka
            kafka_2.10
            0.8.2.2
        
    


然后写一个生产者:目的是发送"Hhhhh!I am coming"的字符串

import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;
//注意导包
import java.util.Properties;

public class MyProducer {
    private static Producer producer;
    private final Properties props = new Properties();

    public MyProducer() {
        //连接broker list,这里因为要使用kafka,因此端口是kafka的默认端口9092
        props.put("metadata.broker.list", "192.168.0.204:9092");
        //在网络传输前都要进行的序列化操作
        props.put("serializer.class", "kafka.serializer.StringEncoder");
        producer = new Producer(new ProducerConfig(props));
    }

    public static void main(String[] args) {
        MyProducer sp = new MyProducer();
        //设置topic,注意要与之前创建的topic名称保持一致
        String topic = "mytopic";
        //设置的消息内容
        String messageStr = "Hhhhh! I am coming";
        //构建消息对象
        KeyedMessage data = new KeyedMessage(topic, messageStr);
        //推送消息到broker
        producer.send(data);
        producer.close();
    }
}

注意这里导包要正确,否则随时有一大堆强制类型转化的提示!

写到这里,如果运行后出现下面的图,那么恭喜恭喜,你可以直接跳过第四部分,学习消费者的代码书写:

kafka发送与接收数据(含奇葩报错解决方案)_第1张图片

生产者因为要发送数据,发送结束就结束了,因此只会有warn,并且会结束程序.

如果有各种奇葩报错,不用担心,请看第四部分,因为我是新装的虚拟机,因此一般来说如果之前没有设置过,可能会有下面的情况.


四:奇葩报错的解决方案

如果你问我,初学者该怎么学习一种新技术,我不会告诉你应该多看书有耐心,而是先把虚拟机的防火墙关了!

比如这个报错:

kafka发送与接收数据(含奇葩报错解决方案)_第2张图片

如果linux服务器在配置的时候没有打开防火墙端口的记忆,那么直接运行这条命令:

>>>su

>>>然后输入你的管理员密码

>>>systemctl stop firewalld.service #停止firewall

>>>systemctl disable firewalld.service #禁止firewall开机启动 (为了安全考虑,这条可以不用)

kafka发送与接收数据(含奇葩报错解决方案)_第3张图片

更多sentos 防火墙指令,请参考博客:http://blog.csdn.net/weixin_35757704/article/details/76016355

(SentOS 7防火墙配置与端口增删改查的命令)

同样在Windows上,也要把防火墙关闭,然后就可以了


五:作为consumer(消费者),接收kafka的topic上的消息

愉快的写一个消费者:

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

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

public class MyConsumer {
    private final ConsumerConnector consumer;
    private final String topic;

    public MyConsumer(String zookeeper, String groupId, String topic) {
        Properties props = new Properties();
        props.put("zookeeper.connect", zookeeper);
        props.put("group.id", groupId);
        //配置一些参数
        props.put("zookeeper.session.timeout.ms", "500");
        props.put("zookeeper.sync.time.ms", "250");
        props.put("auto.commit.interval.ms", "1000");
        consumer = Consumer.createJavaConsumerConnector(new ConsumerConfig(props));
        this.topic = topic;
    }

    public void testConsumer() {
        Map topicCount = new HashMap();
        //定义订阅topic的数量
        topicCount.put("mytopic", new Integer(1));
        //返回topic的map,这里如果无法理解,可以在这里设置断点,观察真正传回的数据格式
        Map>> consumerStreams = consumer.createMessageStreams(topicCount);
        //取出我们需要的topic的消息流
        List> streams = consumerStreams.get(topic);
        for (final KafkaStream stream : streams) {
            ConsumerIterator consumerIte = stream.iterator();
            while (consumerIte.hasNext())
                System.out.println("Message from single topic :: " + new String(consumerIte.next().message()));
        }
        if (consumer != null) {
            consumer.shutdown();
        }
    }

    public static void main(String[] args) {
        String topic = "mytopic";
        MyConsumer myConsumer = new MyConsumer("192.168.0.204:2181", "testgroup", topic);
        myConsumer.testConsumer();
    }
}
然后就可以测试了,首先运行消费者程序MyConsumer,会出现循环,因为kafka本身就是一个死循环,然后运行生产者程序MyProducer,注意观察MyConsumer的控制台打印的内容,如果是下图内容,就证明成功了:

kafka发送与接收数据(含奇葩报错解决方案)_第4张图片

如果出现空指针异常的报错,可能是topic的单词打错了,比如下图所示:

kafka发送与接收数据(含奇葩报错解决方案)_第5张图片

当时我就是一个字母打错了,把'o'打成了'i',大家引以为戒吧.


然后可以根据这个小demo,感受一下kafka的运行过程.同时推荐尝试的读一下kafka的源码,我也在努力的在学习kafka框架,希望能够学到许多关于框架的知识,并且分享出去,同时加强对kafka的理解.

欢迎入坑哟...emoji..

你可能感兴趣的:(大数据,网络)