一、先搭建两个JAVA WEB工程,一个是消息生产者工程ProducerProject,另外是一个消息消费者工程ConsumerProject
二、然后导入RocketMQ的所需要JAR包(rocketmq-client-3.2.6.jar,rocketmq-common-3.2.6.jar,rocketmq-remoting-3.2.6.jar),点击此链接进行下载
三、在ProducerProject 创建一个发送消息的工具类,用来向RocketMQ发送消息,代码如下:
package com.cluster.mq;
import java.io.UnsupportedEncodingException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.alibaba.rocketmq.client.exception.MQBrokerException;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.client.producer.DefaultMQProducer;
import com.alibaba.rocketmq.client.producer.SendResult;
import com.alibaba.rocketmq.common.message.Message;
import com.alibaba.rocketmq.remoting.exception.RemotingException;
/**
* RocketMQ生产者类
* @author pengtian
*
*/
public class RocketMqProducer {
private static Log log = LogFactory.getLog(RocketMqProducer.class);
static DefaultMQProducer producer = null;
private static final Object obj = new Object();
/**
* 系统一启动,就启动运行生产者
*/
static {
if (producer == null) {
synchronized (obj) {
if (producer == null) {
try {
producer = new DefaultMQProducer("myProducer");
//producer.setNamesrvAddr(SystemGlobals.getProperties("nameServiceAddr"));// 连接MQ服务器地址
producer.setNamesrvAddr("rocketmq-nameserver1:9876;rocketmq-nameserver2:9876;rocketmq-nameserver3:9876;rocketmq-nameserver4:9876");// 连接MQ服务器地址;192.168.113.134:9876
producer.start();
} catch (MQClientException e) {
log.error("MQ producer初始化异常");
e.printStackTrace();
}
}
}
}
}
/**
* 发送MQ消息
* @param xml,String MQ消息
* @param topic,String MQ消息主题
* @param tags,String MQ消息标志
* @return
* @throws Exception
*/
public static boolean sendMessage(String xml, String topic, String tags)throws Exception {
// 以注册为例,Message中参数为 Topic ; 注册为memberRegister; 这两个参数必须与收消息方共同定义好,现在用户注册
// 为Topic,memberRegister,新的再加定义
SendResult sendResult = null;
try {
Message msg = new Message(topic, tags, xml.getBytes("UTF-8"));
msg.setKeys("KEYS_"+System.currentTimeMillis());
sendResult = producer.send(msg);
log.info("MSG_ID:"+sendResult.getMsgId()+",SendStatus:"+sendResult.getSendStatus());
//producer.shutdown();
return true;
} catch (UnsupportedEncodingException e) {
log.error("发送消息到mq不支持的编码异常--->");
e.printStackTrace();
} catch (MQClientException e) {
log.error("发送消息到mq MQ客户端异常--->");
e.printStackTrace();
} catch (RemotingException e) {
log.error("发送消息到mq Remoting异常--->");
e.printStackTrace();
} catch (MQBrokerException e) {
log.error("发送消息到mq MQBroker异常--->");
e.printStackTrace();
} catch (Exception e) {
log.error("发送消息到mq未知异常--->");
e.printStackTrace();
}
return false;
}
public static void main(String[] args) {
for(int i=1;i<100;i++){
// 消息的内容
StringBuffer xml = new StringBuffer("");
xml.append("<REQUEST id='mqMsg'>");
xml.append("<VERSION>1.1</VERSION>");
xml.append("<DDH>DD_1231eqwe123</DDH>");
xml.append("</REQUEST>");
String message = xml.toString();
try {
sendMessage(message, "Topic", "MY_TEST_01");
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
四、在ConsumerProject工程配置消费RocketMQ队列中的消息,需要和Spring进行集成:
1、先创建RocketMQ 消费工具类,代码如下:
package com.cluster.mq;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import com.alibaba.rocketmq.client.consumer.DefaultMQPushConsumer;
import com.alibaba.rocketmq.client.exception.MQClientException;
import com.alibaba.rocketmq.common.consumer.ConsumeFromWhere;
import com.alibaba.rocketmq.common.protocol.heartbeat.MessageModel;
import com.cluster.util.SystemGlobals;
/**
* RocketMq消费者
* @author pengtian
*
*/
public class RocketMqConsumers {
private static final Logger log = Logger.getLogger(RocketMqConsumers.class);
private DefaultMQPushConsumer consumer;
private static final String namesrvAddr = "rocketmq-nameserver1:9876;rocketmq-nameserver2:9876;rocketmq-nameserver3:9876;rocketmq-nameserver4:9876";
private static final String consumerGroup = "myProducer";private static final String topicName = "Topic";
private static final String tagsName = "MY_TEST_01||mytest";//代表获取Tags为MY_TEST_01、mytest的消息
private static final int consumeThreadMin = 3;
private static final int consumeThreadMax = 5;
@Autowiredprivate
MsgListenerConcurrently msgListenerConcurrently;
/** * Spring bean init-method */
public void init() throws MQClientException {
try {
// 参数信息log.info("DefaultMQPushConsumer初始化!");
log.info("consumerGroup:"+consumerGroup);
log.info("namesrvAddr:"+namesrvAddr);
log.info("topicName:"+topicName);
log.info("tagsName:"+tagsName);
// 一个应用创建一个Consumer,由应用来维护此对象,可以设置为全局对象或者单例<br>// 注意:ConsumerGroupName需要由应用来保证唯一
consumer = new DefaultMQPushConsumer(consumerGroup);
consumer.setNamesrvAddr(namesrvAddr);
consumer.setInstanceName(String.valueOf(System.currentTimeMillis()));// 订阅指定topic下tags等于tag
consumer.subscribe(topicName, tagsName);
//MessageModel.CLUSTERING 集群消费 :只能有一个消费者消费一次 ,MessageModel.BROADCASTING 广播模式 所有的消费者都会消费一次
consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);
consumer.setMessageModel(MessageModel.CLUSTERING);
consumer.registerMessageListener(msgListenerConcurrently);
consumer.setConsumeThreadMin(consumeThreadMin);
consumer.setConsumeThreadMax(consumeThreadMax);
consumer.start();log.info("DefaultMQPushConsumer初始化成功!");
} catch (Exception ex) {
log.error("DefaultMQPushConsumer初始化异常=" + ex.getMessage());ex.printStackTrace();
}
}
/** * Spring bean destroy-method */
public void destory() {
consumer.shutdown();
}
/** * @param args */
public static void main(String[] args) {
/ / TODO Auto-generated method stub
}
}
package com.cluster.mq;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import com.alibaba.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import com.alibaba.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import com.alibaba.rocketmq.common.message.MessageExt;
import com.bwdz.fpt.common.xml.XmlUtil;
/**
* PushConsumer回调Listener方法
*
*/
@SuppressWarnings("unchecked")
public class MsgListenerConcurrently implements MessageListenerConcurrently {
private static final Logger log = Logger
.getLogger(MsgListenerConcurrently.class);
public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs,
ConsumeConcurrentlyContext context) {
for (MessageExt msg : msgs) {
String body = "";
String tags = msg.getTags();
String topic = msg.getTopic();
log.info("【tags:"+tags+",topic:"+topic+"】");
try {
body = new String(msg.getBody(), "UTF-8");
System.out.println("【MSG:"+body+"】");
//Map map = XmlUtil.Dom2Map(body);
if("topic".equals(topic)&&"A".equals(tags)){
System.out.println("A===============");
}else if("topic".equals(topic)&&"B".equals(tags)){
System.out.println("B===============");
}
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
} catch (Exception e) {
String delay = msg.getProperty("DELAY");
if (delay != null && Integer.parseInt(delay) > 4) {// 重试次数超过3次丢弃此条消息
log.warn("消息重试次数过多,不再消费:" + body);
return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
}
log.error("mq消息消费异常,本条消息是:" + body);
e.printStackTrace();
}
}
return ConsumeConcurrentlyStatus.RECONSUME_LATER;
}
}
2、将上面创建的RocketMQ消费者工具类集成到Spring中,在spring配置文件中进行如下配置:
<!-- 消息消费者Consumer -->
<bean id="msgListenerConcurrently" class="com.cluster.mq.MsgListenerConcurrently" scope="singleton">
</bean>
<!-- 消息消费者Consumer -->
<bean class="com.cluster.mq.RocketMqConsumers" init-method="init" destroy-method="destory" scope="singleton" />
五、接下是检验成败的时候了
1、先启动好RocketMQ集群(具体请查看 RocketMQ集群解决方案),然后启动好ConsumerProject
2、单元运行ProducerProject工程 RocketMqProducer.java Main函数,执行后,ProducerProject工程控制台打印如下信息,说明通讯正常,然后再查看ConsumerProject就会收到发送的报文信息。
16-11-24 14:06:18 INFO RocketMqProducer:63 - MSG_ID:C0A8718A00002A9F000000000000EC08,SendStatus:SEND_OK
16-11-24 14:06:18 INFO RocketMqProducer:63 - MSG_ID:C0A8718A00002A9F000000000000EEEA,SendStatus:SEND_OK
16-11-24 14:06:18 INFO RocketMqProducer:63 - MSG_ID:C0A8718A00002A9F000000000000F1CC,SendStatus:SEND_OK
16-11-24 14:06:18 INFO RocketMqProducer:63 - MSG_ID:C0A8718A00002A9F000000000000F4AE,SendStatus:SEND_OK
16-11-24 14:06:18 INFO RocketMqProducer:63 - MSG_ID:C0A8718A00002A9F000000000000F790,SendStatus:SEND_OK