1.需要启动的服务

  这里启动的端口是9092。

    bin/kafka-console-consumer.sh --topic beifeng --zookeeper linux-hadoop01.ibeifeng.com:2181/kafka

  

2.producer的程序

 package com.jun.it;
import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
public class JavaKafkaProducer {
public static final char[] chars = "qazwsxedcrfvtgbyhnujmikolp0123456789".toCharArray();
public static final int charsLength = chars.length;
public static final Random random = new Random(System.currentTimeMillis());
private Producer<String, String> producer = null; private String topicName = null;
private String brokerList = null;
private boolean isSync = true; // 默认为同步 /**
* 构造函数
*
* @param topicName
* @param brokerList
*/
public JavaKafkaProducer(String topicName, String brokerList) {
this(topicName, brokerList, true);
} /**
* 构造函数,主要是产生producer
*
* @param topicName
* @param brokerList
* @param isSync
*/
public JavaKafkaProducer(String topicName, String brokerList, boolean isSync) {
// 赋值
this.topicName = topicName;
this.brokerList = brokerList;
this.isSync = isSync; // 1. 给定配置信息:参考http://kafka.apache.org/082/documentation.html#producerconfigs
Properties props = new Properties();
// kafka集群的连接信息
props.put("metadata.broker.list", this.brokerList);
// kafka发送数据方式
if (this.isSync) {
// 同步发送数据
props.put("producer.type", "sync");
} else {
// 异步发送数据
props.put("producer.type", "async");
/**
* 0: 不等待broker的返回
* 1: 表示至少等待1个broker返回结果
* -1:表示等待所有broker返回数据接收成功的结果
*/
props.put("request.required.acks", "0");
}
// key/value数据序列化的类
/**
* 默认是:DefaultEncoder, 指发送的数据类型是byte类型
* 如果发送数据是string类型,必须更改StringEncoder
*/
props.put("serializer.class", "kafka.serializer.StringEncoder"); // 2. 构建Kafka的Producer Configuration上下文
ProducerConfig config = new ProducerConfig(props); // 3. 构建Kafka的生产者:Producerr
this.producer = new Producer<String, String>(config);
} /**
* 关闭producer连接
*/
public void closeProducer() {
producer.close();
} /**
* 提供给外部应用调用的直接运行发送数据代码的方法
*
* @param threadNumbers
* @param isRunning
*/
public void run(int threadNumbers, final AtomicBoolean isRunning) {
for (int i = 0; i < threadNumbers; i++) {
new Thread(new Runnable() {
public void run() {
int count = 0;
while (isRunning.get()) {
// 只有在运行状态的情况下,才发送数据
KeyedMessage<String, String> message = generateMessage();
// 发送数据
producer.send(message);
count++;
// 打印一下
if (count % 100 == 0) {
System.out.println("Count = " + count + "; message:" + message);
} // 假设需要休息一下
try {
Thread.sleep(random.nextInt(100) + 10);
} catch (InterruptedException e) {
// nothings
}
}
System.out.println("Thread:" + Thread.currentThread().getName() + " send message count is:" + count);
}
}).start();
}
} /**
* 产生一个随机的Kafka的KeyedMessage对象
*
* @return
*/
public KeyedMessage<String, String> generateMessage() {
String key = generateString(3) + "_" + random.nextInt(10);
StringBuilder sb = new StringBuilder();
int numWords = random.nextInt(5) + 1; // [1,5]单词
for (int i = 0; i < numWords; i++) {
String word = generateString(random.nextInt(5) + 1); // 单词中字符最少1个最多5个
sb.append(word).append(" ");
}
String message = sb.toString().trim();
return new KeyedMessage(this.topicName, key, message);
} /**
* 随机生产一个给定长度的字符串
*
* @param numItems
* @return
*/
public static String generateString(int numItems) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < numItems; i++) {
sb.append(chars[random.nextInt(charsLength)]);
}
return sb.toString();
}
}

3.测试类

 package com.jun.it;

 import java.util.concurrent.atomic.AtomicBoolean;

 public class JavaKafkaProducerTest {
public static void main(String[] args) {
String topicName = "beifeng";
String brokerList = "linux-hadoop01.ibeifeng.com:9092,linux-hadoop01.ibeifeng.com:9093";
int threadNums = 10;
AtomicBoolean isRunning = new AtomicBoolean(true);
JavaKafkaProducer producer = new JavaKafkaProducer(topicName, brokerList);
producer.run(threadNums, isRunning); // 停留60秒后,进行关闭操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// nothings
}
isRunning.set(false); // 关闭连接
producer.closeProducer();
}
}

4.效果

  

二:使用自定义的分区器

1.分区器

 package com.jun.it;

 import kafka.producer.Partitioner;
import kafka.utils.VerifiableProperties; public class JavaKafkaPartitioner implements Partitioner {
/**
* 默认无参构造函数
*/
public JavaKafkaPartitioner() {
this(new VerifiableProperties());
} /**
* 该构造函数必须给定
*
* @param properties 初始化producer的时候给定的配置信息
*/
public JavaKafkaPartitioner(VerifiableProperties properties) {
// nothings
} @Override
public int partition(Object key, int numPartitions) {
String tmp = (String) key;
int index = tmp.lastIndexOf('_');
int number = Integer.valueOf(tmp.substring(index + 1));
return number % numPartitions;
}
}

2.producer类重新修改

 package com.jun.it;
import kafka.javaapi.producer.Producer;
import kafka.producer.KeyedMessage;
import kafka.producer.ProducerConfig;
import java.util.Properties;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
public class JavaKafkaProducer {
public static final char[] chars = "qazwsxedcrfvtgbyhnujmikolp0123456789".toCharArray();
public static final int charsLength = chars.length;
public static final Random random = new Random(System.currentTimeMillis());
private Producer<String, String> producer = null; private String topicName = null;
private String brokerList = null;
private boolean isSync = true; // 默认为同步
private String partitionerClass = null; // 数据分区器class类 /**
* 构造函数
*
* @param topicName
* @param brokerList
*/
public JavaKafkaProducer(String topicName, String brokerList) {
this(topicName, brokerList, true, null);
} /**
* 构造函数
*
* @param topicName
* @param brokerList
* @param partitionerClass
*/
public JavaKafkaProducer(String topicName, String brokerList, String partitionerClass) {
this(topicName, brokerList, true, partitionerClass);
} /**
* 构造函数,主要是产生producer
*
* @param topicName
* @param brokerList
* @param isSync
*/
public JavaKafkaProducer(String topicName, String brokerList, boolean isSync, String partitionerClass) {
// 赋值
this.topicName = topicName;
this.brokerList = brokerList;
this.isSync = isSync;
this.partitionerClass = partitionerClass; // 1. 给定配置信息:参考http://kafka.apache.org/082/documentation.html#producerconfigs
Properties props = new Properties();
// kafka集群的连接信息
props.put("metadata.broker.list", this.brokerList);
// kafka发送数据方式
if (this.isSync) {
// 同步发送数据
props.put("producer.type", "sync");
} else {
// 异步发送数据
props.put("producer.type", "async");
/**
* 0: 不等待broker的返回
* 1: 表示至少等待1个broker返回结果
* -1:表示等待所有broker返回数据接收成功的结果
*/
props.put("request.required.acks", "0");
}
// key/value数据序列化的类
/**
* 默认是:DefaultEncoder, 指发送的数据类型是byte类型
* 如果发送数据是string类型,必须更改StringEncoder
*/
props.put("serializer.class", "kafka.serializer.StringEncoder"); // 给定分区器的class参数
if (this.partitionerClass != null && !this.partitionerClass.trim().isEmpty()) {
// 默认是:DefaultPartiioner,基于key的hashCode进行hash后进行分区
props.put("partitioner.class", this.partitionerClass.trim());
} // 2. 构建Kafka的Producer Configuration上下文
ProducerConfig config = new ProducerConfig(props); // 3. 构建Kafka的生产者:Producerr
this.producer = new Producer<String, String>(config);
} /**
* 关闭producer连接
*/
public void closeProducer() {
producer.close();
} /**
* 提供给外部应用调用的直接运行发送数据代码的方法
*
* @param threadNumbers
* @param isRunning
*/
public void run(int threadNumbers, final AtomicBoolean isRunning) {
for (int i = 0; i < threadNumbers; i++) {
new Thread(new Runnable() {
public void run() {
int count = 0;
while (isRunning.get()) {
// 只有在运行状态的情况下,才发送数据
KeyedMessage<String, String> message = generateMessage();
// 发送数据
producer.send(message);
count++;
// 打印一下
if (count % 100 == 0) {
System.out.println("Count = " + count + "; message:" + message);
} // 假设需要休息一下
try {
Thread.sleep(random.nextInt(100) + 10);
} catch (InterruptedException e) {
// nothings
}
}
System.out.println("Thread:" + Thread.currentThread().getName() + " send message count is:" + count);
}
}).start();
}
} /**
* 产生一个随机的Kafka的KeyedMessage对象
*
* @return
*/
public KeyedMessage<String, String> generateMessage() {
String key = generateString(3) + "_" + random.nextInt(10);
StringBuilder sb = new StringBuilder();
int numWords = random.nextInt(5) + 1; // [1,5]单词
for (int i = 0; i < numWords; i++) {
String word = generateString(random.nextInt(5) + 1); // 单词中字符最少1个最多5个
sb.append(word).append(" ");
}
String message = sb.toString().trim();
return new KeyedMessage(this.topicName, key, message);
} /**
* 随机生产一个给定长度的字符串
*
* @param numItems
* @return
*/
public static String generateString(int numItems) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < numItems; i++) {
sb.append(chars[random.nextInt(charsLength)]);
}
return sb.toString();
}
}

3.测试类

 package com.jun.it;

 import java.util.concurrent.atomic.AtomicBoolean;

 public class JavaKafkaProducerTest {
public static void main(String[] args) {
String topicName = "beifeng";
String brokerList = "linux-hadoop01.ibeifeng.com:9092,linux-hadoop01.ibeifeng.com:9093";
String partitionerClass = "com.jun.it.JavaKafkaPartitioner";
int threadNums = 10;
AtomicBoolean isRunning = new AtomicBoolean(true);
JavaKafkaProducer producer = new JavaKafkaProducer(topicName, brokerList,partitionerClass);
producer.run(threadNums, isRunning); // 停留60秒后,进行关闭操作
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// nothings
}
isRunning.set(false); // 关闭连接
producer.closeProducer();
}
}

4.效果

  

057 Java中kafka的Producer程序实现的更多相关文章

  1. java中子类继承父类程序执行顺序

    java中子类继承父类程序执行顺序 FatherTest.java public class FatherTest { private String name; public FatherTest() ...

  2. java中子类继承父类程序执行顺序问题

    Java中,new一个类的对象,类里面的静态代码块.非静态代码.无参构造方法.有参构造方法.类的一般方法等部分,它们的执行顺序相对来说比较简单,用程序也很容易验证.比如新建一个测试父类. public ...

  3. 对上次“对字符串进行简单的字符数字统计 探索java中的List功能 ”程序,面向对象的改进

    之前的随笔中的程序在思考后发现,运用了太多的static 函数,没有将面向对象的思想融入,于是做出了一下修改: import java.util.ArrayList; import java.util ...

  4. Java 中,编写多线程程序的时候你会遵循哪些最佳实践?

    这是我在写 Java 并发程序的时候遵循的一些最佳实践: a)给线程命名,这样可以帮助调试. b)最小化同步的范围,而不是将整个方法同步,只对关键部分做同步. c)如果可以,更偏向于使用 volati ...

  5. JAVA中处理事务的程序--多条更新SQL语句的执行(包括回滚)

    在与数据库操作时,如果执行多条更新的SQL语句(如:update或insert语句),在执行第一条后如果出现异常或电脑断电, 则后面的SQL语句执行不了,这时候设定我们自己提交SQL语句,不让JDBC ...

  6. Java中native关键字

    Java中native关键字 标签: Java 2016-08-17 11:44 54551人阅读 评论(0) 顶(23453) 收藏(33546)   今日在hibernate源代码中遇到了nati ...

  7. Java中long类型直接赋值大数字 注意事项

    在java中,我们都知道有八种基本数据类型:byte. char. short .int. long. float. double .boolean 下面列出以下四种数据类型及其取值范围: 本文主要讲 ...

  8. Java中native的用法

    原文来自:http://blog.csdn.net/funneies/article/details/8949660 native关键字说明其修饰的方法是一个原生态方法,方法对应的实现不是在当前文件, ...

  9. 关于JAVA中的static方法、并发问题以及JAVA运行时内存模型

    一.前言 最近在工作上用到了一个静态方法,跟同事交流的时候,被一个问题给问倒了,只怪基础不扎实... 问题大致是这样的,“在多线程环境下,静态方法中的局部变量会不会被其它线程给污染掉?”: 我当时的想 ...

随机推荐

  1. 关于Dubbo和Spring异步注解@Async的冲突

    项目中难免会有异步处理的需求,像异步记录日志啦,异步发送邮件啦,而Dubbo又是现在主流的分布式框架,所有异步+Dubbo的组合是再所难免的 但博主是实践中发现Dubbo的服务并不能很好的跟Sprin ...

  2. 搭建activemq服务

    文章链接:https://www.cnblogs.com/xiaxinggege/p/5900319.html ubuntu下安装JDK并搭建activeMQ   1.安装JDK,网上有人说activ ...

  3. Django 2.x 常用命令

    从Pycharm换成VsCode,好多命令都不会,这里记一下. 创建 Django 项目 先进入到你想要创建 project 目录下,执行命令 django-admin startproject pr ...

  4. 4)django-视图view

    视图是django功能函数,结合url使用 1.视图方式 视图方式经常用的有两种 用户GET获取数据      用户POST提交数据            用户第一次访问页面是GET       用户 ...

  5. 手机CPU架构体系分类及各大厂商

    手机cpu相关知识,这对于开发Android应用程序适应各个机型有一定的辅助作用 . 手机cpu架构体系分类 指令集可分为复杂指令集(CISC)和精简指令集(RISC)两部分,代表架构分别是x86.A ...

  6. 解决Navicat连接MySQL总是报错1251的方法

    今天下了个 MySQL8.0,发现Navicat连接不上,总是报错1251: 原因是MySQL8.0版本的加密方式和MySQL5.0的不一样,连接会报错. 试了很多种方法,终于找到一种可以实现的: 更 ...

  7. 银联支付Java开发

    注:原来来源于: <  银联支付Java开发  > 银联的demo写的不错,基本上可以直接使用. 首先是对acp_sdk.properties的内容修改,注意这个文件的文件名不能进行修改. ...

  8. 关于《common-net》的ftp上传

    1:jar的maven的引用: <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http ...

  9. 为 Confluence 6 配置发送邮件消息

    如何配置 Confluence 向外发送邮件: 进入  > 基本配置(General Configuration) > 邮件服务器(Mail Servers).这里列出了所有当前配置的 S ...

  10. nodejs之koa-router与koa-body搭配使用

    简介 koa需要搭配中间件来做接口更方便,使用Koa-body & Koa-router 使用 koa2 创建接口,处理post请求 const koa=require("koa&q ...