初识Kafka(0.10.*)

定义:

   卡夫卡一款的英文高储存的分布式发布订阅消息系统- .kafak是什么?

特点:

    1. 高吞吐,低延迟:每秒可以处理几十万条消息,延迟最低只有几毫秒;

 2. 可扩展性:卡夫卡集群支持热扩展;

 3. 持久性,可靠性:消息被持久化到本地磁盘,并支持数据备份防止数据丢失;

 4. 容错性:允许集群中节点失败,若副本数量为N,则允许n-1个个个节点失败;

 5. 高并发:支持数个客户端同时读写;

 卡夫卡优点有哪些?

应用场景:

    1.日志收集:收集各种服务的日志,通过卡夫卡统一接口服务的方式开放给各种消费品;

    2.消息系统:解耦生产者,消费者,缓存消息等;

    3.用户活动跟踪:用来记录网络用户或应用程序用户的各种活动;

    4.运营指标:记录运营监控数据,包含收集各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告;

    5.流处理:结合Spark Streaming和Storm;

    6.时间源;

    卡夫卡用在哪?

架构组件:
    生产者:生产者,生产消息到话题的一方;
    消费者:消费者,订阅话题消费消息的一方;
    经纪人:消息服务器;
    主题:主题,消息存放的目录;
    Consumer Group:kafka采用广播的方式进行消费分发,而消费者集群在消费某个话题时,zookeeper会为该集群建立抵消消费偏移量,最新的消费者加入并消费该主题时,可以从最新的抵消点开始消费;
    分区:kafka采用对数据文件切片(分区)的方式可以讲一个主题分布式存储到多个Broker上,一个topic可以分为多个partition。在多个consumer并发访问一个分区会有同步锁机制;
你好字:

     1.加入Maven的仓库,以0.10.0.0版本为例:

    <! -  1.kafka-jar  - > 
    <依赖性> 
        <的groupId> org.apache.kafka </的groupId> 
        <artifactId的> kafka_2.10 </ artifactId的> 
        <版本> 0.10.0.0 </版本> 
    </依赖性> 
    
    <! -  1.1。依赖于slf4j-log4j12  - > 
    <依赖性> 
        <的groupId> org.slf4j </的groupId> 
        <artifactId的> SLF4J-log4j12 </ artifactId的> 
        <版本> 1.7。 7 </ 
    依赖性> 
    
    <! -  2.依赖kafka客户端 - > 
    <依赖性> 
      <的groupId> org.apache.kafka </的groupId> 
      <artifactId的>卡夫卡的客户端< / artifactId的> 
      <版本> 0.10.2.1 </版本>
    </依赖性>

    2.创建生产者

/ ** 
 * <p>描述:生产者生产者</ p> 
 *版权:Copyright(c)2018 </ p> 
 * <p>日期:2018年5月28日
 *公司:马赛克</ p> 
 * @作者马赛克
 * @version V1.0 
 * / 
公共类制作人{ 
    / ** 
     *日志
     * /
    private static final Logger log = LoggerFactory.getLogger(Producer.class);
    
    / **
     *生产者生产消息到Broker
     *参见
     * <H4>生产者 - >经纪人</ H4>
     * /
    public static void main(String [] args){
        // 1。配置生产者相关属性
        //属性:属性值
        属性props = new Properties();
        //设置代理服务地址:10.8.5.197:9092; 多个代理地址使用 '' 分隔
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG,“10.8.5.198:9092”);
        //设置请求时,验证
        props.put(ProducerConfig.ACKS_CONFIG,“all”);
        //设置请求失败,重试次数
        props.put(ProducerConfig.RETRIES_CONFIG,0);
        //设置内存缓存区大小
        props.put(ProducerConfig.BUFFER_MEMORY_CONFIG,33554432);
        //设置消息按键序列化器
        props.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());
        //设置消息值序列化器
        props.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,BeanSerializer.class.getName());
        //ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,StringSerializer.class.getName());
         
        // 2。创建生产者
        KafkaProducer <String,Object> producer = new KafkaProducer <>(props);
        
        // 3。生产者生产消息到经纪人
        for(int i = 0; i <9; i ++){
            //将键,值序列化为字节数组
            int random =(int)(Math.random()* 10000);
            
            //3.1。生产者生产消息,不关注消息丢失
            //producer.send(ProducerRecord);
            producer.send(new ProducerRecord <String,Object>(“topic-ids”,String.valueOf(random),Constants.getId()));
            
            //producer.send(new ProducerRecord <K,V>(topic,value));
            // new ProducerRecord <K,V>(topic,key,value)
            //新ProducerRecord <K,V>(主题,分区,键值)
            //新ProducerRecord <K,V>(主题,分区,时间戳,键值)
            // topic:消息主题,partition:分区数,timestamp:时间戳,key,value
            
            DeviceBuilder builder = new DeviceBuilder();
            设备设备= builder.setId(随机)
                                   .setMgntIp(“10.36.3。”+(i + 1))
                                   .setDeviceName(“测试”+(i + 1))
                                   .setCiKey(getRandomCi())
                                   .setVendorKey(getRandomVendor())
                                   。建立();
            
            //3.2。生产者生产消息,异常后支持回调,防止消息丢失
            //producer.send (ProducerRecord,Callback);
            producer.send(新ProducerRecord <String,Object>(“topic-devices”,String.valueOf(random),device),new Callback(){
                @覆盖
                public void onCompletion(RecordMetadata metadata,Exception exection){
                    //发送失败时,针对该记录数据的回调方法
                    if(metadata!= null){
                        log.info(“offset:{},partition:{},device:{}”,metadata.offset(),metadata.partition(),device.getMgntIp());  
                    } 
                    if(exection!= null){
                        log.error(“发送失败”,exection);
                    }
                }
            });
            log.info(“发送主题成功!\ n值:{”+ device.getId()+“”+“}”);
        }
        
        // 4。生产者生产消息结束
        producer.close();
    }
    
    private static String getRandomCi(){
        String [] cis = {“路由器”,“交换机”,“防火墙”};
        int random =(int)(Math.random()* 3);
        return cis [random];
    }
    
    私人静态字符串getRandomVendor(){
        String [] vs = {“华为”,“思科”,“迈普”};
        int random =(int)(Math.random()* 3);
        返回vs [随机];
    }
}

      2.1序列化传输对象时,将对象转换成字节组进行传输

 * <p>描述:对象序列化器</ p>
 * <p>版权:Copyright(c)2018 </ p>
 * <p>日期:2018年5月29日</ p>
 * <p>Company: 马赛克</p>
 * @author 马赛克
 * @version V1.0
 */
public class BeanSerializer implements Serializer<Object> {

    /**
     * log
     */
    private static final Logger log = LoggerFactory.getLogger(BeanSerializer.class);
    
    @Override
    public void close() {
        //调用 producer.close()之后,关闭序列化解析器
        log.info("BeanSerializer is Close !");
    }

    @Override
    public void configure(Map<String, ?> map, boolean isKey) {
        
    }

    @Override
    public byte[] serialize(String topic, Object data) {
        log.info("use serialize to Byte !");
        return BeanUtils.converToByte(data);
    }
}

    3.生产消息

 value:{ 7204 }
 value:{ 6560 }
 value:{ 4141 }
 value:{ 7605 }
 value:{ 9816 }
 value:{ 1058 }
 value:{ 258 }
 value:{ 5088 }
 value:{ 3588 }

    4.创建消费者

      
/**
 * <p>Description: 消费者 </p>
 * <p>Copyright: Copyright (c) 2018 </p>
 * <p>Date: 2018年5月29日 </p>
 * <p>Company: 马赛克 </p>
 * @author 马赛克
 * @version V1.0
 */
public class Consumer {
    /**
     * 消费者从broker中取消息
     * @see 
     *   <H4>Broker -->  Consumer</H4>
     */
    public static void main(String[] args) {
        //1.配置消费者相关信息
        //属性:值
        Properties props = new Properties();
        //设置broker服务地址:10.8.5.197:9092
        props.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, "10.8.5.198:9092");
        //设置消费者组Id group.id
        props.put(KafkaProperties.GROUP_ID, "group-tk");
        //设置启动自动提交  enable.auto.commit
        props.put(KafkaProperties.ENABLE_AUTO_COMMIT, true);
        //设置自动提交间隔  auto.commit.interval.ms
        props.put(KafkaProperties.AUTO_COMMIT_INTERVAL_MS, 1000);
        //设置会话有效时间  session.timeout.ms
        props.put(KafkaProperties.SESSION_TIMEOUT_MS, 10000);
        //设置消息key反序列化器  key.deserializer
        props.put(KafkaProperties.KEY_DESERIALIZER, StringDeserializer.class.getName());
        //设置消息value反序列化器  value.deserializer : 
        props.put(KafkaProperties.VALUE_DESERIALIZER, BeanDeserializer.class.getName());
        
        //2.创建消费者
        @SuppressWarnings("resource")
        KafkaConsumer<String, Object> consumer = new KafkaConsumer<String, Object>(props);
        
        //3.订阅消息
        //3.1.要想broker中订阅要消费的消息
        //3.1.1.确定需要订阅的主题: topics
        Collection<String> topics = new HashSet<String>();
        topics.add("topic-device");
        topics.add("topic-ids");
        
        //3.1.2.订阅主题
        consumer.subscribe(topics);
        
        //topic
        Set<String> scripts = consumer.subscription();
        scripts.stream().forEach(script -> {
            System.out.println("consumer scription : "+ script);
        });
        
        //4.接收消息
        do{
            //每0.1秒消费一次消息
            ConsumerRecords<String, Object> records = consumer.poll(1);
            for (ConsumerRecord<String, Object> record : records) {
                System.out.println("offset: "+record.offset() + ", partition: " + record.partition() + ", topic:" + record.topic() + ", record-key:" + record.key() + ", record-value:"+ record.value().toString());
            }
        }while(true);   
    }
}

     4.1.反序列化对象时,将字节组转换成对象

/**
 * <p>Description: 对象反序列化器 </p>
 * <p>Copyright: Copyright (c) 2018 </p>
 * <p>Date: 2018年5月29日 </p>
 * <p>Company: 马赛克</p>
 * @author 马赛克
 * @version V1.0
 */
public class BeanDeserializer implements Deserializer<Object> {
    /**
     * log
     */
    private static final Logger log = LoggerFactory.getLogger(BeanDeserializer.class);
    
    @Override
    public void close() {
        log.info("BeanDeserializer is Close !");
    }

    @Override
    public void configure(Map<String, ?> map, boolean isKey) {
        
    }

    @Override
    public Object deserialize(String topic, byte[] bytes) {
        log.info("user deserialize to Object !");
        return BeanUtils.converToObj(bytes);
    }

}

    5.对象转换工具类

/**
 * <p>Description: BeanUtils </p>
 * <p>Copyright: Copyright (c) 2018 </p>
 * <p>Date: 2018年5月29日 </p>
 * <p>Company: 马赛克</p>
 * @author 马赛克
 * @version V1.0
 */
public class BeanUtils {
    //防止实例化
    private BeanUtils(){ }
    
    /**
     * 将对象转换成字节组
     * @param obj 对象
     * @return byte[]
     */
    public static byte[] converToByte(Object obj){
        byte[] bytes = null;
        try {
            //字节输出流
            ByteArrayOutputStream byteOutStream = new ByteArrayOutputStream();
            //对象输出流
            ObjectOutputStream objOutStream = new ObjectOutputStream(byteOutStream);
            //写入对象
            objOutStream.writeObject(obj);
            objOutStream.flush();
            bytes = byteOutStream.toByteArray();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return bytes;
    }
    
    /**
     * 将字节码转换成对象
     * @param bytes 字节码
     * @return Object
     */
    public static Object converToObj(byte[] bytes){
        Object obj = null;
        try {
            //字节输入流
            ByteArrayInputStream byteInStream = new ByteArrayInputStream(bytes);
            //对象输入流
            ObjectInputStream objOutStream = new ObjectInputStream(byteInStream);
            //写入对象
            obj = objOutStream.readObject();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return obj;
    }
}

    6.消费消息,这里就不详细打印了

offset: 21, partition: 2, topic:topic-ids, record-key:7204, record-value:fde76c824d7347238ded1fe07b92fdd8
offset: 22, partition: 2, topic:topic-ids, record-key:6560, record-value:3af21949ceb74960acab9d634fdf8bb7
offset: 23, partition: 2, topic:topic-ids, record-key:258, record-value:ea3fa441692640fdad49617a27da4548
offset: 24, partition: 2, topic:topic-ids, record-key:5088, record-value:7b2db6774fc04228bf36f5b6ee8d8f6c
offset: 25, partition: 1, topic:topic-ids, record-key:9816, record-value:586747a189654c60a8f0c7db2197e064
主题:topic-id,record-key:4141,记录值: 
26,partition:1,topic:topic-ids,record-key:1058,record-value:a5fd8aee84434b7fad7039f67d98b8f3偏移量:26,分区:0, e5a4473a8a3649949c3134108b598bc6 
偏移量:27,分区:0,主题:主题的IDS,记录键:7605,记录值:57a83d5d309244769748ca94d7628818 
偏移量:28,分区:0,主题:主题-ID,记录键值:3588,记录值:e6c05210578b4c75b1d63301241073bd




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值