RocketMQ集群解决方案----JAVA应用

       上篇文章 RocketMQ集群解决方案 已经讲解了RocketMQ应用场景及性能、RocketMQ网络部署图、实际集群部署操作步骤(采用多Master多Slave,异步复制集群模式进行部署),这篇文章将讲解JAVA应用中怎么实际调用搭建的RocketMQ集群环境。
     一、先搭建两个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


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值