RocketMQ实现发布-订阅模式

1.为了减少报错,多加了个fastjson的包

    <dependency>
    <groupId>com.alibaba.rocketmq</groupId>
    <artifactId>rocketmq-client</artifactId>
    <version>3.0.10.1</version>
   </dependency>
   <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.47</version>

    </dependency>

2.消息的生产者。 如果报错No route info of this topic,网上有多种解决方式,靠谱的三种:

    一是启动时设置:autoCreateTopicEnable=true

    二是网络链接问题,很可能是linux的防火墙设置的问题,导致用远程ip访问不到mq的namesrv 

    三是缺少fastjson包

public class RocketMQProducer
{

	private DefaultMQProducer sender;

	protected String nameServer;

	protected String groupName;

	protected String topics;

	/**
	 * 初始化信息
	 * @data 2018年5月17日
	 * @author zy
	 */
	public void init()
	{

		sender = new DefaultMQProducer(groupName);
		sender.setNamesrvAddr(nameServer);
		sender.setInstanceName(UUID.randomUUID().toString());
		try
		{
			sender.start();
		}
		catch (MQClientException e)
		{
			e.printStackTrace();
		}
	}

	/**
	 * 构造函数
	 * 
	 * @param nameServer
	 * @param groupName
	 * @param topics
	 */
	public RocketMQProducer(String nameServer, String groupName, String topics)
	{

		this.nameServer = nameServer;
		this.groupName = groupName;
		this.topics = topics;

	}

	/**
	 * 构建消息的方法,启动MQ的时候将autoCreateTopicEnable=true,即使不创建topics,RocketMQ也会默认创建个
	 * 
	 * @data 2018年5月17日
	 * @author zy
	 * @param message
	 * @param i
	 */
	public void send(Message message, int i)
	{

		message.setTopic(topics);
		message.setKeys(String.valueOf(i));

		// 实现message接收的顺序和插队
		if (i != 5)
		{
			message.setDelayTimeLevel(2);
		}

		int dex = i % 100;
		try
		{
			// 为了保证顺序消费,将消息定义在一个MessageQueue中
			SendResult result = sender.send(message, new MessageQueueSelector()
			{

				public MessageQueue select(List<MessageQueue> mqs, Message msg, Object arg)
				{
					int id = (Integer) arg;
					int index = id % mqs.size();
					return mqs.get(index);
				}

			}, dex);
			SendStatus status = result.getSendStatus();

			String info = "第" 
						+ i 
						+ "次发送的messageId = "
						+ result.getMsgId() 
						+ ", " 
						+ "status = " 
						+ status
						+ " MessageQueue id = " 
						+ result.getMessageQueue().getQueueId();

			System.out.println(info);

			App.WriteMsg(info + "\r\n");
		}
		catch (Exception e)
		{

			e.printStackTrace();
		}
	}
}

3.消息的消费者

public class RocketMQConsumer
{

	private DefaultMQPushConsumer consumer;

	private MessageListener listener;

	protected String nameServer;

	protected String groupName;

	protected String topics;

	public RocketMQConsumer(MessageListener listener, String nameServer, String groupName, String topics)
	{
		this.listener = listener;
		this.nameServer = nameServer;
		this.groupName = groupName;
		this.topics = topics;
	}

	/**
	 * 初始化信息
	 * @data 2018年5月17日
	 * @author zy
	 */
	public void init()
	{

		consumer = new DefaultMQPushConsumer(groupName);
		consumer.setNamesrvAddr(nameServer);
        consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_FIRST_OFFSET);

		try
		{

			consumer.subscribe(topics, "*");
		}
		catch (MQClientException e)
		{
			e.printStackTrace();
		}
		consumer.setInstanceName(UUID.randomUUID().toString());
		consumer.setConsumeFromWhere(ConsumeFromWhere.CONSUME_FROM_LAST_OFFSET);
		consumer.registerMessageListener((MessageListenerConcurrently) this.listener);

		try
		{

			consumer.start();
		}
		catch (MQClientException e)
		{
			e.printStackTrace();
		}

		System.out.println("消費者開始消費! group=" + consumer.getConsumerGroup() + " instanceName="
				+ consumer.getInstanceName() + "NamesrvAddr= " + consumer.getNamesrvAddr());
	}
}

4.用main方法测试:

public class App
{
	public static void main(String[] args)
	{
		// 生产者
		testPro();

		// 消费者
		testCon();

	}

	/**
	 * 测试生产者的方法
	 * 
	 * @data 2018年5月17日
	 * @author zy
	 */
	public static void testPro()
	{

		String mqNameServer = "192.168.1.104:9876";
		String mqTopics = "TESTzy";

		String producerMqGroupName = "PRODUCERzy";
		RocketMQProducer mqProducer = new RocketMQProducer(mqNameServer, producerMqGroupName, mqTopics);
		mqProducer.init();

		for (int i = 0; i < 1000; i++)
		{

			Message message = new Message();
			message.setBody(("这是发送的RocketMQ " + i).getBytes());

			mqProducer.send(message, i);
		}
	}

	/**
	 * 测试消费者的方法
	 * 
	 * @data 2018年5月17日
	 * @author zy
	 */
	public static void testCon()
	{
		String mqNameServer = "192.168.1.104:9876";
		String mqTopics = "TESTzy";

		String consumerMqGroupName = "PRODUCERzy";
		RocketMQListener mqListener = new RocketMQListener();
		RocketMQConsumer mqConsumer = new RocketMQConsumer(mqListener, mqNameServer, consumerMqGroupName, mqTopics);
		mqConsumer.init();

		try
		{
			Thread.sleep(1000 * 60L);
		}
		catch (InterruptedException e)
		{
			e.printStackTrace();
		}

	}

	/**
	 * 将收发的消息放在文件中,可以看是否有消息丢失。
	 * 
	 * @param string 消息
	 * 
	 */
	public static void WriteMsg(String string)
	{
		FileOutputStream fos = null;
		File file = new File("E:/log.txt");

		try
		{

			fos = new FileOutputStream(file, true);
			fos.write(string.getBytes());

		}
		catch (FileNotFoundException e)
		{
			e.printStackTrace();
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		finally
		{

			try
			{
				fos.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}

		}
	}
}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
RocketMQ是一款开源的分布式消息队列系统,而rocketmq-client-java是RocketMQ的Java客户端。 rocketmq-client-java提供了丰富的API,使得开发者可以方便地使用RocketMQ进行消息的发布订阅。它支持多种消息发送模式,包括同步发送、异步发送和单向发送。同步发送保证了消息的可靠性和顺序性,异步发送提高了发送效率,而单向发送则不需要等待服务器的响应。此外,rocketmq-client-java还支持批量发送和延迟发送等特性,满足了不同场景下的需求。 rocketmq-client-java提供了多种消息消费模式,包括集群模式和广播模式。在集群模式下,多个消费者可以共同消费一个队列的消息,实现消息的负载均衡和高可用性;而在广播模式下,每个消费者都能收到所有队列的消息,适用于需要实时获得消息的场景。 rocketmq-client-java还提供了自动负载均衡和故障转移的功能。当消费者增减或者下线时,RocketMQ会自动进行负载均衡,保证每个消费者都能平均地消费消息。而当某个消费者出现故障时,RocketMQ会将该消费者的消息重新分配给其他正常工作的消费者,保证消息的可靠性和高可用性。 此外,rocketmq-client-java还支持消息过滤、消息事务和顺序消息等高级特性。消息过滤可以根据指定的条件对消息进行过滤,只消费符合条件的消息。消息事务可以保证消息的原子性,要么一起成功,要么一起失败。顺序消息可以保证按照发送顺序进行消费,避免了消息的乱序问题。 综上所述,rocketmq-client-java是RocketMQ的Java客户端,提供了丰富的API和多种特性,使得开发者可以方便地使用RocketMQ进行消息的发布订阅,并满足不同场景下的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值