SpringKafka——生产者消息发送

生产者消息发送方式

发送既忘方式(异步发送)

不考虑回调,不考虑消息重复,消息漏发,速度最快。常用作收集操作日志、用户浏览痕迹等不重要的信息。

    @Autowired
    @Qualifier("producertemplate")
    private KafkaTemplate<String, String> producertemplate;


public String testKafka(){
 		transactionalTemplate.send("topicname","sendMessage")
        return null;
    }

异步发送 带回调

有回调函数,可以对失败结果或者成功结果进行二次处理。可靠性比发送既忘的方式高,效率比发送既忘方式低(但还是很高,测试过20W条数据眨眼的时间)

    @Autowired
    @Qualifier("producertemplate")
    private KafkaTemplate<String, String> producertemplate;
    public String testKafka(){
  
        producertemplate.send("orderInfo",sendMessage).addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
            @Override
            public void onFailure(Throwable throwable) {
                log.info("msg send fail! exception : "+ throwable.getMessage());  //失败回调
            }
            @Override
            public void onSuccess(SendResult<String, String> stringStringSendResult) {
                log.info("msg send successful! topic : "+stringStringSendResult.getRecordMetadata().topic()+"msg : " +stringStringSendResult.getProducerRecord().value() ); //成功回调
            }
        });

        return null;
    }

同步发送

所谓的同步发送就是阻塞,当发送一条消息后,阻塞该线程,等broker的回调结果,知道broker回调成功后才会继续进行,否则阻塞当前线程。个人觉得没必要使用,异步发送的回调可以解决大部分问题,线程阻塞的方式实在是不怎么友好、

    @Autowired
    @Qualifier("producertemplate")
    private KafkaTemplate<String, String> producertemplate;
    private KafkaTemplate<String, String> transactionalTemplate;
    public String testKafka(){
        try {
            SendResult<String, String> sendResult = producertemplate.send("hello", "message").get();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }

        return null;
    }

事务发送

为什么要使用事务发送呢?

事务发送可以有效的保证消息的不重复,再加上有效的回调手段可以很好的保证消息不丢失也不重复,比如订单类型的信息、支付类型的信息。而且在添加trantional注解的方法上,这个方法如果发生错误,该消息也不会发送,事务除了保证消息的不重复,同样的也复合数据库事务的大部分特性。

所以本次的测试使用事务+异步发送待回调的方式进行测试。

大家可能已经注意 我的注入有两种

    @Autowired
    @Qualifier("producertemplate")
    private KafkaTemplate<String, String> producertemplate;
    @Autowired
    @Qualifier("transactionalTemplate")
    private KafkaTemplate<String, String> transactionalTemplate;

这两种的区别就是一个带事务一个不带事务

使用事务发送把注入对象修改一下 换成id名为transactionalTemplate的实例进行注入即可。

    @Autowired
    @Qualifier("transactionalTemplate")
    private KafkaTemplate<String, String> transactionalTemplate;
    public String testKafka(){
  
        transactionalTemplate.send("orderInfo",sendMessage).addCallback(new ListenableFutureCallback<SendResult<String, String>>() {
            @Override
            public void onFailure(Throwable throwable) {
                log.info("msg send fail! exception : "+ throwable.getMessage());  //失败回调
            }
            @Override
            public void onSuccess(SendResult<String, String> stringStringSendResult) {
                log.info("msg send successful! topic : "+stringStringSendResult.getRecordMetadata().topic()+"msg : " +stringStringSendResult.getProducerRecord().value() ); //成功回调
            }
        });

        return null;
    }

综上所述具体使用哪一种发送方式根据业务场景进行使用,目前我们使用的是事务+异步带回调的方式进行发送,因为业务明细未定以及保证灵活性我们就不编写工具类了

posted @ 2020-03-27 16:02  6。  阅读(579)  评论(1编辑  收藏  举报