SpringMVC整合Kafka实战

7 篇文章 1 订阅

1.SpringMVC整合生产者(Producer)

SpringMVC整合生产者比较简单,我直接用一个单例对象来管理生产者,这样保证生产者也是一个单例对象。

1.1 导入kafka的maven依赖

1.2 创建单例对象管理生产者

我使用静态内部类的方式创建单例对象,保证单例对象的线程安全。直接上代码

public class KafkaManager {

    private static final Logger LOGGER = LoggerFactory.getLogger(KafkaManager.class);

    private static final String BOOTSTRAP_SERVERS = Config.getMqConfig("kafka.bootstrap.servers");


    public static final String TOPIC_LOGIN = "Topic_login";
    public static final String TOPIC_OLD_API = "Topic_api_use";
    public static final String TOPIC_COURSE_VISIT = "Topic_course_visit";

    private boolean kafkaAvailable = true;

    private KafkaProducer<String, String> producer;

    private KafkaManager() {
        this.initManger();
    }
    private static class SingletonManager {
        private static final KafkaManager singletonObj = new KafkaManager();
    }

    public static KafkaManager getInstance() {
        return KafkaManager.SingletonManager.singletonObj;
    }

    private void initManger() {
        try {
            Properties producerProperties = new Properties();
            //设置接入点,请通过控制台获取对应 Topic 的接入点
            producerProperties.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, BOOTSTRAP_SERVERS);
            //消息队列 Kafka 消息的序列化方式
            producerProperties.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
            producerProperties.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG, "org.apache.kafka.common.serialization.StringSerializer");
            //请求的最长等待时间
            producerProperties.put(ProducerConfig.MAX_BLOCK_MS_CONFIG, 30 * 1000);
            this.producer = new KafkaProducer<String, String>(producerProperties);

        } catch (Exception ex) {
            LOGGER.error("创建kafka失败",ex);
            this.kafkaAvailable = false;
        }
    }

    protected void finalize () {
        if (null != this.producer) {
            this.producer.close();
        }
    }

    public boolean sendMessage(String topic, JSONObject body) {
        if (false == this.kafkaAvailable) {
            return false;
        }
        boolean succeed = true;
        try {
            ProducerRecord<String, String>  kafkaMessage =  new ProducerRecord<String, String>(topic, body.toJSONString());

            //发送消息,并获得一个 Future 对象
            Future<RecordMetadata> metadataFuture = this.producer.send(kafkaMessage);
            
        } catch (Exception e) {
            LOGGER.error("发送kafka失败",e);
            succeed = false;
        }
        return succeed;
    }

}

1.3 生产者发送消息

 

2.SpringMVC整合消费者(Consumer)

相对于生产者,SpringMVC整合消费者就显得复杂一点。

2.1 引入kafka消费者的maven依赖

<dependency>
      <groupId>org.apache.kafka</groupId>
      <artifactId>kafka-clients</artifactId>
      <version>0.10.0.0</version>
    </dependency>

    <dependency>
      <groupId>org.springframework.kafka</groupId>
      <artifactId>spring-kafka</artifactId>
      <version>1.1.1.RELEASE</version>
    </dependency>

如上所示,除了kafka客户端的依赖外还需要spring-kafka的依赖。

这里说明一下,我使用Spring配置文件创建bean的方式来管理kafka的消费者。当然还有其他方式,这里我选了比较简单的一种,其他方式可以自行百度一下。

2.2 创建监听类

import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.kafka.listener.MessageListener;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class TopicApiUseKafkaListener implements MessageListener<String, String> {

    private static final Logger LOGGER = LoggerFactory.getLogger(TopicApiUseKafkaListener.class);

    private static final String TABLE_PRE = "";

    @Override
    public void onMessage(ConsumerRecord<String, String> stringStringConsumerRecord) {
        IApiUseService apiUseService = SpringContextUtil.getBean("apiUseService");
        List<ApiUse> dataList = new ArrayList<>();
        String tableName = TABLE_PRE + DateUtil.formatDate(new Date(),"yyyyMM");
        String value = stringStringConsumerRecord.value();
        JSONObject bodyJson = JSONObject.parseObject(value);

        Integer platform = bodyJson.getInteger("platform");
        String url = bodyJson.getString("url");
        String apiVersion = bodyJson.getString("apiVersion");
        String createDate = bodyJson.getString("createDate");

        if (!StringUtils.isEmpty(url) && null != platform && !StringUtils.isEmpty(createDate) && !StringUtils.isEmpty(apiVersion)) {
            ApiUse item = new ApiUse();
            item.setPlatform(platform);
            item.setUrl(url);
            item.setApiVersion(apiVersion);
            item.setCreateDate(createDate);
            dataList.add(item);

        }
        if (dataList.size() > 0) {
            try {
                apiUseService.addApiUse(tableName, dataList);
            } catch (Exception ex1) {
                LOGGER.error("api使用插入错误",ex1);
            }
        }
    }
}

2.3 配置监听类

kafka的监听类的配置需要配置在dispatcher-servlet.xml文件中,配置在spring-context.xml文件中是无效的,这是由Spring的加载机制决定的。

先定义consumer的参数再创建一个全局的consumerFactory的bean对象,如下图所示。这里需要注意enable.auto.commit这个参数,这是kafka自动提交的参数,如果设置成true就有kafka服务端来自动提交,但是由于网络等因素kafka服务端自动提交有时候会失败导致重复消费消息。所以这里设置成false,虽然设置成false但是实际上不需要开发者来手动提交,提交的操作是由Spring-kafka这个sdk类处理的,有兴趣的童鞋可以看一下spring-kafka的源码就知道了。

接下来创建实际执行消费的类,就是我们刚才创建的那个类。

如上图所示,原则上每个topic就要创建一个对应的监听类,然后再配置监听类需要监听的topic。

内容就到这里。更多精彩文章敬请期待。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

现场喷口水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值