rocketmq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jinrongt...@apache.org
Subject [rocketmq-spring.wiki] branch master updated: Created 常见问题 (markdown)
Date Wed, 25 Dec 2019 07:15:23 GMT
This is an automated email from the ASF dual-hosted git repository.

jinrongtong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/rocketmq-spring.wiki.git


The following commit(s) were added to refs/heads/master by this push:
     new 8a5fa83  Created 常见问题 (markdown)
8a5fa83 is described below

commit 8a5fa835129724a72edd4cf3075058b5a0e8f162
Author: rongtong <jinrongtong5@163.com>
AuthorDate: Wed Dec 25 15:15:20 2019 +0800

    Created 常见问题 (markdown)
---
 ...270\270\350\247\201\351\227\256\351\242\230.md" | 141 +++++++++++++++++++++
 1 file changed, 141 insertions(+)

diff --git "a/\345\270\270\350\247\201\351\227\256\351\242\230.md" "b/\345\270\270\350\247\201\351\227\256\351\242\230.md"
new file mode 100644
index 0000000..b483f23
--- /dev/null
+++ "b/\345\270\270\350\247\201\351\227\256\351\242\230.md"
@@ -0,0 +1,141 @@
+1. 生产环境有多个`nameserver`该如何连接?
+
+   `rocketmq.name-server`支持配置多个`nameserver`地址,采用`;`分隔即可。例如:`172.19.0.1:9876;172.19.0.2:9876`
+
+1. `rocketMQTemplate`在什么时候被销毁?
+
+    开发者在项目中使用`rocketMQTemplate`发送消息时,不需要手动执行`rocketMQTemplate.destroy()`方法,
`rocketMQTemplate`会在spring容器销毁时自动销毁。
+
+1. 启动报错:`Caused by: org.apache.rocketmq.client.exception.MQClientException: The
consumer group[xxx] has been created before, specify another name please`
+
+    RocketMQ在设计时就不希望一个消费者同时处理多个类型的消息,因此同一个`consumerGroup`下的consumer职责应该是一样的,不要干不同的事情(即消费多个topic)。建议`consumerGroup`与`topic`一一对应。
+    
+1. 发送的消息内容体是如何被序列化与反序列化的?
+
+    RocketMQ的消息体都是以`byte[]`方式存储。当业务系统的消息内容体如果是`java.lang.String`类型时,统一按照`utf-8`编码转成`byte[]`;如果业务系统的消息内容为非`java.lang.String`类型,则采用[jackson-databind](https://github.com/FasterXML/jackson-databind)序列化成`JSON`格式的字符串之后,再统一按照`utf-8`编码转成`byte[]`。
+    
+1. 如何指定topic的`tags`?
+
+    RocketMQ的最佳实践中推荐:一个应用尽可能用一个Topic,消息子类型用`tags`来标识,`tags`可以由应用自由设置。
+    在使用`rocketMQTemplate`发送消息时,通过设置发送方法的`destination`参数来设置消息的目的地,`destination`的格式为`topicName:tagName`,`:`前面表示topic的名称,后面表示`tags`名称。
+    
+    > 注意:
+    >
+    > `tags`从命名来看像是一个复数,但发送消息时,目的地只能指定一个topic下的一个`tag`,不能指定多个。
+    
+1. 发送消息时如何设置消息的`key`?
+
+    可以通过重载的`xxxSend(String destination, Message<?> msg, ...)`方法来发送消息,指定`msg`的`headers`来完成。示例:
+    
+    ```java
+    Message<?> message = MessageBuilder.withPayload(payload).setHeader(MessageConst.PROPERTY_KEYS,
msgId).build();
+    rocketMQTemplate.send("topic-test", message);
+    ```
+
+    同理还可以根据上面的方式来设置消息的`FLAG`、`WAIT_STORE_MSG_OK`以及一些用户自定义的其它头信息。
+    
+    > 注意:
+    >
+    > 在将Spring的Message转化为RocketMQ的Message时,为防止`header`信息与RocketMQ的系统属性冲突,在所有`header`的名称前面都统一添加了前缀`USERS_`。因此在消费时如果想获取自定义的消息头信息,请遍历头信息中以`USERS_`开头的key即可。
+    
+1. 消费消息时,除了获取消息`payload`外,还想获取RocketMQ消息的其它系统属性,需要怎么做?
+
+    消费者在实现`RocketMQListener`接口时,只需要起泛型为`MessageExt`即可,这样在`onMessage`方法将接收到RocketMQ原生的`MessageExt`消息。
+    
+    ```java
+    @Slf4j
+    @Service
+    @RocketMQMessageListener(topic = "test-topic-1", consumerGroup = "my-consumer_test-topic-1")
+    public class MyConsumer2 implements RocketMQListener<MessageExt>{
+        public void onMessage(MessageExt messageExt) {
+            log.info("received messageExt: {}", messageExt);
+        }
+    }
+    ```
+    
+1. 如何指定消费者从哪开始消费消息,或开始消费的位置?
+
+    消费者默认开始消费的位置请参考:[RocketMQ FAQ](http://rocketmq.apache.org/docs/faq/)。
+    若想自定义消费者开始的消费位置,只需在消费者类添加一个`RocketMQPushConsumerLifecycleListener`接口的实现即可。
示例如下:
+    
+    ```java
+    @Slf4j
+    @Service
+    @RocketMQMessageListener(topic = "test-topic-1", consumerGroup = "my-consumer_test-topic-1")
+    public class MyConsumer1 implements RocketMQListener<String>, RocketMQPushConsumerLifecycleListener
{
+        @Override
+        public void onMessage(String message) {
+            log.info("received message: {}", message);
+        }
+    
+        @Override
+        public void prepareStart(final DefaultMQPushConsumer consumer) {
+            // set consumer consume message from now
+            consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_TIMESTAMP);
+            	  consumer.setConsumeTimestamp(UtilAll.timeMillisToHumanString3(System.currentTimeMillis()));
+        }
+    }
+    ```
+    
+    同理,任何关于`DefaultMQPushConsumer`的更多其它其它配置,都可以采用上述方式来完成。
+    
+1. 如何发送事务消息?
+
+	在客户端,首先用户需要实现RocketMQLocalTransactionListener接口,并在接口类上注解声明@RocketMQTransactionListener,实现确认和回查方法;然后再使用资源模板RocketMQTemplate,
+	调用方法sendMessageInTransaction()来进行消息的发布。 **注意:从RocketMQ-Spring
2.1.0版本之后,注解@RocketMQTransactionListener不能设置txProducerGroup、ak、sk,这些值均与对应的RocketMQTemplate保持一致**。
+  
+1. 如何声明不同name-server或者其他特定的属性来定义非标的RocketMQTemplate?
+
+    第一步: 定义非标的RocketMQTemplate使用你需要的属性,可以定义与标准的RocketMQTemplate不同的nameserver、groupname等。如果不定义,它们取全局的配置属性值或默认值。
  
+    ```java
+    // 这个RocketMQTemplate的Spring Bean名是'extRocketMQTemplate', 与所定义的类名相同(但首字母小写)
+    @ExtRocketMQTemplateConfiguration(nameServer="127.0.0.1:9876"
+       , ... // 定义其他属性,如果有必要。
+    )
+    public class ExtRocketMQTemplate extends RocketMQTemplate {
+      //类里面不需要做任何修改
+    }
+    ```
+    第二步: 使用这个非标RocketMQTemplate
+    ```java
+    @Resource(name = "extRocketMQTemplate") // 这里必须定义name属性来指向上述具体的Spring
Bean.
+    private RocketMQTemplate extRocketMQTemplate; 
+    ```
+    接下来就可以正常使用这个extRocketMQTemplate了。
+
+1. 如何使用非标的RocketMQTemplate发送事务消息?
+
+    首先用户需要实现RocketMQLocalTransactionListener接口,并在接口类上注解声明@RocketMQTransactionListener,注解字段的rocketMQTemplateBeanName指明为非标的RocketMQTemplate的Bean
name(若不设置则默认为标准的RocketMQTemplate),比如非标的RocketMQTemplate
Bean name为“extRocketMQTemplate",则代码如下:
+
+    ```java
+    @RocketMQTransactionListener(rocketMQTemplateBeanName = "extRocketMQTemplate")
+        class TransactionListenerImpl implements RocketMQLocalTransactionListener {
+              @Override
+              public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object
arg) {
+                // ... local transaction process, return bollback, commit or unknown
+                return RocketMQLocalTransactionState.UNKNOWN;
+              }
+    
+              @Override
+              public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
+                // ... check transaction status and return bollback, commit or unknown
+                return RocketMQLocalTransactionState.COMMIT;
+              }
+        }
+    ```
+    然后使用extRocketMQTemplate调用sendMessageInTransaction()来发送事务消息。
+1. MessageListener消费端,是否可以指定不同的name-server而不是使用全局定义的'rocketmq.name-server'属性值
?  
+
+    ```java
+    @Service
+    @RocketMQMessageListener(
+       nameServer = "NEW-NAMESERVER-LIST", // 可以使用这个optional属性来指定不同的name-server
+       topic = "test-topic-1", 
+       consumerGroup = "my-consumer_test-topic-1",
+       enableMsgTrace = true,
+       customizedTraceTopic = "my-trace-topic"
+    )
+    public class MyNameServerConsumer implements RocketMQListener<String> {
+       ...
+    }
+    ```
\ No newline at end of file


Mime
View raw message