在springboot项目中应用kafka生产 、消费消息

4 篇文章 0 订阅
3 篇文章 0 订阅

1、准备工作

工欲善其事必先利其器,首先安装kafka,我们这里使用docker容器进行安装,这里可参考之前的一篇博文docker快速部署pg/redis/kafka/es等中间件

说明:文中提到的所有代码都在我的github项目里面,项目地址https://github.com/chenxiangweifeng/study

搭建好kafka服务端之后。首先在pom文件中引入kafka的依赖:

	<dependency>
			<groupId>org.springframework.kafka</groupId>
			<artifactId>spring-kafka</artifactId>
			<version>2.2.12.RELEASE</version>
		</dependency>
		<dependency>
			<groupId>org.apache.kafka</groupId>
			<artifactId>kafka-clients</artifactId>
			<version>2.2.0</version>
		</dependency>

springboot的配置文件中配置上kafka的连接地址以及生产者和消费者序列化方式如下:

kafka:
    bootstrap-servers:  192.168.28.200:9092
    consumer:
      group-id: group_study
      auto-offset-reset: earliest
      key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
      value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
    producer:
      key-serializer: org.apache.kafka.common.serialization.StringSerializer
      value-serializer: org.springframework.kafka.support.serializer.JsonSerializer
      acks: all
      retries: 3

2、消息发送

我们使用kafkaTemplate发送消息,

    @ApiOperation(value = "向kafka中发送简单字符串信息")
    @RequestMapping(value = "/testSendSimpleMessage", method = RequestMethod.POST)
    public String testSendSimpleMessage(@RequestParam("msg") String msg) {
        KafkaTemplate.send(KafkaTopicEnum.SIMPLE_MSG.code,msg);
        return "发送消息成功";
    }

本项目引入了swagger,可以方便的直接进行接口测试:

通过kafka Tools工具我们可以查询到该topic内的消息,证明消息发送成功。

除了发送这种简单的消息之外,我们还可以向kafka中发送Java中的一个对象构成的消息:如下:

  @ApiOperation(value = "向kafka中发送一个对象消息")
    @RequestMapping(value = "/testSendMessage", method = RequestMethod.POST)
    public String testSendMessage(@RequestParam("personType") Integer personType) {
        Person p = new Person();
        p.setUserName("赵敏");
        p.setPersonType(personType);
        p.setPhoneNum("18018576105");
        // 向特定的topic发送消息
        KafkaTemplate.send(KafkaTopicEnum.TEST_PERSON_MESSAGE.code,p);
        return "发送一个对象消息成功";
    }

通过swagger向该topic内发送一个对象消息:

通过kafka Tool查看到该消息是通过我们设置的json序列化方式,序列化为一个json字符串

3、消息接收

消费者消费消息是通过监听特定的topic来消费消息

    @KafkaListener(topics = "simple-msg",containerFactory = "ackContainerFactory")
    public void receiveSimpleKafkaMsg(ConsumerRecord<?,?> consumerRecord, Acknowledgment acknowledgment){
        System.out.println("监听服务接收到的简单字符串消息是======"+consumerRecord.value().toString());
        System.out.println("=================== end =================");
        acknowledgment.acknowledge();
    }
result: 

监听服务接收到的简单字符串消息是======"hello"
=================== end =================
监听服务接收到的简单字符串消息是======"world"
=================== end =================
监听服务接收到的简单字符串消息是======"kafka"
=================== end =================

当有两个业务想同时消费这一批消息的时候,注意需使用广播模式,设置多个group,通过不同的groupId进行区分,比如我们这里通过两个消费组同时消费对象消息:可以发现,该消息被两个组的消费者各消费一次,达到了广播的效果。

@KafkaListener(topics = "test-person-message",groupId ="serverGroup1",containerFactory = "ackContainerFactory")
    public void receiveKafkaMsg1(ConsumerRecord<?,?> consumerRecord, Acknowledgment acknowledgment){
        System.out.println("监听服务接收到的消息是:111111111111111111111111");
        Person person = JSON.parseObject(consumerRecord.value().toString(), Person.class);
        System.out.println(consumerRecord.value().toString());
        System.out.println("接收到的person是:"+person);
        System.out.println("人员类型是:"+person.getPersonType()+"人员姓名是:"+person.getUserName());
        System.out.println("=================== end =================");
    }

 @KafkaListener(topics = "test-person-message",groupId ="serverGroup2",containerFactory = "ackContainerFactory" )
    public void receiveKafkaMsg2(ConsumerRecord<?,?> consumerRecord, Acknowledgment acknowledgment){
        System.out.println("监听服务接收到的消息是:22222222222222222222222");
        Person person = JSON.parseObject(consumerRecord.value().toString(), Person.class);
        System.out.println("接收到的person是:"+person);
        System.out.println("人员类型是:"+person.getPersonType()+"人员姓名是:"+person.getUserName());
        System.out.println("=================== end =================");
        /**
         * ack 提交掉 监听服务222 已经被ack提交掉,历史消息不会被再次消费
         */
        acknowledgment.acknowledge();
    }

result:
监听服务接收到的消息是:111111111111111111111111
{"id":null,"userName":"赵敏","phoneNum":"18018576105","age":null,"createTime":null,"finish":null,"addr":null,"height":null,"introduction":null,"personType":22}
接收到的person是:Person(id=null, userName=赵敏, phoneNum=18018576105, age=null, createTime=null, finish=null, addr=null, height=null, introduction=null, personType=22)
人员类型是:22人员姓名是:赵敏
=================== end =================
监听服务接收到的消息是:22222222222222222222222
接收到的person是:Person(id=null, userName=赵敏, phoneNum=18018576105, age=null, createTime=null, finish=null, addr=null, height=null, introduction=null, personType=22)
人员类型是:22人员姓名是:赵敏
=================== end =================

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值