RocketMQ工具類,並與spring結合

pom.xml:

<dependency>
	<groupId>org.apache.rocketmq</groupId>
	<artifactId>rocketmq-client</artifactId>
    <version>4.5.0</version>
</dependency>

1,生產者:

RocketMQUtils.java:

支持異步,同步,單向發送。

package com.equaker.cache.rocketmq;

import java.util.List;
import java.util.ResourceBundle;

import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.equaker.common.utils.SerializeUtils;

public class RocketMQUtils {

	private static Logger logger = LoggerFactory.getLogger(RocketMQUtils.class);
	private static final String CONFIG_PATH = "config/config";

//	private static final String ROCKETMQ_TOPIC_TOPIC1 = "topic-1";
//	private static final String ROCKETMQ_TAGS_TAGS1 = "tags-1";
//	private static final String ROCKETMQ_PRODUCEGROUP = "produce_group1";
	private static DefaultMQProducer producer = null;

	static {
		try {

			ResourceBundle resourceBundle = ResourceBundle.getBundle(CONFIG_PATH);
			if (resourceBundle == null) {
				throw new IllegalArgumentException("[config.properties] is not found!");
			}

			final String ROCKETMQ_GROUP_NAME = resourceBundle.getString("rocketmq.groupName");

			final String ROCKETMQ_IP = resourceBundle.getString("rocketmq.ip");

			final String ROCKETMQ_RETRYTIMES = resourceBundle.getString("rocketmq.retryTimes");

			final String ROCKETMQ_TIMEOUT = resourceBundle.getString("rocketmq.timeout");

			producer = new DefaultMQProducer(ROCKETMQ_GROUP_NAME);

			producer.setNamesrvAddr(ROCKETMQ_IP);
			producer.start();
			// producer.setRetryTimesWhenSendFailed(Integer.valueOf(ROCKETMQ_RETRYTIMES));
			producer.setRetryTimesWhenSendAsyncFailed(Integer.valueOf(ROCKETMQ_RETRYTIMES));
			producer.setSendMsgTimeout(Integer.valueOf(ROCKETMQ_TIMEOUT));

			logger.info("producer init success >>>");
//			jedisPool = RedisConfig.getInstance().getJedisPool();
		} catch (Exception e) {
			logger.error("producer init fail!!!", e);
		}
	}

	/**
	 * 異步發送消息
	 * @param <T>
	 * 
	 * @param callback 回調函數
	 * @param object   消息體
	 * @param keys     鍵值對,過濾數據使用
	 */
	public static <T> void asyncPush(String topic, String tags, String keys, SendCallback callback, List<T> objects) {
		
//		for (int i = 0; i < objects.size(); i++) {
//			// Create a message instance, specifying topic, tag and message body.
//			Message msg = new Message(topic, tags, keys, SerializeUtils.serialize(objects.get(i)));
//			try {
//				producer.send(msg, callback);
//				logger.info("send success>>>:");
//			} catch (Exception e) {
//				logger.info("send error>>>:", e);
//			}
//		}

		objects.stream().forEachOrdered(p -> {
			Message msg = new Message(topic, tags, keys, SerializeUtils.serialize(p));
			try {
				producer.send(msg, callback);
				logger.info("send success>>>:");
			} catch (Exception e) {
				logger.info("send error>>>:", e);
			}
		});
	}

	/**
	 * 同步發送消息
	 * @param <T>
	 * 
	 * @param keys   鍵值對,過濾數據使用
	 * @param object 消息體
	 */
	public static <T> void syncPush(String topic, String tags, String keys,  List<T> objects) {

//		 Integer retLength = 0;// 消息推送成功 總數
//		for (int i = 0; i < objects.size(); i++) {
//			Message msg = new Message(topic, tags, keys, SerializeUtils.serialize(objects.get(i)));
//			try {
//				SendResult sendResult = producer.send(msg);
//				logger.info("send success>>>:" + sendResult.getMsgId());
//				retLength++;
//			} catch (Exception e) {
//				logger.info("send error>>>:", e);
//			}
//		}
		
		objects.stream().forEachOrdered(p->{
			Message msg = new Message(topic, tags, keys, SerializeUtils.serialize(p));
			try {
				SendResult sendResult = producer.send(msg);
				logger.info("send success>>>:" + sendResult.getMsgId());
			} catch (Exception e) {
				logger.info("send error>>>:", e);
			}
		});
		
		//return retLength;
	}

	/**
	 * 同步發送消息
	 * @param <T>
	 * 
	 * @param keys   鍵值對,過濾數據使用
	 * @param object 消息體
	 */
	public static <T> void onewayPush(String topic, String tags, String keys,  List<T> objects) {
//		for (int i = 0; i < objects.size(); i++) {
//			Message msg = new Message(topic, tags, keys, SerializeUtils.serialize(object[i]));
//			try {
//				producer.sendOneway(msg);
//				logger.info("send success>>>:");
//			} catch (Exception e) {
//				logger.info("send error>>>:", e);
//			}
//		}
		
		objects.stream().forEachOrdered(p->{
			Message msg = new Message(topic, tags, keys, SerializeUtils.serialize(p));
			try {
				producer.sendOneway(msg);
				logger.info("send success>>>:");
			} catch (Exception e) {
				logger.info("send error>>>:", e);
			}
		});
		
	}

}

config.properties:

#### rocketMQ ####
rocketmq.groupName=produce_group1
rocketmq.ip=*:*
rocketmq.retryTimes=2
rocketmq.timeout=5000

消息生產者的配置如上,網上有生產者與spring結合,在需要的地方通過注入的方式使用,個人感覺沒有必要,而且容易限制producer,畢竟生產者是包含produce group,topic,tags等信息的。本身只起到一個推送消息的作用,同redis的消息隊列(左進右出,和發佈訂閱模式)類似。

 

2,消費者:

消費者應該是處於阻塞階段的程序,需要時刻檢測隊列是否還有數據。所以需要與spring結合,把他的生命週期交給spring管理。

1,首先需要編寫一個消息處理類,實現MessageListenerConcurrently接口(或者MessageListenerOrderly,一個單線程,順序讀取,另一個則是異步)。

MessageListenerImpl.java:

package com.equaker.cache.rocketmq;

import java.util.List;

import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.common.message.MessageExt;

import com.equaker.common.utils.SerializeUtils;

public class MessageListenerImpl implements MessageListenerConcurrently {

	@Override
	public ConsumeConcurrentlyStatus consumeMessage(List<MessageExt> msgs, ConsumeConcurrentlyContext context) {
		for(MessageExt msg : msgs) {
            //在這裏進行相應的業務邏輯,這裏直接進行打印
        	System.out.println(SerializeUtils.deserialize(msg.getBody()));
        	//System.out.println(new String(msg.getBody()));
        }
        System.out.println("*******************");
		return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
	}

}

接下來配置 rocketmq 提供的默認消息消費者:DefaultMQPushConsumer

applicationContext.xml:

<!-- rocketmq 消費者配置 -->
    <bean id="messageListeners" class="com.equaker.cache.rocketmq.MessageListenerImpl"></bean>
    <!-- 導入Spring配置文件 -->
    <bean id="rocketmqConsumer" class="org.apache.rocketmq.client.consumer.DefaultMQPushConsumer" init-method="start" destroy-method="shutdown">
        <property name="consumerGroup" value="consume1"/>
<!--         <property name="instanceName"> -->
<!--             <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> -->
<!--                 <property name="targetClass"> -->
<!--                     <value>com.xx.utils.RunTimeUtil</value> -->
<!--                 </property> -->
<!--                 <property name="targetMethod"> -->
<!--                     <value>getRocketMqUniqeInstanceName</value> -->
<!--                 </property> -->
<!--             </bean> -->
<!--         </property> -->
        <property name="namesrvAddr" value="你的外網地址:port"/>
        <property name="messageListener" ref="messageListeners"/>
        <property name="subscription">
            <map>
                <!-- 進行topic-1的訂閱-->
                <entry key="topic-1" value="*" />
            </map>
        </property>
    </bean>

配置完畢。

3,測試:

啓動spring項目,會發現rocketmq 的broker.log會有日誌顯示:

,此時編寫produce測試類:

AppTest1.java:

package org.equaker.cache;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.rocketmq.client.producer.SendCallback;
import org.apache.rocketmq.client.producer.SendResult;

import com.equaker.cache.rocketmq.RocketMQUtils;

public class AppTest1 {

	public static void main(String[] args) {
		
		List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
		
		for (int i = 0; i < 5; i++) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("name", "@EQuaker-" + i);
			list.add(map);
		}
		
		RocketMQUtils.asyncPush("topic-1", "tags-1", "keys-1", new SendCallback() {

			@Override
			public void onSuccess(SendResult sendResult) {
				System.out.println("messageid: "+sendResult.getMsgId());
			}

			@Override
			public void onException(Throwable e) {
				// TODO Auto-generated method stub

			}
		}, list);
		
//		int length = RocketMQUtils.syncPush("topic-1", "tags-1", "keys-1", map);
//		System.out.println(length);
		
		
	}

}

運行如如下:

produce-console:

consume-tomcat-console:

》》》》》》》》》》》》》》》》》》》

暫時這麼多了,以後會繼續研究rocketmq事物,messagequeue和messagequeueselector等。

歡迎關注我的公衆號:EQuaker,更多東西等你來拿。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章