maihaoche / rocketmq-spring-boot-starter

Spring Boot starter for RocketMQ
Apache License 2.0
287 stars 147 forks source link

关于这次版本升级,提出的几点问题 #3

Closed ijaychang closed 7 years ago

ijaychang commented 7 years ago

1.AbstractMQPushConsumer的dealMessage方法,感觉还是保留重试次数信息的日志打印比较好呢

  1. 我看到了@MQProducer标注的类的实例会调用registerBean而@MQConsumer标注的类的实例没有调用registerBean。我不是很清楚这个registerBean的用意,因为之前没有用到么,似乎不加这一句也没有影响。。。 // register default mq producer to spring context registerBean(DefaultMQProducer.class.getName(), producer); 3.还有那个问题就是将MessageExt对象转换成Map<String,Object> extMap,我觉得不是很合理。我个人建议还是直接把MessageExt就给使用者暴露出来吧 4.消息的轨迹这个特性挺不错的哈 5.还有我看到加了延迟发消息的特性,不错。不过我记得这个level是可以修改配置的,后续可以改成从namesrv取到配置好的level值,而不是将DELAY_ARRAY写死
ijaychang commented 7 years ago

对于问题3 我有个想法,但是貌似不太行,比如继承自MessageExt然后我再加一个属性,比如叫 T msgBody,用来存放解析byte[] body 好的对象实例。但我现在还不知道,怎么把AbstractMQPushConsumer这里的泛型与T msgBody对应起来。 这样process仅需一个参数了

suclogger commented 7 years ago

@jaychang9

  1. 重试次数可以从extMap中获取,所以这里就去除了日志打印
  2. registerBean是把producer暴露到spring容器中,主要有两个目的,一个是为了更方便在单元测试中校验producer是否以单例构建成功,第二是业务方可以注入这个defaultProducer来直接发送任意topic的消息
  3. 个人觉得MessageExt直接暴露给业务方不是很优雅,map更加直观易于理解,我的看法可能也比较片面,不知道大多数人是怎么想的,可以商榷
  4. Thanks to ONS
  5. 可以改进
ijaychang commented 7 years ago

今天本来想加个AbstractTransactionMQProducer,后来发现要想发事务消息,还比较麻烦 ` protected LocalTransactionExecuter localTransactionExecuter;

protected TransactionCheckListener transactionCheckListener;`

必须得让TransactionMQProducer知道localTransactionExecuter与transactionCheckListener,才能发事务消息,而且transactionCheckListener必须是在调用transactionMQProducer.start()之前要设置好的,不知道@suclogger有没有考虑过这个问题。 所以很难自动生成transactionMQProducer实例

suclogger commented 7 years ago

@jaychang9 目前的rocketmq事务消息的功能还不完整,所以暂不考虑实现。 ROCKETMQ-jira-issue

ijaychang commented 7 years ago

@suclogger 感谢及时回答 OK

ijaychang commented 7 years ago

我试了下,事务消息发送是可以的,也就是说能保证,本地事务与发送消息的一致性。 可能“没有实现broker超时回查producer本地事务的执行状态” 这个没有实现吧,因为这个目前也没法测。 @PostConstruct public void init() throws MQClientException, InterruptedException { transactionMQProducer = new TransactionMQProducer("transProducerGroup"); transactionMQProducer.setNamesrvAddr("127.0.0.1:9876"); transactionMQProducer.setInstanceName("transactionMQProducer"); transactionMQProducer.setTransactionCheckListener(new TransactionCheckListener() { @Override public LocalTransactionState checkLocalTransactionState(MessageExt msg) { String key = msg.getKeys(); if(Integer.parseInt(key) % 2 == 0) { return LocalTransactionState.COMMIT_MESSAGE; }else{ return LocalTransactionState.ROLLBACK_MESSAGE; } } }); transactionMQProducer.start(); // 待生产者启动 Thread.sleep(2000L); }

`@GetMapping("sendTrans") public String sendTransaction() throws MQClientException, InterruptedException {

    Demo demo = new Demo("jaychang","do something...");
    Gson gson = new Gson();
    Message message = new Message("TP_TRANS_DEMO","A", gson.toJson(demo).getBytes());
    message.setKeys(RandomStringUtils.randomAlphanumeric(1));

    transactionMQProducer.sendMessageInTransaction(message, new LocalTransactionExecuter() {
        @Override
        public LocalTransactionState executeLocalTransactionBranch(Message msg, Object arg) {
            int random = RandomUtils.nextInt(0,4);
            System.out.println("executeLocalTransactionBranch random = "+random);
            if( random == 1 || random == 3) {
                return LocalTransactionState.COMMIT_MESSAGE;
            }else{
                return LocalTransactionState.ROLLBACK_MESSAGE;
            }
        }
    },demo);`
suclogger commented 7 years ago

@jaychang9 事务的回查目前是缺失的,而且通过消息来做分布式事务,需要人工介入的场景比较多,所以我个人不是很推荐。有兴趣的话可以看一下这个项目:tx-lcn 上面说到的我个人还是倾向用map,也便于后面继续传递,其他的建议也希望加入一起改善。 这个issue先关闭了。