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 <[email protected]>
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